Message ID | 1586173871-5559-4-git-send-email-anand.jain@oracle.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | readmirror feature (sysfs and in-memory only approach; with new read_policy device) | expand |
On 06/04/2020 13:51, Anand Jain wrote: > +static ssize_t btrfs_read_policy_store(struct kobject *kobj, > + struct kobj_attribute *a, > + const char *buf, size_t len) > +{ > + int i; > + struct btrfs_fs_devices *fs_devices = to_fs_devs(kobj); > + > + for (i = 0; i < BTRFS_NR_READ_POLICY; i++) { > + if (btrfs_strmatch(buf, btrfs_read_policy_name[i]) == 0) { > + if (i != fs_devices->read_policy) { > + fs_devices->read_policy = i; > + btrfs_info(fs_devices->fs_info, > + "read policy set to '%s'", > + btrfs_read_policy_name[i]); > + } > + return len; > + } > + } Naive question, what's the advantage over sysfs_match_string()?
On 19/5/20 6:07 pm, Johannes Thumshirn wrote: > On 06/04/2020 13:51, Anand Jain wrote: >> +static ssize_t btrfs_read_policy_store(struct kobject *kobj, >> + struct kobj_attribute *a, >> + const char *buf, size_t len) >> +{ >> + int i; >> + struct btrfs_fs_devices *fs_devices = to_fs_devs(kobj); >> + >> + for (i = 0; i < BTRFS_NR_READ_POLICY; i++) { >> + if (btrfs_strmatch(buf, btrfs_read_policy_name[i]) == 0) { >> + if (i != fs_devices->read_policy) { >> + fs_devices->read_policy = i; >> + btrfs_info(fs_devices->fs_info, >> + "read policy set to '%s'", >> + btrfs_read_policy_name[i]); >> + } >> + return len; >> + } >> + } > > Naive question, what's the advantage over sysfs_match_string()? We strip both leading and trailing whitespaces, its not possible to do the same with sysfs_match_string(). For example: echo ==== These should pass ====== run_nocheck "echo ' pid' > $sysfs_path/read_policy" run_nocheck "echo ' pid ' > $sysfs_path/read_policy" run_nocheck "echo -n ' pid ' > $sysfs_path/read_policy" run_nocheck "echo -n ' pid' > $sysfs_path/read_policy" run_nocheck "echo 'pid ' > $sysfs_path/read_policy" run_nocheck "echo -n 'pid ' > $sysfs_path/read_policy" run_nocheck "echo -n pid > $sysfs_path/read_policy" run_nocheck "echo pid > $sysfs_path/read_policy" Thanks, Anand
On 20/05/2020 10:54, Anand Jain wrote: > On 19/5/20 6:07 pm, Johannes Thumshirn wrote: >> On 06/04/2020 13:51, Anand Jain wrote: >>> +static ssize_t btrfs_read_policy_store(struct kobject *kobj, >>> + struct kobj_attribute *a, >>> + const char *buf, size_t len) >>> +{ >>> + int i; >>> + struct btrfs_fs_devices *fs_devices = to_fs_devs(kobj); >>> + >>> + for (i = 0; i < BTRFS_NR_READ_POLICY; i++) { >>> + if (btrfs_strmatch(buf, btrfs_read_policy_name[i]) == 0) { >>> + if (i != fs_devices->read_policy) { >>> + fs_devices->read_policy = i; >>> + btrfs_info(fs_devices->fs_info, >>> + "read policy set to '%s'", >>> + btrfs_read_policy_name[i]); >>> + } >>> + return len; >>> + } >>> + } >> >> Naive question, what's the advantage over sysfs_match_string()? > > We strip both leading and trailing whitespaces, its not > possible to do the same with sysfs_match_string(). > > For example: > echo ==== These should pass ====== > run_nocheck "echo ' pid' > $sysfs_path/read_policy" > run_nocheck "echo ' pid ' > $sysfs_path/read_policy" > run_nocheck "echo -n ' pid ' > $sysfs_path/read_policy" > run_nocheck "echo -n ' pid' > $sysfs_path/read_policy" > run_nocheck "echo 'pid ' > $sysfs_path/read_policy" > run_nocheck "echo -n 'pid ' > $sysfs_path/read_policy" > run_nocheck "echo -n pid > $sysfs_path/read_policy" > run_nocheck "echo pid > $sysfs_path/read_policy" Ah ok
diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c index 7bb68cef98ab..c9a8850b186a 100644 --- a/fs/btrfs/sysfs.c +++ b/fs/btrfs/sysfs.c @@ -832,6 +832,54 @@ static int btrfs_strmatch(const char *given, const char *golden) return -EINVAL; } +static const char* const btrfs_read_policy_name[] = { "pid" }; + +static ssize_t btrfs_read_policy_show(struct kobject *kobj, + struct kobj_attribute *a, char *buf) +{ + int i; + ssize_t ret = 0; + struct btrfs_fs_devices *fs_devices = to_fs_devs(kobj); + + for (i = 0; i < BTRFS_NR_READ_POLICY; i++) { + if (fs_devices->read_policy == i) + ret += snprintf(buf + ret, PAGE_SIZE - ret, "%s[%s]", + (ret == 0 ? "" : " "), + btrfs_read_policy_name[i]); + else + ret += snprintf(buf + ret, PAGE_SIZE - ret, "%s%s", + (ret == 0 ? "" : " "), + btrfs_read_policy_name[i]); + } + + ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n"); + + return ret; +} + +static ssize_t btrfs_read_policy_store(struct kobject *kobj, + struct kobj_attribute *a, + const char *buf, size_t len) +{ + int i; + struct btrfs_fs_devices *fs_devices = to_fs_devs(kobj); + + for (i = 0; i < BTRFS_NR_READ_POLICY; i++) { + if (btrfs_strmatch(buf, btrfs_read_policy_name[i]) == 0) { + if (i != fs_devices->read_policy) { + fs_devices->read_policy = i; + btrfs_info(fs_devices->fs_info, + "read policy set to '%s'", + btrfs_read_policy_name[i]); + } + return len; + } + } + + return -EINVAL; +} +BTRFS_ATTR_RW(, read_policy, btrfs_read_policy_show, btrfs_read_policy_store); + static const struct attribute *btrfs_attrs[] = { BTRFS_ATTR_PTR(, label), BTRFS_ATTR_PTR(, nodesize), @@ -840,6 +888,7 @@ static const struct attribute *btrfs_attrs[] = { BTRFS_ATTR_PTR(, quota_override), BTRFS_ATTR_PTR(, metadata_uuid), BTRFS_ATTR_PTR(, checksum), + BTRFS_ATTR_PTR(, read_policy), NULL, };