Merge branch 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[firefly-linux-kernel-4.4.55.git] / fs / btrfs / super.c
index db7d7b803a611402883f653c80c5775ed4ed3ca1..9e66f5e724db1e307f19f74df7862550c170f069 100644 (file)
@@ -901,6 +901,15 @@ find_root:
        if (IS_ERR(new_root))
                return ERR_CAST(new_root);
 
+       if (!(sb->s_flags & MS_RDONLY)) {
+               int ret;
+               down_read(&fs_info->cleanup_work_sem);
+               ret = btrfs_orphan_cleanup(new_root);
+               up_read(&fs_info->cleanup_work_sem);
+               if (ret)
+                       return ERR_PTR(ret);
+       }
+
        dir_id = btrfs_root_dirid(&new_root->root_item);
 setup_root:
        location.objectid = dir_id;
@@ -916,7 +925,7 @@ setup_root:
         * a reference to the dentry.  We will have already gotten a reference
         * to the inode in btrfs_fill_super so we're good to go.
         */
-       if (!new && sb->s_root->d_inode == inode) {
+       if (!new && d_inode(sb->s_root) == inode) {
                iput(inode);
                return dget(sb->s_root);
        }
@@ -1221,7 +1230,7 @@ static struct dentry *mount_subvol(const char *subvol_name, int flags,
 
        root = mount_subtree(mnt, subvol_name);
 
-       if (!IS_ERR(root) && !is_subvolume_inode(root->d_inode)) {
+       if (!IS_ERR(root) && !is_subvolume_inode(d_inode(root))) {
                struct super_block *s = root->d_sb;
                dput(root);
                root = ERR_PTR(-EINVAL);
@@ -1886,8 +1895,8 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf)
        buf->f_fsid.val[0] = be32_to_cpu(fsid[0]) ^ be32_to_cpu(fsid[2]);
        buf->f_fsid.val[1] = be32_to_cpu(fsid[1]) ^ be32_to_cpu(fsid[3]);
        /* Mask in the root object ID too, to disambiguate subvols */
-       buf->f_fsid.val[0] ^= BTRFS_I(dentry->d_inode)->root->objectid >> 32;
-       buf->f_fsid.val[1] ^= BTRFS_I(dentry->d_inode)->root->objectid;
+       buf->f_fsid.val[0] ^= BTRFS_I(d_inode(dentry))->root->objectid >> 32;
+       buf->f_fsid.val[1] ^= BTRFS_I(d_inode(dentry))->root->objectid;
 
        return 0;
 }
@@ -1908,6 +1917,17 @@ static struct file_system_type btrfs_fs_type = {
 };
 MODULE_ALIAS_FS("btrfs");
 
+static int btrfs_control_open(struct inode *inode, struct file *file)
+{
+       /*
+        * The control file's private_data is used to hold the
+        * transaction when it is started and is used to keep
+        * track of whether a transaction is already in progress.
+        */
+       file->private_data = NULL;
+       return 0;
+}
+
 /*
  * used by btrfsctl to scan devices when no FS is mounted
  */
@@ -2009,6 +2029,7 @@ static const struct super_operations btrfs_super_ops = {
 };
 
 static const struct file_operations btrfs_ctl_fops = {
+       .open = btrfs_control_open,
        .unlocked_ioctl  = btrfs_control_ioctl,
        .compat_ioctl = btrfs_control_ioctl,
        .owner   = THIS_MODULE,