All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] btrfs-progs: add options to sync filesystem after subvol delete
@ 2013-11-28 16:59 David Sterba
  2013-11-28 19:36 ` Roman Mamedov
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: David Sterba @ 2013-11-28 16:59 UTC (permalink / raw)
  To: linux-btrfs; +Cc: clm, David Sterba, Alex Lyakas

Subvolume deletion does not do a full transaction commit. This can lead
to an unexpected result when the system crashes between deletion and
commit, the subvolume directory will appear again. Add options to request
filesystem sync after each deleted subvolume or after the last one.

If the command with sync option finishes succesfully, the subvolume(s)
deletion status is safely stored on the media.

Userspace approach is more flexible than in-kernel. Related discussions:
http://www.spinics.net/lists/linux-btrfs/msg22088.html
http://www.spinics.net/lists/linux-btrfs/msg27240.html

CC: Alex Lyakas <alex.btrfs@zadarastorage.com>
Signed-off-by: David Sterba <dsterba@suse.cz>
---

The option names may not be ideal, feel free to suggest better.

 cmds-subvolume.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
 man/btrfs.8.in   | 23 ++++++++++++++---
 2 files changed, 90 insertions(+), 10 deletions(-)

diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index c6a5284a02a4..c124c3185252 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -202,24 +202,67 @@ int test_issubvolume(char *path)
 }
 
 static const char * const cmd_subvol_delete_usage[] = {
-	"btrfs subvolume delete <subvolume> [<subvolume>...]",
+	"btrfs subvolume delete [options] <subvolume> [<subvolume>...]",
 	"Delete subvolume(s)",
+	"Delete subvolumes from the filesystem. The corresponding directory",
+	"is removed instantly but the data blocks are removed later.",
+	"The deletion does not involve full commit by default due to",
+	"performance reasons (as a consequence, the subvolume may appear again",
+	"after a crash). Use one of the --sync options to sync the filesystem",
+	"via a btrfs specific ioctl.",
+	"",
+	"-s|--sync-after      call sync at the end of the operation",
+	"-S|--sync-each       sync the filesystem after deleting each subvolume",
 	NULL
 };
 
 static int cmd_subvol_delete(int argc, char **argv)
 {
-	int	res, fd, len, e, cnt = 1, ret = 0;
+	int	res, len, e, ret = 0;
+	int cnt;
+	int fd = -1;
 	struct btrfs_ioctl_vol_args	args;
 	char	*dname, *vname, *cpath;
 	char	*dupdname = NULL;
 	char	*dupvname = NULL;
 	char	*path;
 	DIR	*dirstream = NULL;
+	int sync_mode = 0;
+	struct option long_options[] = {
+		{"sync-after", no_argument, NULL, 's'},	/* sync mode 1 */
+		{"sync-each", no_argument, NULL, 'S'},	/* sync mode 2 */
+		{NULL, 0, NULL, 0}
+	};
 
-	if (argc < 2)
+	optind = 1;
+	while (1) {
+		int c;
+
+		c = getopt_long(argc, argv, "sS", long_options, NULL);
+		if (c < 0)
+			break;
+
+		switch(c) {
+		case 's':
+			sync_mode = 1;
+			break;
+		case 'S':
+			sync_mode = 2;
+			break;
+		default:
+			usage(cmd_subvol_delete_usage);
+		}
+	}
+
+	if (check_argc_min(argc - optind, 1))
 		usage(cmd_subvol_delete_usage);
 
+	printf("Sync filesystem mode: %s\n",
+		!sync_mode ? "none (default)" :
+		sync_mode == 1 ? "at the end" : "after each");
+
+	cnt = optind;
+
 again:
 	path = argv[cnt];
 
@@ -276,8 +319,6 @@ again:
 	res = ioctl(fd, BTRFS_IOC_SNAP_DESTROY, &args);
 	e = errno;
 
-	close_file_or_dir(fd, dirstream);
-
 	if(res < 0 ){
 		fprintf( stderr, "ERROR: cannot delete '%s/%s' - %s\n",
 			dname, vname, strerror(e));
@@ -285,14 +326,38 @@ again:
 		goto out;
 	}
 
+	if (sync_mode == 1) {
+		res = ioctl(fd, BTRFS_IOC_SYNC);
+		if (res < 0) {
+			fprintf(stderr,
+				"ERROR: unable to sync after '%s': %s\n",
+				path, strerror(e));
+			ret = 1;
+		}
+	}
+
 out:
 	free(dupdname);
 	free(dupvname);
 	dupdname = NULL;
 	dupvname = NULL;
 	cnt++;
-	if (cnt < argc)
+	if (cnt < argc) {
+		close_file_or_dir(fd, dirstream);
 		goto again;
+	}
+
+	if (sync_mode == 2 && fd != -1) {
+		res = ioctl(fd, BTRFS_IOC_SYNC);
+		e = errno;
+		if (res < 0) {
+			fprintf(stderr,
+				"ERROR: unable to do final sync: %s\n",
+				strerror(e));
+			ret = 1;
+		}
+	}
+	close_file_or_dir(fd, dirstream);
 
 	return ret;
 }
diff --git a/man/btrfs.8.in b/man/btrfs.8.in
index b6203483296e..2d5c12e08640 100644
--- a/man/btrfs.8.in
+++ b/man/btrfs.8.in
@@ -8,7 +8,7 @@ btrfs \- control a btrfs filesystem
 .SH SYNOPSIS
 \fBbtrfs\fP \fBsubvolume create\fP [-i \fI<qgroupid>\fP] [\fI<dest>\fP/]\fI<name>\fP
 .PP
-\fBbtrfs\fP \fBsubvolume delete\fP \fI<subvolume>\fP [\fI<subvolume>...\fP]
+\fBbtrfs\fP \fBsubvolume delete\fP [\fIoptions\fP] \fI<subvolume>\fP [\fI<subvolume>...\fP]
 .PP
 \fBbtrfs\fP \fBsubvolume list\fP [\fIoptions\fP] [-G [+|-]\fIvalue\fP] [-C [+|-]\fIvalue\fP] [--sort=rootid,gen,ogen,path] \fI<path>\fP
 .PP
@@ -168,9 +168,24 @@ times.
 .RE
 .TP
 
-\fBsubvolume delete\fR\fI <subvolume> \fP[\fI<subvolume>...\fP]\fR
-Delete the subvolume \fI<subvolume>\fR. If \fI<subvolume>\fR is not a
-subvolume, \fBbtrfs\fR returns an error.
+\fBsubvolume delete\fR [\fIoptions\fP] \fI<subvolume>\fP [\fI<subvolume>...\fP]\fR
+Delete the subvolume(s) from the filesystem. If \fI<subvolume>\fR is not a
+subvolume, \fBbtrfs\fR returns an error but continues if there are more arguments
+to process.
+
+The corresponding directory is removed instantly but the data blocks are
+removed later.  The deletion does not involve full commit by default due to
+performance reasons (as a consequence, the subvolume may appear again after a
+crash).  Use one of the --sync options to sync the filesystem via a btrfs
+specific ioctl.
+.RS
+
+\fIOptions\fP
+.IP "\fB-s|--sync-after\fP" 5
+call sync at the end of the operation
+.IP "\fB-S|--sync-each\fP" 5
+sync the filesystem after deleting each subvolume
+.RE
 .TP
 
 \fBsubvolume list\fR [\fIoptions\fP] [-G [+|-]\fIvalue\fP] [-C [+|-]\fIvalue\fP] [--sort=rootid,gen,ogen,path] \fI<path>\fR
-- 
1.8.4.3


^ permalink raw reply related	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2013-12-12 18:07 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-11-28 16:59 [PATCH] btrfs-progs: add options to sync filesystem after subvol delete David Sterba
2013-11-28 19:36 ` Roman Mamedov
2013-11-29  2:04   ` Wang Shilong
2013-11-29 17:37     ` David Sterba
2013-12-02  9:02       ` Wang Shilong
2013-12-09 23:32         ` David Sterba
2013-12-10 13:17           ` Chris Mason
2013-12-10 17:36             ` David Sterba
2013-12-10 18:24               ` Chris Mason
2013-12-12 18:07                 ` David Sterba
2013-11-29  5:13 ` Miao Xie
2013-11-29 17:05   ` David Sterba
2013-11-29  8:05 ` Anand Jain

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.