diff options
Diffstat (limited to 'fs/btrfs/ioctl.c')
-rw-r--r-- | fs/btrfs/ioctl.c | 46 |
1 files changed, 26 insertions, 20 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index d11fc6548e1..ed8c055ab70 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -50,6 +50,7 @@ | |||
50 | #include "print-tree.h" | 50 | #include "print-tree.h" |
51 | #include "volumes.h" | 51 | #include "volumes.h" |
52 | #include "locking.h" | 52 | #include "locking.h" |
53 | #include "inode-map.h" | ||
53 | 54 | ||
54 | /* Mask out flags that are inappropriate for the given type of inode. */ | 55 | /* Mask out flags that are inappropriate for the given type of inode. */ |
55 | static inline __u32 btrfs_mask_flags(umode_t mode, __u32 flags) | 56 | static inline __u32 btrfs_mask_flags(umode_t mode, __u32 flags) |
@@ -81,6 +82,13 @@ static unsigned int btrfs_flags_to_ioctl(unsigned int flags) | |||
81 | iflags |= FS_NOATIME_FL; | 82 | iflags |= FS_NOATIME_FL; |
82 | if (flags & BTRFS_INODE_DIRSYNC) | 83 | if (flags & BTRFS_INODE_DIRSYNC) |
83 | iflags |= FS_DIRSYNC_FL; | 84 | iflags |= FS_DIRSYNC_FL; |
85 | if (flags & BTRFS_INODE_NODATACOW) | ||
86 | iflags |= FS_NOCOW_FL; | ||
87 | |||
88 | if ((flags & BTRFS_INODE_COMPRESS) && !(flags & BTRFS_INODE_NOCOMPRESS)) | ||
89 | iflags |= FS_COMPR_FL; | ||
90 | else if (flags & BTRFS_INODE_NOCOMPRESS) | ||
91 | iflags |= FS_NOCOMP_FL; | ||
84 | 92 | ||
85 | return iflags; | 93 | return iflags; |
86 | } | 94 | } |
@@ -144,16 +152,13 @@ static int check_flags(unsigned int flags) | |||
144 | if (flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | \ | 152 | if (flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | \ |
145 | FS_NOATIME_FL | FS_NODUMP_FL | \ | 153 | FS_NOATIME_FL | FS_NODUMP_FL | \ |
146 | FS_SYNC_FL | FS_DIRSYNC_FL | \ | 154 | FS_SYNC_FL | FS_DIRSYNC_FL | \ |
147 | FS_NOCOMP_FL | FS_COMPR_FL | \ | 155 | FS_NOCOMP_FL | FS_COMPR_FL | |
148 | FS_NOCOW_FL | FS_COW_FL)) | 156 | FS_NOCOW_FL)) |
149 | return -EOPNOTSUPP; | 157 | return -EOPNOTSUPP; |
150 | 158 | ||
151 | if ((flags & FS_NOCOMP_FL) && (flags & FS_COMPR_FL)) | 159 | if ((flags & FS_NOCOMP_FL) && (flags & FS_COMPR_FL)) |
152 | return -EINVAL; | 160 | return -EINVAL; |
153 | 161 | ||
154 | if ((flags & FS_NOCOW_FL) && (flags & FS_COW_FL)) | ||
155 | return -EINVAL; | ||
156 | |||
157 | return 0; | 162 | return 0; |
158 | } | 163 | } |
159 | 164 | ||
@@ -218,6 +223,10 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg) | |||
218 | ip->flags |= BTRFS_INODE_DIRSYNC; | 223 | ip->flags |= BTRFS_INODE_DIRSYNC; |
219 | else | 224 | else |
220 | ip->flags &= ~BTRFS_INODE_DIRSYNC; | 225 | ip->flags &= ~BTRFS_INODE_DIRSYNC; |
226 | if (flags & FS_NOCOW_FL) | ||
227 | ip->flags |= BTRFS_INODE_NODATACOW; | ||
228 | else | ||
229 | ip->flags &= ~BTRFS_INODE_NODATACOW; | ||
221 | 230 | ||
222 | /* | 231 | /* |
223 | * The COMPRESS flag can only be changed by users, while the NOCOMPRESS | 232 | * The COMPRESS flag can only be changed by users, while the NOCOMPRESS |
@@ -230,11 +239,9 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg) | |||
230 | } else if (flags & FS_COMPR_FL) { | 239 | } else if (flags & FS_COMPR_FL) { |
231 | ip->flags |= BTRFS_INODE_COMPRESS; | 240 | ip->flags |= BTRFS_INODE_COMPRESS; |
232 | ip->flags &= ~BTRFS_INODE_NOCOMPRESS; | 241 | ip->flags &= ~BTRFS_INODE_NOCOMPRESS; |
242 | } else { | ||
243 | ip->flags &= ~(BTRFS_INODE_COMPRESS | BTRFS_INODE_NOCOMPRESS); | ||
233 | } | 244 | } |
234 | if (flags & FS_NOCOW_FL) | ||
235 | ip->flags |= BTRFS_INODE_NODATACOW; | ||
236 | else if (flags & FS_COW_FL) | ||
237 | ip->flags &= ~BTRFS_INODE_NODATACOW; | ||
238 | 245 | ||
239 | trans = btrfs_join_transaction(root, 1); | 246 | trans = btrfs_join_transaction(root, 1); |
240 | BUG_ON(IS_ERR(trans)); | 247 | BUG_ON(IS_ERR(trans)); |
@@ -323,8 +330,7 @@ static noinline int create_subvol(struct btrfs_root *root, | |||
323 | u64 new_dirid = BTRFS_FIRST_FREE_OBJECTID; | 330 | u64 new_dirid = BTRFS_FIRST_FREE_OBJECTID; |
324 | u64 index = 0; | 331 | u64 index = 0; |
325 | 332 | ||
326 | ret = btrfs_find_free_objectid(NULL, root->fs_info->tree_root, | 333 | ret = btrfs_find_free_objectid(root->fs_info->tree_root, &objectid); |
327 | 0, &objectid); | ||
328 | if (ret) { | 334 | if (ret) { |
329 | dput(parent); | 335 | dput(parent); |
330 | return ret; | 336 | return ret; |
@@ -416,7 +422,7 @@ static noinline int create_subvol(struct btrfs_root *root, | |||
416 | BUG_ON(ret); | 422 | BUG_ON(ret); |
417 | 423 | ||
418 | ret = btrfs_insert_dir_item(trans, root, | 424 | ret = btrfs_insert_dir_item(trans, root, |
419 | name, namelen, dir->i_ino, &key, | 425 | name, namelen, dir, &key, |
420 | BTRFS_FT_DIR, index); | 426 | BTRFS_FT_DIR, index); |
421 | if (ret) | 427 | if (ret) |
422 | goto fail; | 428 | goto fail; |
@@ -427,7 +433,7 @@ static noinline int create_subvol(struct btrfs_root *root, | |||
427 | 433 | ||
428 | ret = btrfs_add_root_ref(trans, root->fs_info->tree_root, | 434 | ret = btrfs_add_root_ref(trans, root->fs_info->tree_root, |
429 | objectid, root->root_key.objectid, | 435 | objectid, root->root_key.objectid, |
430 | dir->i_ino, index, name, namelen); | 436 | btrfs_ino(dir), index, name, namelen); |
431 | 437 | ||
432 | BUG_ON(ret); | 438 | BUG_ON(ret); |
433 | 439 | ||
@@ -1123,7 +1129,7 @@ static noinline int btrfs_ioctl_subvol_getflags(struct file *file, | |||
1123 | int ret = 0; | 1129 | int ret = 0; |
1124 | u64 flags = 0; | 1130 | u64 flags = 0; |
1125 | 1131 | ||
1126 | if (inode->i_ino != BTRFS_FIRST_FREE_OBJECTID) | 1132 | if (btrfs_ino(inode) != BTRFS_FIRST_FREE_OBJECTID) |
1127 | return -EINVAL; | 1133 | return -EINVAL; |
1128 | 1134 | ||
1129 | down_read(&root->fs_info->subvol_sem); | 1135 | down_read(&root->fs_info->subvol_sem); |
@@ -1150,7 +1156,7 @@ static noinline int btrfs_ioctl_subvol_setflags(struct file *file, | |||
1150 | if (root->fs_info->sb->s_flags & MS_RDONLY) | 1156 | if (root->fs_info->sb->s_flags & MS_RDONLY) |
1151 | return -EROFS; | 1157 | return -EROFS; |
1152 | 1158 | ||
1153 | if (inode->i_ino != BTRFS_FIRST_FREE_OBJECTID) | 1159 | if (btrfs_ino(inode) != BTRFS_FIRST_FREE_OBJECTID) |
1154 | return -EINVAL; | 1160 | return -EINVAL; |
1155 | 1161 | ||
1156 | if (copy_from_user(&flags, arg, sizeof(flags))) | 1162 | if (copy_from_user(&flags, arg, sizeof(flags))) |
@@ -1633,7 +1639,7 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file, | |||
1633 | goto out_dput; | 1639 | goto out_dput; |
1634 | } | 1640 | } |
1635 | 1641 | ||
1636 | if (inode->i_ino != BTRFS_FIRST_FREE_OBJECTID) { | 1642 | if (btrfs_ino(inode) != BTRFS_FIRST_FREE_OBJECTID) { |
1637 | err = -EINVAL; | 1643 | err = -EINVAL; |
1638 | goto out_dput; | 1644 | goto out_dput; |
1639 | } | 1645 | } |
@@ -1919,7 +1925,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
1919 | } | 1925 | } |
1920 | 1926 | ||
1921 | /* clone data */ | 1927 | /* clone data */ |
1922 | key.objectid = src->i_ino; | 1928 | key.objectid = btrfs_ino(src); |
1923 | key.type = BTRFS_EXTENT_DATA_KEY; | 1929 | key.type = BTRFS_EXTENT_DATA_KEY; |
1924 | key.offset = 0; | 1930 | key.offset = 0; |
1925 | 1931 | ||
@@ -1946,7 +1952,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
1946 | 1952 | ||
1947 | btrfs_item_key_to_cpu(leaf, &key, slot); | 1953 | btrfs_item_key_to_cpu(leaf, &key, slot); |
1948 | if (btrfs_key_type(&key) > BTRFS_EXTENT_DATA_KEY || | 1954 | if (btrfs_key_type(&key) > BTRFS_EXTENT_DATA_KEY || |
1949 | key.objectid != src->i_ino) | 1955 | key.objectid != btrfs_ino(src)) |
1950 | break; | 1956 | break; |
1951 | 1957 | ||
1952 | if (btrfs_key_type(&key) == BTRFS_EXTENT_DATA_KEY) { | 1958 | if (btrfs_key_type(&key) == BTRFS_EXTENT_DATA_KEY) { |
@@ -1989,7 +1995,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
1989 | goto next; | 1995 | goto next; |
1990 | 1996 | ||
1991 | memcpy(&new_key, &key, sizeof(new_key)); | 1997 | memcpy(&new_key, &key, sizeof(new_key)); |
1992 | new_key.objectid = inode->i_ino; | 1998 | new_key.objectid = btrfs_ino(inode); |
1993 | if (off <= key.offset) | 1999 | if (off <= key.offset) |
1994 | new_key.offset = key.offset + destoff - off; | 2000 | new_key.offset = key.offset + destoff - off; |
1995 | else | 2001 | else |
@@ -2043,7 +2049,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
2043 | ret = btrfs_inc_extent_ref(trans, root, | 2049 | ret = btrfs_inc_extent_ref(trans, root, |
2044 | disko, diskl, 0, | 2050 | disko, diskl, 0, |
2045 | root->root_key.objectid, | 2051 | root->root_key.objectid, |
2046 | inode->i_ino, | 2052 | btrfs_ino(inode), |
2047 | new_key.offset - datao); | 2053 | new_key.offset - datao); |
2048 | BUG_ON(ret); | 2054 | BUG_ON(ret); |
2049 | } | 2055 | } |