]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blobdiff - fs/btrfs/ioctl.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[mirror_ubuntu-focal-kernel.git] / fs / btrfs / ioctl.c
index fa1b78cf25f68083de3db86ead690a41563316ce..d6715c2bcdc472d567bab9fd617e808fbcbd480f 100644 (file)
@@ -156,37 +156,6 @@ void btrfs_update_iflags(struct inode *inode)
                      new_fl);
 }
 
-/*
- * Inherit flags from the parent inode.
- *
- * Currently only the compression flags and the cow flags are inherited.
- */
-void btrfs_inherit_iflags(struct inode *inode, struct inode *dir)
-{
-       unsigned int flags;
-
-       if (!dir)
-               return;
-
-       flags = BTRFS_I(dir)->flags;
-
-       if (flags & BTRFS_INODE_NOCOMPRESS) {
-               BTRFS_I(inode)->flags &= ~BTRFS_INODE_COMPRESS;
-               BTRFS_I(inode)->flags |= BTRFS_INODE_NOCOMPRESS;
-       } else if (flags & BTRFS_INODE_COMPRESS) {
-               BTRFS_I(inode)->flags &= ~BTRFS_INODE_NOCOMPRESS;
-               BTRFS_I(inode)->flags |= BTRFS_INODE_COMPRESS;
-       }
-
-       if (flags & BTRFS_INODE_NODATACOW) {
-               BTRFS_I(inode)->flags |= BTRFS_INODE_NODATACOW;
-               if (S_ISREG(inode->i_mode))
-                       BTRFS_I(inode)->flags |= BTRFS_INODE_NODATASUM;
-       }
-
-       btrfs_update_iflags(inode);
-}
-
 static int btrfs_ioctl_getflags(struct file *file, void __user *arg)
 {
        struct btrfs_inode *ip = BTRFS_I(file_inode(file));
@@ -327,8 +296,10 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
 
                if (fs_info->compress_type == BTRFS_COMPRESS_LZO)
                        comp = "lzo";
-               else
+               else if (fs_info->compress_type == BTRFS_COMPRESS_ZLIB)
                        comp = "zlib";
+               else
+                       comp = "zstd";
                ret = btrfs_set_prop(inode, "btrfs.compression",
                                     comp, strlen(comp), 0);
                if (ret)
@@ -638,7 +609,7 @@ fail_free:
        return ret;
 }
 
-static void btrfs_wait_for_no_snapshoting_writes(struct btrfs_root *root)
+static void btrfs_wait_for_no_snapshotting_writes(struct btrfs_root *root)
 {
        s64 writers;
        DEFINE_WAIT(wait);
@@ -681,9 +652,9 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir,
                goto free_pending;
        }
 
-       atomic_inc(&root->will_be_snapshoted);
+       atomic_inc(&root->will_be_snapshotted);
        smp_mb__after_atomic();
-       btrfs_wait_for_no_snapshoting_writes(root);
+       btrfs_wait_for_no_snapshotting_writes(root);
 
        ret = btrfs_start_delalloc_inodes(root, 0);
        if (ret)
@@ -754,8 +725,8 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir,
 fail:
        btrfs_subvolume_release_metadata(fs_info, &pending_snapshot->block_rsv);
 dec_and_free:
-       if (atomic_dec_and_test(&root->will_be_snapshoted))
-               wake_up_atomic_t(&root->will_be_snapshoted);
+       if (atomic_dec_and_test(&root->will_be_snapshotted))
+               wake_up_atomic_t(&root->will_be_snapshotted);
 free_pending:
        kfree(pending_snapshot->root_item);
        btrfs_free_path(pending_snapshot->path);
@@ -1286,6 +1257,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
        unsigned long cluster = max_cluster;
        u64 new_align = ~((u64)SZ_128K - 1);
        struct page **pages = NULL;
+       bool do_compress = range->flags & BTRFS_DEFRAG_RANGE_COMPRESS;
 
        if (isize == 0)
                return 0;
@@ -1293,7 +1265,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
        if (range->start >= isize)
                return -EINVAL;
 
