Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 231744
b: refs/heads/master
c: 0caa102
h: refs/heads/master
v: v3
  • Loading branch information
Li Zefan committed Dec 23, 2010
1 parent 8d7b63e commit 6e61f27
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b83cc9693f39689490970c19f6c5b866f6719a70
refs/heads/master: 0caa102da82799efaba88e234484786a9591c797
83 changes: 83 additions & 0 deletions trunk/fs/btrfs/ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1009,6 +1009,85 @@ static noinline int btrfs_ioctl_snap_create_v2(struct file *file,
return ret;
}

static noinline int btrfs_ioctl_subvol_getflags(struct file *file,
void __user *arg)
{
struct inode *inode = fdentry(file)->d_inode;
struct btrfs_root *root = BTRFS_I(inode)->root;
int ret = 0;
u64 flags = 0;

if (inode->i_ino != BTRFS_FIRST_FREE_OBJECTID)
return -EINVAL;

down_read(&root->fs_info->subvol_sem);
if (btrfs_root_readonly(root))
flags |= BTRFS_SUBVOL_RDONLY;
up_read(&root->fs_info->subvol_sem);

if (copy_to_user(arg, &flags, sizeof(flags)))
ret = -EFAULT;

return ret;
}

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;
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;

if (copy_from_user(&flags, arg, sizeof(flags)))
return -EFAULT;

if (flags & ~BTRFS_SUBVOL_CREATE_ASYNC)
return -EINVAL;

if (flags & ~BTRFS_SUBVOL_RDONLY)
return -EOPNOTSUPP;

down_write(&root->fs_info->subvol_sem);

/* nothing to do */
if (!!(flags & BTRFS_SUBVOL_RDONLY) == btrfs_root_readonly(root))
goto out;

root_flags = btrfs_root_flags(&root->root_item);
if (flags & BTRFS_SUBVOL_RDONLY)
btrfs_set_root_flags(&root->root_item,
root_flags | BTRFS_ROOT_SUBVOL_RDONLY);
else
btrfs_set_root_flags(&root->root_item,
root_flags & ~BTRFS_ROOT_SUBVOL_RDONLY);

trans = btrfs_start_transaction(root, 1);
if (IS_ERR(trans)) {
ret = PTR_ERR(trans);
goto out_reset;
}

ret = btrfs_update_root(trans, root,
&root->root_key, &root->root_item);

btrfs_commit_transaction(trans, root);
out_reset:
if (ret)
btrfs_set_root_flags(&root->root_item, root_flags);
out:
up_write(&root->fs_info->subvol_sem);
return ret;
}

/*
* helper to check if the subvolume references other subvolumes
*/
Expand Down Expand Up @@ -2282,6 +2361,10 @@ long btrfs_ioctl(struct file *file, unsigned int
return btrfs_ioctl_snap_create(file, argp, 1);
case BTRFS_IOC_SNAP_DESTROY:
return btrfs_ioctl_snap_destroy(file, argp);
case BTRFS_IOC_SUBVOL_GETFLAGS:
return btrfs_ioctl_subvol_getflags(file, argp);
case BTRFS_IOC_SUBVOL_SETFLAGS:
return btrfs_ioctl_subvol_setflags(file, argp);
case BTRFS_IOC_DEFAULT_SUBVOL:
return btrfs_ioctl_default_subvol(file, argp);
case BTRFS_IOC_DEFRAG:
Expand Down
2 changes: 2 additions & 0 deletions trunk/fs/btrfs/ioctl.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,4 +194,6 @@ struct btrfs_ioctl_space_args {
#define BTRFS_IOC_WAIT_SYNC _IOW(BTRFS_IOCTL_MAGIC, 22, __u64)
#define BTRFS_IOC_SNAP_CREATE_V2 _IOW(BTRFS_IOCTL_MAGIC, 23, \
struct btrfs_ioctl_vol_args_v2)
#define BTRFS_IOC_SUBVOL_GETFLAGS _IOW(BTRFS_IOCTL_MAGIC, 25, __u64)
#define BTRFS_IOC_SUBVOL_SETFLAGS _IOW(BTRFS_IOCTL_MAGIC, 26, __u64)
#endif

0 comments on commit 6e61f27

Please sign in to comment.