> On 23 Jul 2019, at 10:57 PM, David Sterba <dste...@suse.cz> wrote:
> 
> 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.


prop_handler::extract() is only used by inherit_props(). Readmirror property is 
for the volume/fsid so prop_handler::inheritable is set to 0. So 
inherit_props() doesn’t call extract() for readmirror.
The getxattr still work using the xattr interface and will have to mount the 
root which is I think is ok which is similar to the admin only operations, 
otherwise we have to introduce a new ioctl.

Thanks, Anand


>> +    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)

Reply via email to