* ones specified below then we will fail to mount
  */
 #define BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF   (1ULL << 0)
+#define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL  (2ULL << 0)
 
 #define BTRFS_FEATURE_COMPAT_SUPP              0ULL
 #define BTRFS_FEATURE_COMPAT_RO_SUPP           0ULL
 #define BTRFS_FEATURE_INCOMPAT_SUPP            \
-       BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF
+       (BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF | \
+        BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL)
 
 /*
  * A leaf is full of items. offset and size tell us where to find
 
        return ret;
 }
 
+static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp)
+{
+       struct inode *inode = fdentry(file)->d_inode;
+       struct btrfs_root *root = BTRFS_I(inode)->root;
+       struct btrfs_root *new_root;
+       struct btrfs_dir_item *di;
+       struct btrfs_trans_handle *trans;
+       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;
+
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+
+       if (copy_from_user(&objectid, argp, sizeof(objectid)))
+               return -EFAULT;
+
+       if (!objectid)
+               objectid = root->root_key.objectid;
+
+       location.objectid = objectid;
+       location.type = BTRFS_ROOT_ITEM_KEY;
+       location.offset = (u64)-1;
+
+       new_root = btrfs_read_fs_root_no_name(root->fs_info, &location);
+       if (IS_ERR(new_root))
+               return PTR_ERR(new_root);
+
+       if (btrfs_root_refs(&new_root->root_item) == 0)
+               return -ENOENT;
+
+       path = btrfs_alloc_path();
+       if (!path)
+               return -ENOMEM;
+       path->leave_spinning = 1;
+
+       trans = btrfs_start_transaction(root, 1);
+       if (!trans) {
+               btrfs_free_path(path);
+               return -ENOMEM;
+       }
+
+       dir_id = btrfs_super_root_dir(&root->fs_info->super_copy);
+       di = btrfs_lookup_dir_item(trans, root->fs_info->tree_root, path,
+                                  dir_id, "default", 7, 1);
+       if (!di) {
+               btrfs_free_path(path);
+               btrfs_end_transaction(trans, root);
+               printk(KERN_ERR "Umm, you don't have the default dir item, "
+                      "this isn't going to work\n");
+               return -ENOENT;
+       }
+
+       btrfs_cpu_key_to_disk(&disk_key, &new_root->root_key);
+       btrfs_set_dir_item_key(path->nodes[0], di, &disk_key);
+       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_end_transaction(trans, root);
+
+       return 0;
+}
+
 /*
  * there are many ways the trans_start and trans_end ioctls can lead
  * to deadlocks.  They should only be used by applications that
                return btrfs_ioctl_snap_create(file, argp, 1);
        case BTRFS_IOC_SNAP_DESTROY:
                return btrfs_ioctl_snap_destroy(file, argp);
+       case BTRFS_IOC_DEFAULT_SUBVOL:
+               return btrfs_ioctl_default_subvol(file, argp);
        case BTRFS_IOC_DEFRAG:
                return btrfs_ioctl_defrag(file);
        case BTRFS_IOC_RESIZE: