*/
        u64 last_trans_log_full_commit;
        unsigned long mount_opt;
+       /*
+        * Track requests for actions that need to be done during transaction
+        * commit (like for some mount options).
+        */
+       unsigned long pending_changes;
        unsigned long compress_type:4;
        int commit_interval;
        /*
 #define btrfs_raw_test_opt(o, opt)     ((o) & BTRFS_MOUNT_##opt)
 #define btrfs_test_opt(root, opt)      ((root)->fs_info->mount_opt & \
                                         BTRFS_MOUNT_##opt)
+
 #define btrfs_set_and_info(root, opt, fmt, args...)                    \
 {                                                                      \
        if (!btrfs_test_opt(root, opt))                                 \
        btrfs_clear_opt(root->fs_info->mount_opt, opt);                 \
 }
 
+/*
+ * Requests for changes that need to be done during transaction commit.
+ *
+ * Internal mount options that are used for special handling of the real
+ * mount options (eg. cannot be set during remount and have to be set during
+ * transaction commit)
+ */
+
+#define btrfs_test_pending(info, opt)  \
+       test_bit(BTRFS_PENDING_##opt, &(info)->pending_changes)
+#define btrfs_set_pending(info, opt)   \
+       set_bit(BTRFS_PENDING_##opt, &(info)->pending_changes)
+#define btrfs_clear_pending(info, opt) \
+       clear_bit(BTRFS_PENDING_##opt, &(info)->pending_changes)
+
+/*
+ * Helpers for setting pending mount option changes.
+ *
+ * Expects corresponding macros
+ * BTRFS_PENDING_SET_ and CLEAR_ + short mount option name
+ */
+#define btrfs_set_pending_and_info(info, opt, fmt, args...)            \
+do {                                                                   \
+       if (!btrfs_raw_test_opt((info)->mount_opt, opt)) {              \
+               btrfs_info((info), fmt, ##args);                        \
+               btrfs_set_pending((info), SET_##opt);                   \
+               btrfs_clear_pending((info), CLEAR_##opt);               \
+       }                                                               \
+} while(0)
+
+#define btrfs_clear_pending_and_info(info, opt, fmt, args...)          \
+do {                                                                   \
+       if (btrfs_raw_test_opt((info)->mount_opt, opt)) {               \
+               btrfs_info((info), fmt, ##args);                        \
+               btrfs_set_pending((info), CLEAR_##opt);                 \
+               btrfs_clear_pending((info), SET_##opt);                 \
+       }                                                               \
+} while(0)
+
 /*
  * Inode flags
  */
 
        if (btrfs_test_opt(tree_root, CHANGE_INODE_CACHE))
                btrfs_set_opt(tree_root->fs_info->mount_opt, INODE_MAP_CACHE);
 
+       /*
+        * Mount does not set all options immediatelly, we can do it now and do
+        * not have to wait for transaction commit
+        */
+       btrfs_apply_pending_changes(fs_info);
+
 #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY
        if (btrfs_test_opt(tree_root, CHECK_INTEGRITY)) {
                ret = btrfsic_mount(tree_root, fs_devices,
 
        else
                btrfs_clear_opt(root->fs_info->mount_opt, INODE_MAP_CACHE);
 
+       btrfs_apply_pending_changes(root->fs_info);
+
        /* commit_fs_roots gets rid of all the tree log roots, it is now
         * safe to free the root of tree log roots
         */
 
        return (ret < 0) ? 0 : 1;
 }
+
+void btrfs_apply_pending_changes(struct btrfs_fs_info *fs_info)
+{
+       unsigned long prev;
+       unsigned long bit;
+
+       prev = cmpxchg(&fs_info->pending_changes, 0, 0);
+       if (!prev)
+               return;
+
+       if (prev)
+               btrfs_warn(fs_info,
+                       "unknown pending changes left 0x%lx, ignoring", prev);
+}