aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/ioctl.c')
-rw-r--r--fs/btrfs/ioctl.c46
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. */
55static inline __u32 btrfs_mask_flags(umode_t mode, __u32 flags) 56static 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 }