Goffredo Baroncelli wrote:
> Hi Li,
> 
> On Thursday, 09 December, 2010, Li Zefan wrote:
>> This allows us to set a snapshot or a subvolume readonly or writable
>> on the fly.
>>
>> Usage:
>>
>> Set BTRFS_SUBVOL_RDONLY of btrfs_ioctl_vol_arg_v2->flags, and then
>> call ioctl(BTRFS_IOCTL_SUBVOL_SETFLAGS);
>>
>> Changelog for v2:
>> - Add _GETFLAGS ioctl.
>> - Check if the passed fd is the root of a subvolume.
>> - Change the name from _SNAP_SETFLAGS to _SUBVOL_SETFLAGS.
>>
>> Signed-off-by: Li Zefan <l...@cn.fujitsu.com>
>> ---
>>  fs/btrfs/ioctl.c |   92 
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>  fs/btrfs/ioctl.h |    4 ++
>>  2 files changed, 96 insertions(+), 0 deletions(-)
>>
>> diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
>> index db2b231..29304c7 100644
>> --- a/fs/btrfs/ioctl.c
>> +++ b/fs/btrfs/ioctl.c
>> @@ -1010,6 +1010,94 @@ out:
> [...]
>> +    struct btrfs_ioctl_vol_args_v2 *vol_args;
>> +    int ret = 0;
>> +    u64 flags = 0;
>> +
>> +    if (inode->i_ino != BTRFS_FIRST_FREE_OBJECTID)
>> +            return -EINVAL;
>> +
>> +    vol_args = memdup_user(arg, sizeof(*vol_args));
> 
> Would be better to avoid a dynamic allocation for a so small struct ? 
> And as more general comment: what is the reason to pass a so complex struct 
> only for setting/getting the flags ?
> Would be it better to pass directly a u64 variable.
> 

I was considering using the same structure for all subvolume ioctls,
but here seems it's overkill..

> [..]
>> +
>> +static noinline int btrfs_ioctl_subvol_setflags(struct file *file,
>> +                                          void __user *arg)
>> +{
>> +    struct inode *inode = fdentry(file)->d_inode;
>> +    struct btrfs_root *root = BTRFS_I(inode)->root;
>> +    struct btrfs_trans_handle *trans;
>> +    struct btrfs_ioctl_vol_args_v2 *vol_args;
>> +    u64 root_flags;
>> +    u64 flags;
>> +    int ret = 0;
>> +
>> +    if (root->fs_info->sb->s_flags & MS_RDONLY)
>> +            return -EROFS;
>> +
>> +    if (inode->i_ino != BTRFS_FIRST_FREE_OBJECTID)
>> +            return -EINVAL;
>> +
>> +    vol_args = memdup_user(arg, sizeof(*vol_args));
> 
> Same as before.
> 
>> +    if (IS_ERR(vol_args))
>> +            return PTR_ERR(vol_args);
>> +    flags = vol_args->flags;
>> +
>> +    if (flags & ~BTRFS_SUBVOL_RDONLY) {
>> +            ret = -EINVAL;
>> +            goto out;
>> +    }
>> +
>> +    down_write(&root->fs_info->subvol_sem);
>> +
>> +    /* nothing to do */
>> +    if (!!(flags & BTRFS_SUBVOL_RDONLY) == root->readonly)
>> +            goto out_unlock;
> 
> This is only an aesthetic comment: I prefer a simpler style like
> 
>       if ((flags & BTRFS_SUBVOL_RDONLY) && root->readonly)
>               goto out_unlock;
> 

They are not equivalent. The former checks if the flags and the
root both have readonly bit set or cleared.

> But I know that every body has its style :-)
> 
>> +
>> +    root_flags = btrfs_root_flags(&root->root_item);
>> +    if (flags & BTRFS_SUBVOL_RDONLY)
>> +            btrfs_set_root_flags(&root->root_item,
>> +                                 root_flags | BTRFS_ROOT_SNAP_RDONLY);
>> +    else
>> +            btrfs_set_root_flags(&root->root_item,
>> +                                 root_flags & ~BTRFS_ROOT_SNAP_RDONLY);
>> +    root->readonly = !root->readonly;
> 
> I double checked this line. But if I read the code correctly I think that the 
> line above is wrong: the field "root->readonly" is flipped regardless the 
> value of the flags passed by the user.
> 

Yep, that's because if we don't need to flip it, we've already exited early.

Note, there's only one flag.

> Moreover I have another question: why internally the flags is 
> BTRFS_ROOT_SNAP_RDONLY, instead in user space the flag is BTRFS_SUBVOL_RDONLY 
> ? 
> 

That's my carelessness..

> I suggest to 
> - rename BTRFS_SUBVOL_RDONLY in BTRFS_SUBVOL_CREATE_SNAP_RDONLY (like 
> BTRFS_SUBVOL_CREATE_SNAP_ASYNC)
> - rename BTRFS_ROOT_SNAP_RDONLY in BTRFS_ROOT_FLAGS_RDONLY and use both in 
> userspace and in kernel space this flag. I suggested to remove SNAP because 
> the flag make sense also for a "standard" subvolume.
> 

I'd prefer not to mix flags for root_item flags and vol ioctl flags.

And CREATE_RDONLY and CREATE_ASYNC can also be valid for subvolumes too.
Support for async subvolume creation is already there, just lack of an
user interface. So I've changed _CREATE_SNAP_ASYNC to _CREATE_ASYNC
in the patch I sent just now.
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to