xref: /netbsd-src/external/gpl2/lvm2/dist/lib/activate/fs.c (revision d685da8d62f30d0a988361c4d0759bb35d1f03f5)
1*d685da8dShaad /*	$NetBSD: fs.c,v 1.4 2009/12/02 00:58:03 haad Exp $	*/
256a34939Shaad 
356a34939Shaad /*
456a34939Shaad  * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
556a34939Shaad  * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
656a34939Shaad  *
756a34939Shaad  * This file is part of LVM2.
856a34939Shaad  *
956a34939Shaad  * This copyrighted material is made available to anyone wishing to use,
1056a34939Shaad  * modify, copy, or redistribute it subject to the terms and conditions
1156a34939Shaad  * of the GNU Lesser General Public License v.2.1.
1256a34939Shaad  *
1356a34939Shaad  * You should have received a copy of the GNU Lesser General Public License
1456a34939Shaad  * along with this program; if not, write to the Free Software Foundation,
1556a34939Shaad  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
1656a34939Shaad  */
1756a34939Shaad 
1856a34939Shaad #include "lib.h"
1956a34939Shaad #include "fs.h"
2056a34939Shaad #include "toolcontext.h"
2156a34939Shaad #include "lvm-string.h"
2256a34939Shaad #include "lvm-file.h"
2356a34939Shaad #include "memlock.h"
2456a34939Shaad 
2556a34939Shaad #include <sys/stat.h>
2656a34939Shaad #include <fcntl.h>
2756a34939Shaad #include <unistd.h>
2856a34939Shaad #include <limits.h>
2956a34939Shaad #include <dirent.h>
3056a34939Shaad 
_mk_dir(const char * dev_dir,const char * vg_name)3156a34939Shaad static int _mk_dir(const char *dev_dir, const char *vg_name)
3256a34939Shaad {
3356a34939Shaad 	char vg_path[PATH_MAX];
34*d685da8dShaad 	mode_t old_umask;
3556a34939Shaad 
3656a34939Shaad 	if (dm_snprintf(vg_path, sizeof(vg_path), "%s%s",
3756a34939Shaad 			 dev_dir, vg_name) == -1) {
3856a34939Shaad 		log_error("Couldn't construct name of volume "
3956a34939Shaad 			  "group directory.");
4056a34939Shaad 		return 0;
4156a34939Shaad 	}
4256a34939Shaad 
4356a34939Shaad 	if (dir_exists(vg_path))
4456a34939Shaad 		return 1;
4556a34939Shaad 
4656a34939Shaad 	log_very_verbose("Creating directory %s", vg_path);
47*d685da8dShaad 
48*d685da8dShaad 	old_umask = umask(DM_DEV_DIR_UMASK);
4956a34939Shaad 	if (mkdir(vg_path, 0777)) {
5056a34939Shaad 		log_sys_error("mkdir", vg_path);
51*d685da8dShaad 		umask(old_umask);
5256a34939Shaad 		return 0;
5356a34939Shaad 	}
54*d685da8dShaad 	umask(old_umask);
5556a34939Shaad 
5656a34939Shaad 	return 1;
5756a34939Shaad }
5856a34939Shaad 
_rm_dir(const char * dev_dir,const char * vg_name)5956a34939Shaad static int _rm_dir(const char *dev_dir, const char *vg_name)
6056a34939Shaad {
6156a34939Shaad 	char vg_path[PATH_MAX];
6256a34939Shaad 
6356a34939Shaad 	if (dm_snprintf(vg_path, sizeof(vg_path), "%s%s",
6456a34939Shaad 			 dev_dir, vg_name) == -1) {
6556a34939Shaad 		log_error("Couldn't construct name of volume "
6656a34939Shaad 			  "group directory.");
6756a34939Shaad 		return 0;
6856a34939Shaad 	}
6956a34939Shaad 
7056a34939Shaad 	if (dir_exists(vg_path) && is_empty_dir(vg_path)) {
7156a34939Shaad 		log_very_verbose("Removing directory %s", vg_path);
7256a34939Shaad 		rmdir(vg_path);
7356a34939Shaad 	}
7456a34939Shaad 
7556a34939Shaad 	return 1;
7656a34939Shaad }
7756a34939Shaad 
_rm_blks(const char * dir)7856a34939Shaad static void _rm_blks(const char *dir)
7956a34939Shaad {
8056a34939Shaad 	const char *name;
8156a34939Shaad 	char path[PATH_MAX];
8256a34939Shaad 	struct dirent *dirent;
8356a34939Shaad 	struct stat buf;
8456a34939Shaad 	DIR *d;
8556a34939Shaad 
8656a34939Shaad 	if (!(d = opendir(dir))) {
8756a34939Shaad 		log_sys_error("opendir", dir);
8856a34939Shaad 		return;
8956a34939Shaad 	}
9056a34939Shaad 
9156a34939Shaad 	while ((dirent = readdir(d))) {
9256a34939Shaad 		name = dirent->d_name;
9356a34939Shaad 
9456a34939Shaad 		if (!strcmp(name, ".") || !strcmp(name, ".."))
9556a34939Shaad 			continue;
9656a34939Shaad 
9756a34939Shaad 		if (dm_snprintf(path, sizeof(path), "%s/%s", dir, name) == -1) {
9856a34939Shaad 			log_error("Couldn't create path for %s", name);
9956a34939Shaad 			continue;
10056a34939Shaad 		}
10156a34939Shaad 
10256a34939Shaad 		if (!lstat(path, &buf)) {
10356a34939Shaad 			if (!S_ISBLK(buf.st_mode))
10456a34939Shaad 				continue;
10556a34939Shaad 			log_very_verbose("Removing %s", path);
10656a34939Shaad 			if (unlink(path) < 0)
10756a34939Shaad 				log_sys_error("unlink", path);
10856a34939Shaad 		}
109c6f73bb8Shaad #ifdef __NetBSD__
110c6f73bb8Shaad 		if (dm_snprintf(path, sizeof(path), "%s/r%s", dir, name) == -1) {
111c6f73bb8Shaad 			log_error("Couldn't create path for r%s", name);
112c6f73bb8Shaad 			continue;
113c6f73bb8Shaad 		}
114c6f73bb8Shaad 
115c6f73bb8Shaad 		if (!lstat(path, &buf)) {
116c6f73bb8Shaad 			if (!S_ISCHR(buf.st_mode))
117c6f73bb8Shaad 				continue;
118c6f73bb8Shaad 			log_very_verbose("Removing %s", path);
119c6f73bb8Shaad 			if (unlink(path) < 0)
120c6f73bb8Shaad 				log_sys_error("unlink", path);
121c6f73bb8Shaad 		}
122c6f73bb8Shaad #endif
12356a34939Shaad 	}
12456a34939Shaad }
12556a34939Shaad 
_mk_link(const char * dev_dir,const char * vg_name,const char * lv_name,const char * dev)12656a34939Shaad static int _mk_link(const char *dev_dir, const char *vg_name,
12756a34939Shaad 		    const char *lv_name, const char *dev)
12856a34939Shaad {
12956a34939Shaad 	char lv_path[PATH_MAX], link_path[PATH_MAX], lvm1_group_path[PATH_MAX];
13056a34939Shaad 	char vg_path[PATH_MAX];
131*d685da8dShaad 	struct stat buf, buf_lp;
13256a34939Shaad 
133c6f73bb8Shaad #ifdef __NetBSD__
134c6f73bb8Shaad 	/* Add support for creating links to BSD raw devices */
135c6f73bb8Shaad 	char raw_lv_path[PATH_MAX], raw_link_path[PATH_MAX];
136c6f73bb8Shaad #endif
137c6f73bb8Shaad 
13856a34939Shaad 	if (dm_snprintf(vg_path, sizeof(vg_path), "%s%s",
13956a34939Shaad 			 dev_dir, vg_name) == -1) {
14056a34939Shaad 		log_error("Couldn't create path for volume group dir %s",
14156a34939Shaad 			  vg_name);
14256a34939Shaad 		return 0;
14356a34939Shaad 	}
14456a34939Shaad 
145c6f73bb8Shaad #ifdef __NetBSD__
146c6f73bb8Shaad 	if (dm_snprintf(raw_lv_path, sizeof(raw_lv_path), "%s/r%s", vg_path,
147c6f73bb8Shaad 		lv_name) == -1) {
148c6f73bb8Shaad 		log_error("Couldn't create source pathname for "
149c6f73bb8Shaad 		    "logical volume link r%s", lv_name);
150c6f73bb8Shaad 		return 0;
151c6f73bb8Shaad 	}
152c6f73bb8Shaad 
153c6f73bb8Shaad 	if (dm_snprintf(raw_link_path, sizeof(raw_link_path), "%s/r%s",
154c6f73bb8Shaad 		dm_dir(), dev) == -1) {
155c6f73bb8Shaad 		log_error("Couldn't create destination pathname for "
156c6f73bb8Shaad 		    "logical volume link for %s", lv_name);
157c6f73bb8Shaad 		return 0;
158c6f73bb8Shaad 	}
159c6f73bb8Shaad 
160c6f73bb8Shaad 	if (!lstat(raw_lv_path, &buf)) {
161c6f73bb8Shaad 		if (!S_ISLNK(buf.st_mode) && !S_ISCHR(buf.st_mode)) {
162c6f73bb8Shaad 			log_error("Symbolic link %s not created: file exists",
163c6f73bb8Shaad 				  raw_link_path);
164c6f73bb8Shaad 			return 0;
165c6f73bb8Shaad 		}
166c6f73bb8Shaad 
167c6f73bb8Shaad 		log_very_verbose("Removing %s", raw_lv_path);
168c6f73bb8Shaad 		if (unlink(raw_lv_path) < 0) {
169c6f73bb8Shaad 			log_sys_error("unlink", raw_lv_path);
170c6f73bb8Shaad 			return 0;
171c6f73bb8Shaad 		}
172c6f73bb8Shaad 	}
173c6f73bb8Shaad 
174c6f73bb8Shaad 	log_very_verbose("Linking %s -> %s", raw_lv_path, raw_link_path);
175c6f73bb8Shaad 	if (symlink(raw_link_path, raw_lv_path) < 0) {
176c6f73bb8Shaad 		log_sys_error("symlink", raw_lv_path);
177c6f73bb8Shaad 		return 0;
178c6f73bb8Shaad 	}
179c6f73bb8Shaad 
180c6f73bb8Shaad #endif
18156a34939Shaad 	if (dm_snprintf(lv_path, sizeof(lv_path), "%s/%s", vg_path,
18256a34939Shaad 			 lv_name) == -1) {
18356a34939Shaad 		log_error("Couldn't create source pathname for "
18456a34939Shaad 			  "logical volume link %s", lv_name);
18556a34939Shaad 		return 0;
18656a34939Shaad 	}
18756a34939Shaad 
18856a34939Shaad 	if (dm_snprintf(link_path, sizeof(link_path), "%s/%s",
18956a34939Shaad 			 dm_dir(), dev) == -1) {
19056a34939Shaad 		log_error("Couldn't create destination pathname for "
19156a34939Shaad 			  "logical volume link for %s", lv_name);
19256a34939Shaad 		return 0;
19356a34939Shaad 	}
19456a34939Shaad 
19556a34939Shaad 	if (dm_snprintf(lvm1_group_path, sizeof(lvm1_group_path), "%s/group",
19656a34939Shaad 			 vg_path) == -1) {
19756a34939Shaad 		log_error("Couldn't create pathname for LVM1 group file for %s",
19856a34939Shaad 			  vg_name);
19956a34939Shaad 		return 0;
20056a34939Shaad 	}
20156a34939Shaad 
20256a34939Shaad 	/* To reach this point, the VG must have been locked.
20356a34939Shaad 	 * As locking fails if the VG is active under LVM1, it's
20456a34939Shaad 	 * now safe to remove any LVM1 devices we find here
20556a34939Shaad 	 * (as well as any existing LVM2 symlink). */
20656a34939Shaad 	if (!lstat(lvm1_group_path, &buf)) {
20756a34939Shaad 		if (!S_ISCHR(buf.st_mode)) {
20856a34939Shaad 			log_error("Non-LVM1 character device found at %s",
20956a34939Shaad 				  lvm1_group_path);
21056a34939Shaad 		} else {
21156a34939Shaad 			_rm_blks(vg_path);
21256a34939Shaad 
21356a34939Shaad 			log_very_verbose("Removing %s", lvm1_group_path);
21456a34939Shaad 			if (unlink(lvm1_group_path) < 0)
21556a34939Shaad 				log_sys_error("unlink", lvm1_group_path);
21656a34939Shaad 		}
21756a34939Shaad 	}
21856a34939Shaad 
21956a34939Shaad 	if (!lstat(lv_path, &buf)) {
22056a34939Shaad 		if (!S_ISLNK(buf.st_mode) && !S_ISBLK(buf.st_mode)) {
22156a34939Shaad 			log_error("Symbolic link %s not created: file exists",
22256a34939Shaad 				  link_path);
22356a34939Shaad 			return 0;
22456a34939Shaad 		}
22556a34939Shaad 
226*d685da8dShaad 		if (dm_udev_get_sync_support()) {
227*d685da8dShaad 			/* Check udev created the correct link. */
228*d685da8dShaad 			if (!stat(link_path, &buf_lp) &&
229*d685da8dShaad 			    !stat(lv_path, &buf)) {
230*d685da8dShaad 				if (buf_lp.st_rdev == buf.st_rdev)
231*d685da8dShaad 					return 1;
232*d685da8dShaad 				else
233*d685da8dShaad 					log_warn("Symlink %s that should have been "
234*d685da8dShaad 						 "created by udev does not have "
235*d685da8dShaad 						 "correct target. Falling back to "
236*d685da8dShaad 						 "direct link creation", lv_path);
237*d685da8dShaad 			} else
238*d685da8dShaad 				log_warn("Symlink %s that should have been "
239*d685da8dShaad 					 "created by udev could not be checked "
240*d685da8dShaad 					 "for its correctness. Falling back to "
241*d685da8dShaad 					 "direct link creation.", lv_path);
242*d685da8dShaad 
243*d685da8dShaad 		}
244*d685da8dShaad 
24556a34939Shaad 		log_very_verbose("Removing %s", lv_path);
24656a34939Shaad 		if (unlink(lv_path) < 0) {
24756a34939Shaad 			log_sys_error("unlink", lv_path);
24856a34939Shaad 			return 0;
24956a34939Shaad 		}
250*d685da8dShaad 	} else if (dm_udev_get_sync_support())
251*d685da8dShaad 		log_warn("The link %s should had been created by udev "
252*d685da8dShaad 			  "but it was not found. Falling back to "
253*d685da8dShaad 			  "direct link creation.", lv_path);
25456a34939Shaad 
25556a34939Shaad 	log_very_verbose("Linking %s -> %s", lv_path, link_path);
25656a34939Shaad 	if (symlink(link_path, lv_path) < 0) {
25756a34939Shaad 		log_sys_error("symlink", lv_path);
25856a34939Shaad 		return 0;
25956a34939Shaad 	}
26056a34939Shaad 
26156a34939Shaad 	if (!dm_set_selinux_context(lv_path, S_IFLNK))
26256a34939Shaad 		return_0;
26356a34939Shaad 
26456a34939Shaad 	return 1;
26556a34939Shaad }
26656a34939Shaad 
_rm_link(const char * dev_dir,const char * vg_name,const char * lv_name)26756a34939Shaad static int _rm_link(const char *dev_dir, const char *vg_name,
26856a34939Shaad 		    const char *lv_name)
26956a34939Shaad {
27056a34939Shaad 	struct stat buf;
27156a34939Shaad 	char lv_path[PATH_MAX];
27256a34939Shaad 
273c6f73bb8Shaad #ifdef __NetBSD__
274c6f73bb8Shaad 	/* Add support for removing links to BSD raw devices */
275c6f73bb8Shaad 	char raw_lv_path[PATH_MAX];
276c6f73bb8Shaad 
277c6f73bb8Shaad 	if (dm_snprintf(raw_lv_path, sizeof(raw_lv_path), "%s%s/r%s",
278c6f73bb8Shaad 			 dev_dir, vg_name, lv_name) == -1) {
279c6f73bb8Shaad 		log_error("Couldn't determine link pathname.");
280c6f73bb8Shaad 		return 0;
281c6f73bb8Shaad 	}
282c6f73bb8Shaad 
283c6f73bb8Shaad 	if (lstat(raw_lv_path, &buf) || !S_ISLNK(buf.st_mode)) {
284c6f73bb8Shaad 		if (errno == ENOENT)
285c6f73bb8Shaad 			return 1;
286c6f73bb8Shaad 		log_error("%s not symbolic link - not removing", raw_lv_path);
287c6f73bb8Shaad 		return 0;
288c6f73bb8Shaad 	}
289c6f73bb8Shaad 
290c6f73bb8Shaad 	log_very_verbose("Removing link %s", raw_lv_path);
291c6f73bb8Shaad 	if (unlink(raw_lv_path) < 0) {
292c6f73bb8Shaad 		log_sys_error("unlink", raw_lv_path);
293c6f73bb8Shaad 		return 0;
294c6f73bb8Shaad 	}
295c6f73bb8Shaad #endif
29656a34939Shaad 	if (dm_snprintf(lv_path, sizeof(lv_path), "%s%s/%s",
29756a34939Shaad 			 dev_dir, vg_name, lv_name) == -1) {
29856a34939Shaad 		log_error("Couldn't determine link pathname.");
29956a34939Shaad 		return 0;
30056a34939Shaad 	}
30156a34939Shaad 
302*d685da8dShaad 	if (lstat(lv_path, &buf) && errno == ENOENT)
30356a34939Shaad 		return 1;
304*d685da8dShaad 	else if (dm_udev_get_sync_support())
305*d685da8dShaad 		log_warn("The link %s should have been removed by udev "
306*d685da8dShaad 			 "but it is still present. Falling back to "
307*d685da8dShaad 			 "direct link removal.", lv_path);
308*d685da8dShaad 
309*d685da8dShaad 	if (!S_ISLNK(buf.st_mode)) {
31056a34939Shaad 		log_error("%s not symbolic link - not removing", lv_path);
31156a34939Shaad 		return 0;
31256a34939Shaad 	}
31356a34939Shaad 
31456a34939Shaad 	log_very_verbose("Removing link %s", lv_path);
31556a34939Shaad 	if (unlink(lv_path) < 0) {
31656a34939Shaad 		log_sys_error("unlink", lv_path);
31756a34939Shaad 		return 0;
31856a34939Shaad 	}
31956a34939Shaad 
32056a34939Shaad 	return 1;
32156a34939Shaad }
32256a34939Shaad 
32356a34939Shaad typedef enum {
32456a34939Shaad 	FS_ADD,
32556a34939Shaad 	FS_DEL,
32656a34939Shaad 	FS_RENAME
32756a34939Shaad } fs_op_t;
32856a34939Shaad 
_do_fs_op(fs_op_t type,const char * dev_dir,const char * vg_name,const char * lv_name,const char * dev,const char * old_lv_name)32956a34939Shaad static int _do_fs_op(fs_op_t type, const char *dev_dir, const char *vg_name,
33056a34939Shaad 		     const char *lv_name, const char *dev,
33156a34939Shaad 		     const char *old_lv_name)
33256a34939Shaad {
33356a34939Shaad 	switch (type) {
33456a34939Shaad 	case FS_ADD:
33556a34939Shaad 		if (!_mk_dir(dev_dir, vg_name) ||
33656a34939Shaad 		    !_mk_link(dev_dir, vg_name, lv_name, dev))
33756a34939Shaad 			return_0;
33856a34939Shaad 		break;
33956a34939Shaad 	case FS_DEL:
34056a34939Shaad 		if (!_rm_link(dev_dir, vg_name, lv_name) ||
34156a34939Shaad 		    !_rm_dir(dev_dir, vg_name))
34256a34939Shaad 			return_0;
34356a34939Shaad 		break;
34456a34939Shaad 		/* FIXME Use rename() */
34556a34939Shaad 	case FS_RENAME:
34656a34939Shaad 		if (old_lv_name && !_rm_link(dev_dir, vg_name, old_lv_name))
34756a34939Shaad 			stack;
34856a34939Shaad 
34956a34939Shaad 		if (!_mk_link(dev_dir, vg_name, lv_name, dev))
35056a34939Shaad 			stack;
35156a34939Shaad 	}
35256a34939Shaad 
35356a34939Shaad 	return 1;
35456a34939Shaad }
35556a34939Shaad 
35656a34939Shaad static DM_LIST_INIT(_fs_ops);
35756a34939Shaad 
35856a34939Shaad struct fs_op_parms {
35956a34939Shaad 	struct dm_list list;
36056a34939Shaad 	fs_op_t type;
36156a34939Shaad 	char *dev_dir;
36256a34939Shaad 	char *vg_name;
36356a34939Shaad 	char *lv_name;
36456a34939Shaad 	char *dev;
36556a34939Shaad 	char *old_lv_name;
36656a34939Shaad 	char names[0];
36756a34939Shaad };
36856a34939Shaad 
_store_str(char ** pos,char ** ptr,const char * str)36956a34939Shaad static void _store_str(char **pos, char **ptr, const char *str)
37056a34939Shaad {
37156a34939Shaad 	strcpy(*pos, str);
37256a34939Shaad 	*ptr = *pos;
37356a34939Shaad 	*pos += strlen(*ptr) + 1;
37456a34939Shaad }
37556a34939Shaad 
_stack_fs_op(fs_op_t type,const char * dev_dir,const char * vg_name,const char * lv_name,const char * dev,const char * old_lv_name)37656a34939Shaad static int _stack_fs_op(fs_op_t type, const char *dev_dir, const char *vg_name,
37756a34939Shaad 			const char *lv_name, const char *dev,
37856a34939Shaad 			const char *old_lv_name)
37956a34939Shaad {
38056a34939Shaad 	struct fs_op_parms *fsp;
38156a34939Shaad 	size_t len = strlen(dev_dir) + strlen(vg_name) + strlen(lv_name) +
38256a34939Shaad 	    strlen(dev) + strlen(old_lv_name) + 5;
38356a34939Shaad 	char *pos;
38456a34939Shaad 
38556a34939Shaad 	if (!(fsp = dm_malloc(sizeof(*fsp) + len))) {
38656a34939Shaad 		log_error("No space to stack fs operation");
38756a34939Shaad 		return 0;
38856a34939Shaad 	}
38956a34939Shaad 
39056a34939Shaad 	pos = fsp->names;
39156a34939Shaad 	fsp->type = type;
39256a34939Shaad 
39356a34939Shaad 	_store_str(&pos, &fsp->dev_dir, dev_dir);
39456a34939Shaad 	_store_str(&pos, &fsp->vg_name, vg_name);
39556a34939Shaad 	_store_str(&pos, &fsp->lv_name, lv_name);
39656a34939Shaad 	_store_str(&pos, &fsp->dev, dev);
39756a34939Shaad 	_store_str(&pos, &fsp->old_lv_name, old_lv_name);
39856a34939Shaad 
39956a34939Shaad 	dm_list_add(&_fs_ops, &fsp->list);
40056a34939Shaad 
40156a34939Shaad 	return 1;
40256a34939Shaad }
40356a34939Shaad 
_pop_fs_ops(void)40456a34939Shaad static void _pop_fs_ops(void)
40556a34939Shaad {
40656a34939Shaad 	struct dm_list *fsph, *fspht;
40756a34939Shaad 	struct fs_op_parms *fsp;
40856a34939Shaad 
40956a34939Shaad 	dm_list_iterate_safe(fsph, fspht, &_fs_ops) {
41056a34939Shaad 		fsp = dm_list_item(fsph, struct fs_op_parms);
41156a34939Shaad 		_do_fs_op(fsp->type, fsp->dev_dir, fsp->vg_name, fsp->lv_name,
41256a34939Shaad 			  fsp->dev, fsp->old_lv_name);
41356a34939Shaad 		dm_list_del(&fsp->list);
41456a34939Shaad 		dm_free(fsp);
41556a34939Shaad 	}
41656a34939Shaad }
41756a34939Shaad 
_fs_op(fs_op_t type,const char * dev_dir,const char * vg_name,const char * lv_name,const char * dev,const char * old_lv_name)41856a34939Shaad static int _fs_op(fs_op_t type, const char *dev_dir, const char *vg_name,
41956a34939Shaad 		  const char *lv_name, const char *dev, const char *old_lv_name)
42056a34939Shaad {
42156a34939Shaad 	if (memlock()) {
42256a34939Shaad 		if (!_stack_fs_op(type, dev_dir, vg_name, lv_name, dev,
42356a34939Shaad 				  old_lv_name))
42456a34939Shaad 			return_0;
42556a34939Shaad 		return 1;
42656a34939Shaad 	}
42756a34939Shaad 
42856a34939Shaad 	return _do_fs_op(type, dev_dir, vg_name, lv_name, dev, old_lv_name);
42956a34939Shaad }
43056a34939Shaad 
fs_add_lv(const struct logical_volume * lv,const char * dev)43156a34939Shaad int fs_add_lv(const struct logical_volume *lv, const char *dev)
43256a34939Shaad {
43356a34939Shaad 	return _fs_op(FS_ADD, lv->vg->cmd->dev_dir, lv->vg->name, lv->name,
43456a34939Shaad 		      dev, "");
43556a34939Shaad }
43656a34939Shaad 
fs_del_lv(const struct logical_volume * lv)43756a34939Shaad int fs_del_lv(const struct logical_volume *lv)
43856a34939Shaad {
43956a34939Shaad 	return _fs_op(FS_DEL, lv->vg->cmd->dev_dir, lv->vg->name, lv->name,
44056a34939Shaad 		      "", "");
44156a34939Shaad }
44256a34939Shaad 
fs_del_lv_byname(const char * dev_dir,const char * vg_name,const char * lv_name)44356a34939Shaad int fs_del_lv_byname(const char *dev_dir, const char *vg_name, const char *lv_name)
44456a34939Shaad {
44556a34939Shaad 	return _fs_op(FS_DEL, dev_dir, vg_name, lv_name, "", "");
44656a34939Shaad }
44756a34939Shaad 
fs_rename_lv(struct logical_volume * lv,const char * dev,const char * old_vgname,const char * old_lvname)448526dfe53Shaad int fs_rename_lv(struct logical_volume *lv, const char *dev,
449526dfe53Shaad 		const char *old_vgname, const char *old_lvname)
45056a34939Shaad {
451526dfe53Shaad 	if (strcmp(old_vgname, lv->vg->name)) {
452526dfe53Shaad 		return
453526dfe53Shaad 			(_fs_op(FS_DEL, lv->vg->cmd->dev_dir, old_vgname, old_lvname, "", "") &&
454526dfe53Shaad 			 _fs_op(FS_ADD, lv->vg->cmd->dev_dir, lv->vg->name, lv->name, dev, ""));
455526dfe53Shaad 	}
456526dfe53Shaad 	else
45756a34939Shaad 		return _fs_op(FS_RENAME, lv->vg->cmd->dev_dir, lv->vg->name, lv->name,
458526dfe53Shaad 			      dev, old_lvname);
45956a34939Shaad }
46056a34939Shaad 
fs_unlock(void)46156a34939Shaad void fs_unlock(void)
46256a34939Shaad {
46356a34939Shaad 	if (!memlock()) {
46456a34939Shaad 		dm_lib_release();
46556a34939Shaad 		_pop_fs_ops();
46656a34939Shaad 	}
46756a34939Shaad }
468