On Wed, Jun 26, 2019 at 04:34:01PM +0800, Anand Jain wrote: > Function call chain __btrfs_map_block()->find_live_mirror() uses > thread %pid to determine the %mirror_num for the read when mirror_num=0 > in the argument. > > This patch introduces a framework so that readmirror is a configurable > parameter, with default set to pid. > > Signed-off-by: Anand Jain <anand.j...@oracle.com> > --- > fs/btrfs/props.c | 41 +++++++++++++++++++++++++++++++++++++++++ > fs/btrfs/volumes.c | 9 ++++++++- > fs/btrfs/volumes.h | 6 ++++++ > 3 files changed, 55 insertions(+), 1 deletion(-) > > diff --git a/fs/btrfs/props.c b/fs/btrfs/props.c > index f9143f7c006d..0dc26a154a98 100644 > --- a/fs/btrfs/props.c > +++ b/fs/btrfs/props.c > @@ -10,6 +10,7 @@ > #include "ctree.h" > #include "xattr.h" > #include "compression.h" > +#include "volumes.h" > > #define BTRFS_PROP_HANDLERS_HT_BITS 8 > static DEFINE_HASHTABLE(prop_handlers_ht, BTRFS_PROP_HANDLERS_HT_BITS); > @@ -312,6 +313,39 @@ static const char *prop_compression_extract(struct inode > *inode) > return NULL; > } > > +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; > + > + if (!len) > + return 0; > + > + return -EINVAL; > +} > + > +static int prop_readmirror_apply(struct inode *inode, const char *value, > + size_t len) > +{ > + struct btrfs_fs_devices *fs_devices = btrfs_sb(inode->i_sb)->fs_devices; > + > + fs_devices->readmirror_policy = BTRFS_READMIRROR_DEFAULT; > + > + return 0; > +} > + > +static const char *prop_readmirror_extract(struct inode *inode) > +{ > + /* > + * readmirror policy is applied for the whole FS, inheritance is not > + * applicable. > + */
Extract is the 'get' implementation of the property, not inheritance, or I don't understand what does the comment refer to. > + return NULL; The return value should reflect the status of the property, ie. basically the same value that would set the current state. > +} > + > static struct prop_handler prop_handlers[] = { > { > .xattr_name = XATTR_BTRFS_PREFIX "compression", > @@ -320,6 +354,13 @@ static struct prop_handler prop_handlers[] = { > .extract = prop_compression_extract, > .inheritable = 1 > }, > + { > + .xattr_name = XATTR_BTRFS_PREFIX "readmirror", > + .validate = prop_readmirror_validate, > + .apply = prop_readmirror_apply, > + .extract = prop_readmirror_extract, > + .inheritable = 0 > + }, > }; > > static int inherit_props(struct btrfs_trans_handle *trans, > diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c > index a13ddba1ebc3..d72850ed4f88 100644 > --- a/fs/btrfs/volumes.c > +++ b/fs/btrfs/volumes.c > @@ -5490,7 +5490,14 @@ static int find_live_mirror(struct btrfs_fs_info > *fs_info, > else > num_stripes = map->num_stripes; > > - preferred_mirror = first + current->pid % num_stripes; > + switch(fs_info->fs_devices->readmirror_policy) { > + case BTRFS_READMIRROR_DEFAULT: > + /* fall through */ > + default: > + /* readmirror as per thread pid */ > + preferred_mirror = first + current->pid % num_stripes; > + break; > + } > > if (dev_replace_is_ongoing && > fs_info->dev_replace.cont_reading_from_srcdev_mode == > diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h > index 7f6aa1816409..e985d2133c0a 100644 > --- a/fs/btrfs/volumes.h > +++ b/fs/btrfs/volumes.h > @@ -219,6 +219,10 @@ BTRFS_DEVICE_GETSET_FUNCS(total_bytes); > BTRFS_DEVICE_GETSET_FUNCS(disk_total_bytes); > BTRFS_DEVICE_GETSET_FUNCS(bytes_used); > > +enum btrfs_readmirror_policy { > + BTRFS_READMIRROR_DEFAULT, > +}; > + > struct btrfs_fs_devices { > u8 fsid[BTRFS_FSID_SIZE]; /* FS specific uuid */ > u8 metadata_uuid[BTRFS_FSID_SIZE]; > @@ -269,6 +273,8 @@ struct btrfs_fs_devices { > struct kobject fsid_kobj; > struct kobject *device_dir_kobj; > struct completion kobj_unregister; > + > + int readmirror_policy; > }; > > #define BTRFS_BIO_INLINE_CSUM_SIZE 64 > -- > 2.20.1 (Apple Git-117)