Message ID | 20190626083723.2094-2-anand.jain@oracle.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [1/2,RESEND,Rebased] btrfs-progs: add helper to create xattr name | expand |
On Wed, Jun 26, 2019 at 04:37:23PM +0800, Anand Jain wrote: > This sets the readmirror=<parm> as a btrfs.<attr> extentded attribute. > > Signed-off-by: Anand Jain <anand.jain@oracle.com> > --- > props.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 49 insertions(+) > > diff --git a/props.c b/props.c > index 3a498bd9e904..1d1a2c7f9d14 100644 > --- a/props.c > +++ b/props.c > @@ -178,6 +178,53 @@ out: > return ret; > } > > +static int prop_readmirror(enum prop_object_type type, const char *object, > + const char *name, const char *value) > +{ > + int fd; > + int ret; > + char buf[256] = {0}; > + char *xattr_name; > + DIR *dirstream = NULL; > + > + fd = open_file_or_dir3(object, &dirstream, value ? O_RDWR : O_RDONLY); > + if (fd < 0) { > + ret = -errno; > + error("failed to open %s: %m", object); > + return ret; > + } > + > + xattr_name = alloc_xattr_name(name); > + if (IS_ERR(xattr_name)) { > + error("failed to alloc xattr_name %s: %m", object); > + return PTR_ERR(xattr_name); > + } > + > + ret = 0; > + if (value) { > + if (fsetxattr(fd, xattr_name, value, strlen(value), 0) < 0) { > + ret = -errno; > + error("failed to set readmirror for %s: %m", object); > + } > + } else { > + if (fgetxattr(fd, xattr_name, buf, 256) < 0) { > + if (errno != ENOATTR) { > + ret = -errno; > + error("failed to get readmirror for %s: %m", > + object); > + } > + } else { > + fprintf(stdout, "readmirror=%.*s\n", (int) strlen(buf), > + buf); > + } > + } > + > + free(xattr_name); > + close_file_or_dir(fd, dirstream); > + > + return ret; > +} > + > const struct prop_handler prop_handlers[] = { > {"ro", "Set/get read-only flag of subvolume.", 0, prop_object_subvol, > prop_read_only}, > @@ -185,5 +232,7 @@ const struct prop_handler prop_handlers[] = { > prop_object_dev | prop_object_root, prop_label}, > {"compression", "Set/get compression for a file or directory", 0, > prop_object_inode, prop_compression}, > + {"readmirror", "set/get readmirror policy for filesystem", 0, > + prop_object_root, prop_readmirror}, For some unknown reason the object type for filesystem-wide props is called prop_object_root, which is correct, but it got me confused first. So the most reliable way to set it is $ btrfs prop set -t filesystem /path readmirror <VALUE> and $ btrfs prop set /path readmirror <VALUE> will auto-detect the object type by /path, but I'm not sure what exactly does it do in case it's a mount point but not the toplevel subvolume.
On Wed, Jun 26, 2019 at 04:37:23PM +0800, Anand Jain wrote: > prop_object_inode, prop_compression}, > + {"readmirror", "set/get readmirror policy for filesystem", 0, The help text for the property is useless.
On 23/7/19 9:53 PM, David Sterba wrote: > On Wed, Jun 26, 2019 at 04:37:23PM +0800, Anand Jain wrote: >> This sets the readmirror=<parm> as a btrfs.<attr> extentded attribute. >> >> Signed-off-by: Anand Jain <anand.jain@oracle.com> >> --- >> props.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ >> 1 file changed, 49 insertions(+) >> >> diff --git a/props.c b/props.c >> index 3a498bd9e904..1d1a2c7f9d14 100644 >> --- a/props.c >> +++ b/props.c >> @@ -178,6 +178,53 @@ out: >> return ret; >> } >> >> +static int prop_readmirror(enum prop_object_type type, const char *object, >> + const char *name, const char *value) >> +{ >> + int fd; >> + int ret; >> + char buf[256] = {0}; >> + char *xattr_name; >> + DIR *dirstream = NULL; >> + >> + fd = open_file_or_dir3(object, &dirstream, value ? O_RDWR : O_RDONLY); >> + if (fd < 0) { >> + ret = -errno; >> + error("failed to open %s: %m", object); >> + return ret; >> + } >> + >> + xattr_name = alloc_xattr_name(name); >> + if (IS_ERR(xattr_name)) { >> + error("failed to alloc xattr_name %s: %m", object); >> + return PTR_ERR(xattr_name); >> + } >> + >> + ret = 0; >> + if (value) { >> + if (fsetxattr(fd, xattr_name, value, strlen(value), 0) < 0) { >> + ret = -errno; >> + error("failed to set readmirror for %s: %m", object); >> + } >> + } else { >> + if (fgetxattr(fd, xattr_name, buf, 256) < 0) { >> + if (errno != ENOATTR) { >> + ret = -errno; >> + error("failed to get readmirror for %s: %m", >> + object); >> + } >> + } else { >> + fprintf(stdout, "readmirror=%.*s\n", (int) strlen(buf), >> + buf); >> + } >> + } >> + >> + free(xattr_name); >> + close_file_or_dir(fd, dirstream); >> + >> + return ret; >> +} >> + >> const struct prop_handler prop_handlers[] = { >> {"ro", "Set/get read-only flag of subvolume.", 0, prop_object_subvol, >> prop_read_only}, >> @@ -185,5 +232,7 @@ const struct prop_handler prop_handlers[] = { >> prop_object_dev | prop_object_root, prop_label}, >> {"compression", "Set/get compression for a file or directory", 0, >> prop_object_inode, prop_compression}, >> + {"readmirror", "set/get readmirror policy for filesystem", 0, >> + prop_object_root, prop_readmirror}, > > For some unknown reason the object type for filesystem-wide props is > called prop_object_root, which is correct, but it got me confused first. > > So the most reliable way to set it is > > $ btrfs prop set -t filesystem /path readmirror <VALUE> > > and > > $ btrfs prop set /path readmirror <VALUE> > > will auto-detect the object type by /path, but I'm not sure what exactly > does it do in case it's a mount point but not the toplevel subvolume. > If its not toplevel subvolume it fails in kernel with -EINVAL. ---- +static int prop_readmirror_validate(struct inode *inode, const char *value, + size_t len) +{ + struct btrfs_root *root = BTRFS_I(inode)->root; + + if (root->root_key.objectid != BTRFS_FS_TREE_OBJECTID) + return -EINVAL; -----
diff --git a/props.c b/props.c index 3a498bd9e904..1d1a2c7f9d14 100644 --- a/props.c +++ b/props.c @@ -178,6 +178,53 @@ out: return ret; } +static int prop_readmirror(enum prop_object_type type, const char *object, + const char *name, const char *value) +{ + int fd; + int ret; + char buf[256] = {0}; + char *xattr_name; + DIR *dirstream = NULL; + + fd = open_file_or_dir3(object, &dirstream, value ? O_RDWR : O_RDONLY); + if (fd < 0) { + ret = -errno; + error("failed to open %s: %m", object); + return ret; + } + + xattr_name = alloc_xattr_name(name); + if (IS_ERR(xattr_name)) { + error("failed to alloc xattr_name %s: %m", object); + return PTR_ERR(xattr_name); + } + + ret = 0; + if (value) { + if (fsetxattr(fd, xattr_name, value, strlen(value), 0) < 0) { + ret = -errno; + error("failed to set readmirror for %s: %m", object); + } + } else { + if (fgetxattr(fd, xattr_name, buf, 256) < 0) { + if (errno != ENOATTR) { + ret = -errno; + error("failed to get readmirror for %s: %m", + object); + } + } else { + fprintf(stdout, "readmirror=%.*s\n", (int) strlen(buf), + buf); + } + } + + free(xattr_name); + close_file_or_dir(fd, dirstream); + + return ret; +} + const struct prop_handler prop_handlers[] = { {"ro", "Set/get read-only flag of subvolume.", 0, prop_object_subvol, prop_read_only}, @@ -185,5 +232,7 @@ const struct prop_handler prop_handlers[] = { prop_object_dev | prop_object_root, prop_label}, {"compression", "Set/get compression for a file or directory", 0, prop_object_inode, prop_compression}, + {"readmirror", "set/get readmirror policy for filesystem", 0, + prop_object_root, prop_readmirror}, {NULL, NULL, 0, 0, NULL} };
This sets the readmirror=<parm> as a btrfs.<attr> extentded attribute. Signed-off-by: Anand Jain <anand.jain@oracle.com> --- props.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+)