All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/6] More send v2 updates: otime, fileattr
@ 2022-06-15 13:24 David Sterba
  2022-06-15 13:24 ` [PATCH 1/6] btrfs: send: add OTIME as utimes attribute for proto 2+ by default David Sterba
                   ` (6 more replies)
  0 siblings, 7 replies; 9+ messages in thread
From: David Sterba @ 2022-06-15 13:24 UTC (permalink / raw)
  To: linux-btrfs; +Cc: David Sterba

New protocol enhancements:

- send otime with utimes command
- rename SETFLAGS to FILEATTR and send the btrfs inode flags
- other cleanups

David Sterba (6):
  btrfs: send: add OTIME as utimes attribute for proto 2+ by default
  btrfs: send: add new command FILEATTR for file attributes
  btrfs: send: drop __KERNEL__ ifdef from send.h
  btrfs: send: simplify includes
  btrfs: send: remove old TODO regarding ERESTARTSYS
  btrfs: send: use boolean types for current inode status

 fs/btrfs/send.c | 147 ++++++++++++++++++++++++++++++++----------------
 fs/btrfs/send.h |  17 ++++--
 2 files changed, 109 insertions(+), 55 deletions(-)

-- 
2.36.1


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

* [PATCH 1/6] btrfs: send: add OTIME as utimes attribute for proto 2+ by default
  2022-06-15 13:24 [PATCH 0/6] More send v2 updates: otime, fileattr David Sterba
@ 2022-06-15 13:24 ` David Sterba
  2022-06-15 13:25 ` [PATCH 2/6] btrfs: send: add new command FILEATTR for file attributes David Sterba
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: David Sterba @ 2022-06-15 13:24 UTC (permalink / raw)
  To: linux-btrfs; +Cc: David Sterba

When send v1 was introduced the otime (inode creation time) was not
available, however the attribute in btrfs send protocol exists. Though
it would be possible to add it for v1 too as the attribute would be
ignored by v1 receive, let's not change the layout of v1 and only add
that to v2+.  The otime cannot be changed and is only informative.

Signed-off-by: David Sterba <dsterba@suse.com>
---
 fs/btrfs/send.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 7de6aa5056cd..63f48a2aa3d4 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -2580,7 +2580,8 @@ static int send_utimes(struct send_ctx *sctx, u64 ino, u64 gen)
 	TLV_PUT_BTRFS_TIMESPEC(sctx, BTRFS_SEND_A_ATIME, eb, &ii->atime);
 	TLV_PUT_BTRFS_TIMESPEC(sctx, BTRFS_SEND_A_MTIME, eb, &ii->mtime);
 	TLV_PUT_BTRFS_TIMESPEC(sctx, BTRFS_SEND_A_CTIME, eb, &ii->ctime);
-	/* TODO Add otime support when the otime patches get into upstream */
+	if (sctx->proto >= 2)
+		TLV_PUT_BTRFS_TIMESPEC(sctx, BTRFS_SEND_A_OTIME, eb, &ii->otime);
 
 	ret = send_cmd(sctx);
 
-- 
2.36.1


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

