Btrfs: Check INCOMPAT flags on remount and add helper function
authorMitch Harder <mitch.harder@sabayonlinux.org>
Tue, 24 Jul 2012 17:58:43 +0000 (11:58 -0600)
committerChris Mason <chris.mason@fusionio.com>
Wed, 25 Jul 2012 20:14:31 +0000 (16:14 -0400)
In support of the recently added capability to remount with lzo
compression, provide a helper function to check the compression
INCOMPAT flags when remounting with lzo compression, and set
the flags if necessary.

Also, implement the new helper function when defragmenting with
explicit lzo compression and when setting the default subvolume.

Signed-off-by: Mitch Harder <mitch.harder@sabayonlinux.org>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
fs/btrfs/ctree.h
fs/btrfs/ioctl.c
fs/btrfs/super.c

index 00f9a50f986d95615e6affb651bf52510519396b..0f369da5cd97794139104bf80d6e87f62a2ee2e9 100644 (file)
@@ -3288,6 +3288,23 @@ void __btrfs_abort_transaction(struct btrfs_trans_handle *trans,
                               struct btrfs_root *root, const char *function,
                               unsigned int line, int errno);
 
+#define btrfs_set_fs_incompat(__fs_info, opt) \
+       __btrfs_set_fs_incompat((__fs_info), BTRFS_FEATURE_INCOMPAT_##opt)
+
+static inline void __btrfs_set_fs_incompat(struct btrfs_fs_info *fs_info,
+                                          u64 flag)
+{
+       struct btrfs_super_block *disk_super;
+       u64 features;
+
+       disk_super = fs_info->super_copy;
+       features = btrfs_super_incompat_flags(disk_super);
+       if (!(features & flag)) {
+               features |= flag;
+               btrfs_set_super_incompat_flags(disk_super, features);
+       }
+}
+
 #define btrfs_abort_transaction(trans, root, errno)            \
 do {                                                           \
        __btrfs_abort_transaction(trans, root, __func__,        \
index e54b663fd3aab34972ee5a4d3ee21a54617df289..3f3cbe928a1ab5e05bd8147d0833992994c493bd 100644 (file)
@@ -1053,11 +1053,9 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
                      u64 newer_than, unsigned long max_to_defrag)
 {
        struct btrfs_root *root = BTRFS_I(inode)->root;
-       struct btrfs_super_block *disk_super;
        struct file_ra_state *ra = NULL;
        unsigned long last_index;
        u64 isize = i_size_read(inode);
-       u64 features;
        u64 last_len = 0;
        u64 skip = 0;
        u64 defrag_end = 0;
@@ -1244,11 +1242,8 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
                mutex_unlock(&inode->i_mutex);
        }
 
-       disk_super = root->fs_info->super_copy;
-       features = btrfs_super_incompat_flags(disk_super);
        if (range->compress_type == BTRFS_COMPRESS_LZO) {
-               features |= BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO;
-               btrfs_set_super_incompat_flags(disk_super, features);
+               btrfs_set_fs_incompat(root->fs_info, COMPRESS_LZO);
        }
 
        ret = defrag_count;
@@ -2784,8 +2779,6 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp)
        struct btrfs_path *path;
        struct btrfs_key location;
        struct btrfs_disk_key disk_key;
-       struct btrfs_super_block *disk_super;
-       u64 features;
        u64 objectid = 0;
        u64 dir_id;
 
@@ -2836,12 +2829,7 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp)
        btrfs_mark_buffer_dirty(path->nodes[0]);
        btrfs_free_path(path);
 
-       disk_super = root->fs_info->super_copy;
-       features = btrfs_super_incompat_flags(disk_super);
-       if (!(features & BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL)) {
-               features |= BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL;
-               btrfs_set_super_incompat_flags(disk_super, features);
-       }
+       btrfs_set_fs_incompat(root->fs_info, DEFAULT_SUBVOL);
        btrfs_end_transaction(trans, root);
 
        return 0;
index 26da344231ac6b765e3f4a32cb2eaae680616300..75ee2c7791f0917ac605b8fc0004997c97b96ebb 100644 (file)
@@ -401,6 +401,7 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
                                compress_type = "lzo";
                                info->compress_type = BTRFS_COMPRESS_LZO;
                                btrfs_set_opt(info->mount_opt, COMPRESS);
+                               btrfs_set_fs_incompat(info, COMPRESS_LZO);
                        } else if (strncmp(args[0].from, "no", 2) == 0) {
                                compress_type = "no";
                                info->compress_type = BTRFS_COMPRESS_NONE;