swap_activate will check for a compressed or copy-on-write file; we shouldn't
allow it to become either once it has already been activated.

Signed-off-by: Omar Sandoval <osan...@osandov.com>
---
 fs/btrfs/ioctl.c | 50 +++++++++++++++++++++++++++++++-------------------
 1 file changed, 31 insertions(+), 19 deletions(-)

diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 4399f0c..f022dce 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -293,14 +293,21 @@ static int btrfs_ioctl_setflags(struct file *file, void 
__user *arg)
                }
        } else {
                /*
-                * Revert back under same assuptions as above
+                * swap_activate checks that we don't swapon a copy-on-write
+                * file, but we must also make sure that it doesn't become
+                * copy-on-write.
                 */
-               if (S_ISREG(mode)) {
-                       if (inode->i_size == 0)
-                               ip->flags &= ~(BTRFS_INODE_NODATACOW
-                                            | BTRFS_INODE_NODATASUM);
-               } else {
-                       ip->flags &= ~BTRFS_INODE_NODATACOW;
+               if (!IS_SWAPFILE(inode)) {
+                       /*
+                        * Revert back under same assumptions as above
+                        */
+                       if (S_ISREG(mode)) {
+                               if (inode->i_size == 0)
+                                       ip->flags &= ~(BTRFS_INODE_NODATACOW |
+                                                      BTRFS_INODE_NODATASUM);
+                       } else {
+                               ip->flags &= ~BTRFS_INODE_NODATACOW;
+                       }
                }
        }
 
@@ -317,20 +324,25 @@ static int btrfs_ioctl_setflags(struct file *file, void 
__user *arg)
                if (ret && ret != -ENODATA)
                        goto out_drop;
        } else if (flags & FS_COMPR_FL) {
-               const char *comp;
-
-               ip->flags |= BTRFS_INODE_COMPRESS;
-               ip->flags &= ~BTRFS_INODE_NOCOMPRESS;
+               /*
+                * Like nodatacow, swap_activate checks that we don't swapon a
+                * compressed file, so we shouldn't let it become compressed.
+                */
+               if (!IS_SWAPFILE(inode)) {
+                       const char *comp;
 
-               if (root->fs_info->compress_type == BTRFS_COMPRESS_LZO)
-                       comp = "lzo";
-               else
-                       comp = "zlib";
-               ret = btrfs_set_prop(inode, "btrfs.compression",
-                                    comp, strlen(comp), 0);
-               if (ret)
-                       goto out_drop;
+                       ip->flags |= BTRFS_INODE_COMPRESS;
+                       ip->flags &= ~BTRFS_INODE_NOCOMPRESS;
 
+                       if (root->fs_info->compress_type == BTRFS_COMPRESS_LZO)
+                               comp = "lzo";
+                       else
+                               comp = "zlib";
+                       ret = btrfs_set_prop(inode, "btrfs.compression",
+                                            comp, strlen(comp), 0);
+                       if (ret)
+                               goto out_drop;
+               }
        } else {
                ret = btrfs_set_prop(inode, "btrfs.compression", NULL, 0, 0);
                if (ret && ret != -ENODATA)
-- 
2.1.3

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