* [PATCH 2/6] btrfs: send: add new command FILEATTR for file attributes
  2022-06-15 13:24 [PATCH 0/6] More send v2 updates: otime, fileattr David Sterba
  2022-06-15 13:24 ` [PATCH 1/6] btrfs: send: add OTIME as utimes attribute for proto 2+ by default David Sterba
@ 2022-06-15 13:25 ` David Sterba
  2022-06-15 13:25 ` [PATCH 3/6] btrfs: send: drop __KERNEL__ ifdef from send.h David Sterba
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: David Sterba @ 2022-06-15 13:25 UTC (permalink / raw)
  To: linux-btrfs; +Cc: David Sterba

There are file attributes inherited from previous ext2 SETFLAGS/GETFLAGS
and later from XFLAGS interfaces, now commonly found under the
'fileattr' API. This corresponds to the individual inode bits and that's
part of the on-disk format, so this is suitable for the protocol. The
other interfaces contain a lot of cruft or bits that btrfs does not
support yet.

Currently the value is u64 and matches btrfs_inode_item. Not all the
bits can be set by ioctls (like NODATASUM or READONLY), but we can send
them over the protocol and leave it up to the receiving side what and
how to apply.

As some of the flags, eg. IMMUTABLE, can prevent any further changes,
the receiving side needs to understand that and apply the changes in the
right order, or possibly with some intermediate steps. This should be
easier, future proof and simpler on the protocol layer than implementing
in kernel.

Signed-off-by: David Sterba <dsterba@suse.com>
---
 fs/btrfs/send.c | 104 +++++++++++++++++++++++++++++++++++-------------
 fs/btrfs/send.h |  10 ++++-
 2 files changed, 85 insertions(+), 29 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 63f48a2aa3d4..ba87e1ba1f2a 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -846,7 +846,7 @@ static int send_rmdir(struct send_ctx *sctx, struct fs_path *path)
  */
 static int __get_inode_info(struct btrfs_root *root, struct btrfs_path *path,
 			  u64 ino, u64 *size, u64 *gen, u64 *mode, u64 *uid,
-			  u64 *gid, u64 *rdev)
+			  u64 *gid, u64 *rdev, u64 *fileattr)
 {
 	int ret;
 	struct btrfs_inode_item *ii;
@@ -876,6 +876,12 @@ static int __get_inode_info(struct btrfs_root *root, struct btrfs_path *path,
 		*gid = btrfs_inode_gid(path->nodes[0], ii);
 	if (rdev)
 		*rdev = btrfs_inode_rdev(path->nodes[0], ii);
+	/*
+	 * Transfer the unchanged u64 value of btrfs_inode_item::flags, that's
+	 * otherwise logically split to 32/32 parts.
+	 */
+	if (fileattr)
+		*fileattr = btrfs_stack_inode_flags(ii);
 
 	return ret;
 }
@@ -883,7 +889,7 @@ static int __get_inode_info(struct btrfs_root *root, struct btrfs_path *path,
 static int get_inode_info(struct btrfs_root *root,
 			  u64 ino, u64 *size, u64 *gen,
 			  u64 *mode, u64 *uid, u64 *gid,
-			  u64 *rdev)
+			  u64 *rdev, u64 *fileattr)
 {
 	struct btrfs_path *path;
 	int ret;
@@ -892,7 +898,7 @@ static int get_inode_info(struct btrfs_root *root,
 	if (!path)
 		return -ENOMEM;
 	ret = __get_inode_info(root, path, ino, size, gen, mode, uid, gid,
-			       rdev);
+			       rdev, fileattr);
 	btrfs_free_path(path);
 	return ret;
 }
@@ -1638,7 +1644,7 @@ static int get_cur_inode_state(struct send_ctx *sctx, u64 ino, u64 gen)
 	u64 right_gen;
 
 	ret = get_inode_info(sctx->send_root, ino, NULL, &left_gen, NULL, NULL,
-			NULL, NULL);
+			NULL, NULL, NULL);
 	if (ret < 0 && ret != -ENOENT)
 		goto out;
 	left_ret = ret;
@@ -1647,7 +1653,7 @@ static int get_cur_inode_state(struct send_ctx *sctx, u64 ino, u64 gen)
 		right_ret = -ENOENT;
 	} else {
 		ret = get_inode_info(sctx->parent_root, ino, NULL, &right_gen,
-				NULL, NULL, NULL, NULL);
+				NULL, NULL, NULL, NULL, NULL);
 		if (ret < 0 && ret != -ENOENT)
 			goto out;
 		right_ret = ret;
@@ -1810,7 +1816,7 @@ static int get_first_ref(struct btrfs_root *root, u64 ino,
 
 	if (dir_gen) {
 		ret = get_inode_info(root, parent_dir, NULL, dir_gen, NULL,
-				     NULL, NULL, NULL);
+				     NULL, NULL, NULL, NULL);
 		if (ret < 0)
 			goto out;
 	}
@@ -1882,7 +1888,7 @@ static int will_overwrite_ref(struct send_ctx *sctx, u64 dir, u64 dir_gen,
 	 */
 	if (sctx->parent_root && dir != BTRFS_FIRST_FREE_OBJECTID) {
 		ret = get_inode_info(sctx->parent_root, dir, NULL, &gen, NULL,
-				     NULL, NULL, NULL);
+				     NULL, NULL, NULL, NULL);
 		if (ret < 0 && ret != -ENOENT)
 			goto out;
 		if (ret) {
@@ -1910,7 +1916,7 @@ static int will_overwrite_ref(struct send_ctx *sctx, u64 dir, u64 dir_gen,
 	if (other_inode > sctx->send_progress ||
 	    is_waiting_for_move(sctx, other_inode)) {
 		ret = get_inode_info(sctx->parent_root, other_inode, NULL,
-				who_gen, who_mode, NULL, NULL, NULL);
+				who_gen, who_mode, NULL, NULL, NULL, NULL);
 		if (ret < 0)
 			goto out;
 
@@ -1949,7 +1955,7 @@ static int did_overwrite_ref(struct send_ctx *sctx,
 
 	if (dir != BTRFS_FIRST_FREE_OBJECTID) {
 		ret = get_inode_info(sctx->send_root, dir, NULL, &gen, NULL,
-				     NULL, NULL, NULL);
+				     NULL, NULL, NULL, NULL);
 		if (ret < 0 && ret != -ENOENT)
 			goto out;
 		if (ret) {
@@ -1972,7 +1978,7 @@ static int did_overwrite_ref(struct send_ctx *sctx,
 	}
 
 	ret = get_inode_info(sctx->send_root, ow_inode, NULL, &gen, NULL, NULL,
-			NULL, NULL);
+			NULL, NULL, NULL);
 	if (ret < 0)
 		goto out;
 
@@ -2501,6 +2507,39 @@ static int send_chmod(struct send_ctx *sctx, u64 ino, u64 gen, u64 mode)
 	return ret;
 }
 
+static int send_fileattr(struct send_ctx *sctx, u64 ino, u64 gen, u64 fileattr)
+{
+	struct btrfs_fs_info *fs_info = sctx->send_root->fs_info;
+	int ret = 0;
+	struct fs_path *p;
+
+	if (sctx->proto < 2)
+		return 0;
+
+	btrfs_debug(fs_info, "send_fileattr %llu fileattr=%llu", ino, fileattr);
+
+	p = fs_path_alloc();
+	if (!p)
+		return -ENOMEM;
+
+	ret = begin_cmd(sctx, BTRFS_SEND_C_FILEATTR);
+	if (ret < 0)
+		goto out;
+
+	ret = get_cur_path(sctx, ino, gen, p);
+	if (ret < 0)
+		goto out;
+	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
+	TLV_PUT_U64(sctx, BTRFS_SEND_A_FILEATTR, fileattr);
+
+	ret = send_cmd(sctx);
+
+tlv_put_failure:
+out:
+	fs_path_free(p);
+	return ret;
+}
+
 static int send_chown(struct send_ctx *sctx, u64 ino, u64 gen, u64 uid, u64 gid)
 {
 	struct btrfs_fs_info *fs_info = sctx->send_root->fs_info;
@@ -2615,7 +2654,7 @@ static int send_create_inode(struct send_ctx *sctx, u64 ino)
 
 	if (ino != sctx->cur_ino) {
 		ret = get_inode_info(sctx->send_root, ino, NULL, &gen, &mode,
-				     NULL, NULL, &rdev);
+				     NULL, NULL, &rdev, NULL);
 		if (ret < 0)
 			goto out;
 	} else {
@@ -3318,7 +3357,7 @@ static int apply_dir_move(struct send_ctx *sctx, struct pending_dir_move *pm)
 		 * The parent inode might have been deleted in the send snapshot
 		 */
 		ret = get_inode_info(sctx->send_root, cur->dir, NULL,
-				     NULL, NULL, NULL, NULL, NULL);
+				     NULL, NULL, NULL, NULL, NULL, NULL);
 		if (ret == -ENOENT) {
 			ret = 0;
 			continue;
@@ -3493,11 +3532,11 @@ static int wait_for_dest_dir_move(struct send_ctx *sctx,
 	}
 
 	ret = get_inode_info(sctx->parent_root, di_key.objectid, NULL,
-			     &left_gen, NULL, NULL, NULL, NULL);
+			     &left_gen, NULL, NULL, NULL, NULL, NULL);
 	if (ret < 0)
 		goto out;
 	ret = get_inode_info(sctx->send_root, di_key.objectid, NULL,
-			     &right_gen, NULL, NULL, NULL, NULL);
+			     &right_gen, NULL, NULL, NULL, NULL, NULL);
 	if (ret < 0) {
 		if (ret == -ENOENT)
 			ret = 0;
@@ -3628,7 +3667,7 @@ static int is_ancestor(struct btrfs_root *root,
 			}
 
 			ret = get_inode_info(root, parent, NULL, &parent_gen,
-					     NULL, NULL, NULL, NULL);
+					     NULL, NULL, NULL, NULL, NULL);
 			if (ret < 0)
 				goto out;
 			ret = check_ino_in_path(root, ino1, ino1_gen,
@@ -3720,7 +3759,7 @@ static int wait_for_parent_move(struct send_ctx *sctx,
 
 			ret = get_inode_info(sctx->parent_root, ino, NULL,
 					     &parent_ino_gen, NULL, NULL, NULL,
-					     NULL);
+					     NULL, NULL);
 			if (ret < 0)
 				goto out;
 			if (ino_gen == parent_ino_gen) {
@@ -4326,8 +4365,7 @@ static int record_ref(struct btrfs_root *root, u64 dir, struct fs_path *name,
 	if (!p)
 		return -ENOMEM;
 
-	ret = get_inode_info(root, dir, NULL, &gen, NULL, NULL,
-			NULL, NULL);
+	ret = get_inode_info(root, dir, NULL, &gen, NULL, NULL, NULL, NULL, NULL);
 	if (ret < 0)
 		goto out;
 
@@ -4415,7 +4453,7 @@ static int __find_iref(int num, u64 dir, int index,
 		 * else matches.
 		 */
 		ret = get_inode_info(ctx->root, dir, NULL, &dir_gen, NULL,
-				     NULL, NULL, NULL);
+				     NULL, NULL, NULL, NULL);
 		if (ret)
 			return ret;
 		if (dir_gen != ctx->dir_gen)
@@ -4459,7 +4497,7 @@ static int __record_changed_new_ref(int num, u64 dir, int index,
 	struct send_ctx *sctx = ctx;
 
 	ret = get_inode_info(sctx->send_root, dir, NULL, &dir_gen, NULL,
-			     NULL, NULL, NULL);
+			     NULL, NULL, NULL, NULL);
 	if (ret)
 		return ret;
 
@@ -4482,7 +4520,7 @@ static int __record_changed_deleted_ref(int num, u64 dir, int index,
 	struct send_ctx *sctx = ctx;
 
 	ret = get_inode_info(sctx->parent_root, dir, NULL, &dir_gen, NULL,
-			     NULL, NULL, NULL);
+			     NULL, NULL, NULL, NULL);
 	if (ret)
 		return ret;
 
@@ -5031,7 +5069,7 @@ static int send_clone(struct send_ctx *sctx,
 
 	if (clone_root->root == sctx->send_root) {
 		ret = get_inode_info(sctx->send_root, clone_root->ino, NULL,
-				&gen, NULL, NULL, NULL, NULL);
+				&gen, NULL, NULL, NULL, NULL, NULL);
 		if (ret < 0)
 			goto out;
 		ret = get_cur_path(sctx, clone_root->ino, gen, p);
@@ -5540,7 +5578,8 @@ static int clone_range(struct send_ctx *sctx, struct btrfs_path *dst_path,
 	 * accept clones from these extents.
 	 */
 	ret = __get_inode_info(clone_root->root, path, clone_root->ino,
-			       &clone_src_i_size, NULL, NULL, NULL, NULL, NULL);
+			       &clone_src_i_size, NULL, NULL, NULL, NULL, NULL,
+			       NULL);
 	btrfs_release_path(path);
 	if (ret < 0)
 		goto out;
@@ -6235,11 +6274,14 @@ static int finish_inode_if_needed(struct send_ctx *sctx, int at_end)
 	u64 left_mode;
 	u64 left_uid;
 	u64 left_gid;
+	u64 left_fileattr;
 	u64 right_mode;
 	u64 right_uid;
 	u64 right_gid;
+	u64 right_fileattr;
 	int need_chmod = 0;
 	int need_chown = 0;
+	bool need_fileattr = false;
 	int need_truncate = 1;
 	int pending_move = 0;
 	int refs_processed = 0;
@@ -6273,7 +6315,7 @@ static int finish_inode_if_needed(struct send_ctx *sctx, int at_end)
 		goto out;
 
 	ret = get_inode_info(sctx->send_root, sctx->cur_ino, NULL, NULL,
-			&left_mode, &left_uid, &left_gid, NULL);
+			&left_mode, &left_uid, &left_gid, NULL, &left_fileattr);
 	if (ret < 0)
 		goto out;
 
@@ -6288,7 +6330,7 @@ static int finish_inode_if_needed(struct send_ctx *sctx, int at_end)
 
 		ret = get_inode_info(sctx->parent_root, sctx->cur_ino,
 				&old_size, NULL, &right_mode, &right_uid,
-				&right_gid, NULL);
+				&right_gid, NULL, &right_fileattr);
 		if (ret < 0)
 			goto out;
 
@@ -6296,6 +6338,8 @@ static int finish_inode_if_needed(struct send_ctx *sctx, int at_end)
 			need_chown = 1;
 		if (!S_ISLNK(sctx->cur_inode_mode) && left_mode != right_mode)
 			need_chmod = 1;
+		if (!S_ISLNK(sctx->cur_inode_mode) && left_fileattr != right_fileattr)
+			need_fileattr = true;
 		if ((old_size == sctx->cur_inode_size) ||
 		    (sctx->cur_inode_size > old_size &&
 		     sctx->cur_inode_next_write_offset == sctx->cur_inode_size))
@@ -6339,6 +6383,12 @@ static int finish_inode_if_needed(struct send_ctx *sctx, int at_end)
 		if (ret < 0)
 			goto out;
 	}
+	if (need_fileattr) {
+		ret = send_fileattr(sctx, sctx->cur_ino, sctx->cur_inode_gen,
+				    left_fileattr);
+		if (ret < 0)
+			goto out;
+	}
 
 	ret = send_capabilities(sctx);
 	if (ret < 0)
@@ -6750,12 +6800,12 @@ static int dir_changed(struct send_ctx *sctx, u64 dir)
 	int ret;
 
 	ret = get_inode_info(sctx->send_root, dir, NULL, &new_gen, NULL, NULL,
-			     NULL, NULL);
+			     NULL, NULL, NULL);
 	if (ret)
 		return ret;
 
 	ret = get_inode_info(sctx->parent_root, dir, NULL, &orig_gen, NULL,
-			     NULL, NULL, NULL);
+			     NULL, NULL, NULL, NULL);
 	if (ret)
 		return ret;
 
diff --git a/fs/btrfs/send.h b/fs/btrfs/send.h
index b0dc07567d09..f954ce6f17d8 100644
--- a/fs/btrfs/send.h
+++ b/fs/btrfs/send.h
@@ -85,7 +85,7 @@ enum btrfs_send_cmd {
 
 	/* Version 2 */
 	BTRFS_SEND_C_FALLOCATE		= 23,
-	BTRFS_SEND_C_SETFLAGS		= 24,
+	BTRFS_SEND_C_FILEATTR		= 24,
 	BTRFS_SEND_C_ENCODED_WRITE	= 25,
 	BTRFS_SEND_C_MAX_V2		= 25,
 
@@ -138,7 +138,13 @@ enum {
 	/* Version 2 */
 	BTRFS_SEND_A_FALLOCATE_MODE	= 25,
 
-	BTRFS_SEND_A_SETFLAGS_FLAGS	= 26,
+	/*
+	 * File attributes from the FS_*_FL namespace (i_flags, xflags),
+	 * translated to BTRFS_INODE_* bits (BTRFS_INODE_FLAG_MASK) and stored
+	 * in btrfs_inode_item::flags (represented by btrfs_inode::flags and
+	 * btrfs_inode::ro_flags).
+	 */
+	BTRFS_SEND_A_FILEATTR		= 26,
 
 	BTRFS_SEND_A_UNENCODED_FILE_LEN	= 27,
 	BTRFS_SEND_A_UNENCODED_LEN	= 28,
-- 
2.36.1


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

* [PATCH 3/6] btrfs: send: drop __KERNEL__ ifdef from send.h
  2022-06-15 13:24 [PATCH 0/6] More send v2 updates: otime, fileattr David Sterba
  2022-06-15 13:24 ` [PATCH 1/6] btrfs: send: add OTIME as utimes attribute for proto 2+ by default David Sterba
  2022-06-15 13:25 ` [PATCH 2/6] btrfs: send: add new command FILEATTR for file attributes David Sterba
@ 2022-06-15 13:25 ` David Sterba
  2022-06-15 13:25 ` [PATCH 4/6] btrfs: send: simplify includes David Sterba
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: David Sterba @ 2022-06-15 13:25 UTC (permalink / raw)
  To: linux-btrfs; +Cc: David Sterba

We don't need this ifdef as the header file is not shared, the protocol
definition used by userspace should be from libbtrfs or libbtrfsutil.

Signed-off-by: David Sterba <dsterba@suse.com>
---
 fs/btrfs/send.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/fs/btrfs/send.h b/fs/btrfs/send.h
index f954ce6f17d8..2cce43ddcad5 100644
--- a/fs/btrfs/send.h
+++ b/fs/btrfs/send.h
@@ -161,8 +161,6 @@ enum {
 	BTRFS_SEND_A_MAX		= 31,
 };
 
-#ifdef __KERNEL__
 long btrfs_ioctl_send(struct inode *inode, struct btrfs_ioctl_send_args *arg);
-#endif
 
 #endif
-- 
2.36.1


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

* [PATCH 4/6] btrfs: send: simplify includes
  2022-06-15 13:24 [PATCH 0/6] More send v2 updates: otime, fileattr David Sterba
                   ` (2 preceding siblings ...)
  2022-06-15 13:25 ` [PATCH 3/6] btrfs: send: drop __KERNEL__ ifdef from send.h David Sterba
@ 2022-06-15 13:25 ` David Sterba
  2022-06-15 13:25 ` [PATCH 5/6] btrfs: send: remove old TODO regarding ERESTARTSYS David Sterba
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: David Sterba @ 2022-06-15 13:25 UTC (permalink / raw)
  To: linux-btrfs; +Cc: David Sterba

We don't need the whole ctree.h in send.h, none of the data types
defined there are used.

Signed-off-by: David Sterba <dsterba@suse.com>
---
 fs/btrfs/send.c | 1 +
 fs/btrfs/send.h | 5 ++++-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index ba87e1ba1f2a..d8d4f062cd4f 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -16,6 +16,7 @@
 #include <linux/crc32c.h>
 
 #include "send.h"
+#include "ctree.h"
 #include "backref.h"
 #include "locking.h"
 #include "disk-io.h"
diff --git a/fs/btrfs/send.h b/fs/btrfs/send.h
index 2cce43ddcad5..4bb4e6a638cb 100644
--- a/fs/btrfs/send.h
+++ b/fs/btrfs/send.h
@@ -7,7 +7,7 @@
 #ifndef BTRFS_SEND_H
 #define BTRFS_SEND_H
 
-#include "ctree.h"
+#include <linux/types.h>
 
 #define BTRFS_SEND_STREAM_MAGIC "btrfs-stream"
 #define BTRFS_SEND_STREAM_VERSION 2
@@ -18,6 +18,9 @@
  */
 #define BTRFS_SEND_BUF_SIZE_V1				SZ_64K
 
+struct inode;
+struct btrfs_ioctl_send_args;
+
 enum btrfs_tlv_type {
 	BTRFS_TLV_U8,
 	BTRFS_TLV_U16,
-- 
2.36.1


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

* [PATCH 5/6] btrfs: send: remove old TODO regarding ERESTARTSYS
  2022-06-15 13:24 [PATCH 0/6] More send v2 updates: otime, fileattr David Sterba
                   ` (3 preceding siblings ...)
  2022-06-15 13:25 ` [PATCH 4/6] btrfs: send: simplify includes David Sterba
@ 2022-06-15 13:25 ` David Sterba
  2022-06-15 13:25 ` [PATCH 6/6] btrfs: send: use boolean types for current inode status David Sterba
  2022-06-23 14:29 ` [PATCH 0/6] More send v2 updates: otime, fileattr David Sterba
  6 siblings, 0 replies; 9+ messages in thread