-       if (range->flags & BTRFS_DEFRAG_RANGE_COMPRESS) {
+       if (do_compress) {
                if (range->compress_type > BTRFS_COMPRESS_TYPES)
                        return -EINVAL;
                if (range->compress_type)
@@ -1304,20 +1276,19 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
                extent_thresh = SZ_256K;
 
        /*
-        * if we were not given a file, allocate a readahead
-        * context
+        * If we were not given a file, allocate a readahead context. As
+        * readahead is just an optimization, defrag will work without it so
+        * we don't error out.
         */
        if (!file) {
-               ra = kzalloc(sizeof(*ra), GFP_NOFS);
-               if (!ra)
-                       return -ENOMEM;
-               file_ra_state_init(ra, inode->i_mapping);
+               ra = kzalloc(sizeof(*ra), GFP_KERNEL);
+               if (ra)
+                       file_ra_state_init(ra, inode->i_mapping);
        } else {
                ra = &file->f_ra;
        }
 
-       pages = kmalloc_array(max_cluster, sizeof(struct page *),
-                       GFP_NOFS);
+       pages = kmalloc_array(max_cluster, sizeof(struct page *), GFP_KERNEL);
        if (!pages) {
                ret = -ENOMEM;
                goto out_ra;
@@ -1373,8 +1344,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
 
                if (!should_defrag_range(inode, (u64)i << PAGE_SHIFT,
                                         extent_thresh, &last_len, &skip,
-                                        &defrag_end, range->flags &
-                                        BTRFS_DEFRAG_RANGE_COMPRESS)) {
+                                        &defrag_end, do_compress)){
                        unsigned long next;
                        /*
                         * the should_defrag function tells us how much to skip
@@ -1395,14 +1365,15 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
 
                if (i + cluster > ra_index) {
                        ra_index = max(i, ra_index);
-                       btrfs_force_ra(inode->i_mapping, ra, file, ra_index,
-                                      cluster);
+                       if (ra)
+                               page_cache_sync_readahead(inode->i_mapping, ra,
+                                               file, ra_index, cluster);
                        ra_index += cluster;
                }
 
                inode_lock(inode);
-               if (range->flags & BTRFS_DEFRAG_RANGE_COMPRESS)
-                       BTRFS_I(inode)->force_compress = compress_type;
+               if (do_compress)
+                       BTRFS_I(inode)->defrag_compress = compress_type;
                ret = cluster_pages_for_defrag(inode, pages, i, cluster);
                if (ret < 0) {
                        inode_unlock(inode);
@@ -1449,7 +1420,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
                        filemap_flush(inode->i_mapping);
        }
 
-       if ((range->flags & BTRFS_DEFRAG_RANGE_COMPRESS)) {
+       if (do_compress) {
                /* the filemap_flush will queue IO into the worker threads, but
                 * we have to make sure the IO is actually started and that
                 * ordered extents get created before we return
@@ -1466,14 +1437,16 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
 
        if (range->compress_type == BTRFS_COMPRESS_LZO) {
                btrfs_set_fs_incompat(fs_info, COMPRESS_LZO);
+       } else if (range->compress_type == BTRFS_COMPRESS_ZSTD) {
+               btrfs_set_fs_incompat(fs_info, COMPRESS_ZSTD);
        }
 
        ret = defrag_count;
 
 out_ra:
-       if (range->flags & BTRFS_DEFRAG_RANGE_COMPRESS) {
+       if (do_compress) {
                inode_lock(inode);
-               BTRFS_I(inode)->force_compress = BTRFS_COMPRESS_NONE;
+               BTRFS_I(inode)->defrag_compress = BTRFS_COMPRESS_NONE;
                inode_unlock(inode);
        }
        if (!file)
@@ -1600,8 +1573,7 @@ static noinline int btrfs_ioctl_resize(struct file *file,
                goto out_free;
        }
 
-       new_size = div_u64(new_size, fs_info->sectorsize);
-       new_size *= fs_info->sectorsize;
+       new_size = round_down(new_size, fs_info->sectorsize);
 
        btrfs_info_in_rcu(fs_info, "new size for %s is %llu",
                          rcu_str_deref(device->name), new_size);
@@ -2201,9 +2173,6 @@ static noinline int btrfs_ioctl_tree_search_v2(struct file *file,
 
        buf_size = args.buf_size;
 
-       if (buf_size < sizeof(struct btrfs_ioctl_search_header))
-               return -EOVERFLOW;
-
        /* limit result size to 16MB */
        if (buf_size > buf_limit)
                buf_size = buf_limit;
@@ -3998,15 +3967,35 @@ static long btrfs_ioctl_trans_start(struct file *file)
        struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
        struct btrfs_root *root = BTRFS_I(inode)->root;
        struct btrfs_trans_handle *trans;
+       struct btrfs_file_private *private;
        int ret;
+       static bool warned = false;
 
        ret = -EPERM;
        if (!capable(CAP_SYS_ADMIN))
                goto out;
 
+       if (!warned) {
+               btrfs_warn(fs_info,
+                       "Userspace transaction mechanism is considered "
+                       "deprecated and slated to be removed in 4.17. "
+                       "If you have a valid use case please "
+                       "speak up on the mailing list");
+               WARN_ON(1);
+               warned = true;
+       }
+
        ret = -EINPROGRESS;
-       if (file->private_data)
+       private = file->private_data;
+       if (private && private->trans)
                goto out;
+       if (!private) {
+               private = kzalloc(sizeof(struct btrfs_file_private),
+                                 GFP_KERNEL);
+               if (!private)
+                       return -ENOMEM;
+               file->private_data = private;
+       }
 
        ret = -EROFS;
        if (btrfs_root_readonly(root))
@@ -4023,7 +4012,7 @@ static long btrfs_ioctl_trans_start(struct file *file)
        if (IS_ERR(trans))
                goto out_drop;
 
-       file->private_data = trans;
+       private->trans = trans;
        return 0;
 
 out_drop:
@@ -4278,14 +4267,13 @@ long btrfs_ioctl_trans_end(struct file *file)
 {
        struct inode *inode = file_inode(file);
        struct btrfs_root *root = BTRFS_I(inode)->root;
-       struct btrfs_trans_handle *trans;
+       struct btrfs_file_private *private = file->private_data;
 
-       trans = file->private_data;
-       if (!trans)
+       if (!private || !private->trans)
                return -EINVAL;
-       file->private_data = NULL;
 
-       btrfs_end_transaction(trans);
+       btrfs_end_transaction(private->trans);
+       private->trans = NULL;
 
        atomic_dec(&root->fs_info->open_ioctl_trans);
 
@@ -4438,7 +4426,7 @@ static long btrfs_ioctl_dev_replace(struct btrfs_fs_info *fs_info,
 
        switch (p->cmd) {
        case BTRFS_IOCTL_DEV_REPLACE_CMD_START:
-               if (fs_info->sb->s_flags & MS_RDONLY) {
+               if (sb_rdonly(fs_info->sb)) {
                        ret = -EROFS;
                        goto out;
                }