From: David Sterba @ 2022-06-15 13:25 UTC (permalink / raw)
  To: linux-btrfs; +Cc: David Sterba

The whole send operation is restartable and handling properly a buffer
write may not be easy. We can't know what caused that and if a short
delay and retry will fix it or how many retries should be performed in
case it's a temporary condition.

The error value is returned to the ioctl caller so in case it's
transient problem, the user would be notified about the reason. Remove
the TODO note as there's no plan to handle ERESTARTSYS.

Signed-off-by: David Sterba <dsterba@suse.com>
---
 fs/btrfs/send.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index d8d4f062cd4f..f6469c7666c9 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -580,15 +580,10 @@ static int write_buf(struct file *filp, const void *buf, u32 len, loff_t *off)
 
 	while (pos < len) {
 		ret = kernel_write(filp, buf + pos, len - pos, off);
-		/* TODO handle that correctly */
-		/*if (ret == -ERESTARTSYS) {
-			continue;
-		}*/
 		if (ret < 0)
 			return ret;
-		if (ret == 0) {
+		if (ret == 0)
 			return -EIO;
-		}
 		pos += ret;
 	}
 
-- 
2.36.1


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

* [PATCH 6/6] btrfs: send: use boolean types for current inode status
  2022-06-15 13:24 [PATCH 0/6] More send v2 updates: otime, fileattr David Sterba
                   ` (4 preceding siblings ...)
  2022-06-15 13:25 ` [PATCH 5/6] btrfs: send: remove old TODO regarding ERESTARTSYS David Sterba
@ 2022-06-15 13:25 ` David Sterba
  2022-06-23 14:29 ` [PATCH 0/6] More send v2 updates: otime, fileattr David Sterba
  6 siblings, 0 replies; 9+ messages in thread
From: David Sterba @ 2022-06-15 13:25 UTC (permalink / raw)
  To: linux-btrfs; +Cc: David Sterba

The new, new_gen and deleted indicate a status, use boolean type instead
of int.

Signed-off-by: David Sterba <dsterba@suse.com>
---
 fs/btrfs/send.c | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index f6469c7666c9..b417674a36b9 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -117,9 +117,9 @@ struct send_ctx {
 	 */
 	u64 cur_ino;
 	u64 cur_inode_gen;
-	int cur_inode_new;
-	int cur_inode_new_gen;
-	int cur_inode_deleted;
+	bool cur_inode_new;
+	bool cur_inode_new_gen;
+	bool cur_inode_deleted;
 	u64 cur_inode_size;
 	u64 cur_inode_mode;
 	u64 cur_inode_rdev;
@@ -6529,7 +6529,7 @@ static int changed_inode(struct send_ctx *sctx,
 	close_current_inode(sctx);
 
 	sctx->cur_ino = key->objectid;
-	sctx->cur_inode_new_gen = 0;
+	sctx->cur_inode_new_gen = false;
 	sctx->cur_inode_last_extent = (u64)-1;
 	sctx->cur_inode_next_write_offset = 0;
 	sctx->ignore_cur_inode = false;
@@ -6570,7 +6570,7 @@ static int changed_inode(struct send_ctx *sctx,
 		 */
 		if (left_gen != right_gen &&
 		    sctx->cur_ino != BTRFS_FIRST_FREE_OBJECTID)
-			sctx->cur_inode_new_gen = 1;
+			sctx->cur_inode_new_gen = true;
 	}
 
 	/*
@@ -6602,8 +6602,8 @@ static int changed_inode(struct send_ctx *sctx,
 
 	if (result == BTRFS_COMPARE_TREE_NEW) {
 		sctx->cur_inode_gen = left_gen;
-		sctx->cur_inode_new = 1;
-		sctx->cur_inode_deleted = 0;
+		sctx->cur_inode_new = true;
+		sctx->cur_inode_deleted = false;
 		sctx->cur_inode_size = btrfs_inode_size(
 				sctx->left_path->nodes[0], left_ii);
 		sctx->cur_inode_mode = btrfs_inode_mode(
@@ -6614,8 +6614,8 @@ static int changed_inode(struct send_ctx *sctx,
 			ret = send_create_inode_if_needed(sctx);
 	} else if (result == BTRFS_COMPARE_TREE_DELETED) {
 		sctx->cur_inode_gen = right_gen;
-		sctx->cur_inode_new = 0;
-		sctx->cur_inode_deleted = 1;
+		sctx->cur_inode_new = false;
+		sctx->cur_inode_deleted = true;
 		sctx->cur_inode_size = btrfs_inode_size(
 				sctx->right_path->nodes[0], right_ii);
 		sctx->cur_inode_mode = btrfs_inode_mode(
@@ -6633,8 +6633,8 @@ static int changed_inode(struct send_ctx *sctx,
 			 * First, process the inode as if it was deleted.
 			 */
 			sctx->cur_inode_gen = right_gen;
-			sctx->cur_inode_new = 0;
-			sctx->cur_inode_deleted = 1;
+			sctx->cur_inode_new = false;
+			sctx->cur_inode_deleted = true;
 			sctx->cur_inode_size = btrfs_inode_size(
 					sctx->right_path->nodes[0], right_ii);
 			sctx->cur_inode_mode = btrfs_inode_mode(
@@ -6648,8 +6648,8 @@ static int changed_inode(struct send_ctx *sctx,
 			 * Now process the inode as if it was new.
 			 */
 			sctx->cur_inode_gen = left_gen;
-			sctx->cur_inode_new = 1;
-			sctx->cur_inode_deleted = 0;
+			sctx->cur_inode_new = true;
+			sctx->cur_inode_deleted = false;
 			sctx->cur_inode_size = btrfs_inode_size(
 					sctx->left_path->nodes[0], left_ii);
 			sctx->cur_inode_mode = btrfs_inode_mode(
@@ -6681,9 +6681,9 @@ static int changed_inode(struct send_ctx *sctx,
 				goto out;
 		} else {
 			sctx->cur_inode_gen = left_gen;
-			sctx->cur_inode_new = 0;
-			sctx->cur_inode_new_gen = 0;
-			sctx->cur_inode_deleted = 0;
+			sctx->cur_inode_new = false;
+			sctx->cur_inode_new_gen = false;
+			sctx->cur_inode_deleted = false;
 			sctx->cur_inode_size = btrfs_inode_size(
 					sctx->left_path->nodes[0], left_ii);
 			sctx->cur_inode_mode = btrfs_inode_mode(
-- 
2.36.1


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

* Re: [PATCH 0/6] More send v2 updates: otime, fileattr
  2022-06-15 13:24 [PATCH 0/6] More send v2 updates: otime, fileattr David Sterba
                   ` (5 preceding siblings ...)
  2022-06-15 13:25 ` [PATCH 6/6] btrfs: send: use boolean types for current inode status David Sterba
@ 2022-06-23 14:29 ` David Sterba
  2022-07-22 16:43   ` Omar Sandoval
  6 siblings, 1 reply; 9+ messages in thread
From: David Sterba @ 2022-06-23 14:29 UTC (permalink / raw)
  To: David Sterba; +Cc: linux-btrfs

On Wed, Jun 15, 2022 at 03:24:55PM +0200, David Sterba wrote:
> New protocol enhancements:
> 
> - send otime with utimes command
> - rename SETFLAGS to FILEATTR and send the btrfs inode flags
> - other cleanups
> 
> David Sterba (6):
>   btrfs: send: add OTIME as utimes attribute for proto 2+ by default
>   btrfs: send: add new command FILEATTR for file attributes
>   btrfs: send: drop __KERNEL__ ifdef from send.h
>   btrfs: send: simplify includes
>   btrfs: send: remove old TODO regarding ERESTARTSYS
>   btrfs: send: use boolean types for current inode status

Moving from topic branch to misc-next. I got no feedback on the protocol
extensions, there's still time though.

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

* Re: [PATCH 0/6] More send v2 updates: otime, fileattr
  2022-06-23 14:29 ` [PATCH 0/6] More send v2 updates: otime, fileattr David Sterba
@ 2022-07-22 16:43   ` Omar Sandoval
  0 siblings, 0 replies; 9+ messages in thread
From: Omar Sandoval @ 2022-07-22 16:43 UTC (permalink / raw)
  To: David Sterba; +Cc: David Sterba, linux-btrfs

On Thu, Jun 23, 2022 at 04:29:05PM +0200, David Sterba wrote:
> On Wed, Jun 15, 2022 at 03:24:55PM +0200, David Sterba wrote:
> > New protocol enhancements:
> > 
> > - send otime with utimes command
> > - rename SETFLAGS to FILEATTR and send the btrfs inode flags
> > - other cleanups
> > 
> > David Sterba (6):
> >   btrfs: send: add OTIME as utimes attribute for proto 2+ by default
> >   btrfs: send: add new command FILEATTR for file attributes
> >   btrfs: send: drop __KERNEL__ ifdef from send.h
> >   btrfs: send: simplify includes
> >   btrfs: send: remove old TODO regarding ERESTARTSYS
> >   btrfs: send: use boolean types for current inode status
> 
> Moving from topic branch to misc-next. I got no feedback on the protocol
> extensions, there's still time though.

This looks good to me. I think it's reasonable to send the inode flags
exactly as is and implement applying them in receive later.

I don't know whether you want to go back and add it, but for the series
as it currently exists in misc-next:

Reviewed-by: Omar Sandoval <osandov@fb.com>

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

end of thread, other threads:[~2022-07-22 16:43 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-15 13:24 [PATCH 0/6] More send v2 updates: otime, fileattr David Sterba
2022-06-15 13:24 ` [PATCH 1/6] btrfs: send: add OTIME as utimes attribute for proto 2+ by default David Sterba
2022-06-15 13:25 ` [PATCH 2/6] btrfs: send: add new command FILEATTR for file attributes David Sterba
2022-06-15 13:25 ` [PATCH 3/6] btrfs: send: drop __KERNEL__ ifdef from send.h David Sterba
2022-06-15 13:25 ` [PATCH 4/6] btrfs: send: simplify includes David Sterba
2022-06-15 13:25 ` [PATCH 5/6] btrfs: send: remove old TODO regarding ERESTARTSYS David Sterba
2022-06-15 13:25 ` [PATCH 6/6] btrfs: send: use boolean types for current inode status David Sterba
2022-06-23 14:29 ` [PATCH 0/6] More send v2 updates: otime, fileattr David Sterba
2022-07-22 16:43   ` Omar Sandoval

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.