Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1a0a397e authored by J. Bruce Fields's avatar J. Bruce Fields Committed by Al Viro
Browse files

dcache: d_obtain_alias callers don't all want DISCONNECTED



There are a few d_obtain_alias callers that are using it to get the
root of a filesystem which may already have an alias somewhere else.

This is not the same as the filehandle-lookup case, and none of them
actually need DCACHE_DISCONNECTED set.

It isn't really a serious problem, but it would really be clearer if we
reserved DCACHE_DISCONNECTED for those cases where it's actually needed.

In the btrfs case this was causing a spurious printk from
nfsd/nfsfh.c:fh_verify when it found an unexpected DCACHE_DISCONNECTED
dentry.  Josef worked around this by unsetting DCACHE_DISCONNECTED
manually in 3a0dfa6a "Btrfs: unset DCACHE_DISCONNECTED when mounting
default subvol", and this replaces that workaround.

Cc: Josef Bacik <jbacik@fb.com>
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent da093a9b
Loading
Loading
Loading
Loading
+1 −8
Original line number Diff line number Diff line
@@ -851,7 +851,6 @@ static struct dentry *get_default_root(struct super_block *sb,
	struct btrfs_path *path;
	struct btrfs_key location;
	struct inode *inode;
	struct dentry *dentry;
	u64 dir_id;
	int new = 0;

@@ -922,13 +921,7 @@ static struct dentry *get_default_root(struct super_block *sb,
		return dget(sb->s_root);
	}

	dentry = d_obtain_alias(inode);
	if (!IS_ERR(dentry)) {
		spin_lock(&dentry->d_lock);
		dentry->d_flags &= ~DCACHE_DISCONNECTED;
		spin_unlock(&dentry->d_lock);
	}
	return dentry;
	return d_obtain_root(inode);
}

static int btrfs_fill_super(struct super_block *sb,
+1 −1
Original line number Diff line number Diff line
@@ -755,7 +755,7 @@ static struct dentry *open_root_dentry(struct ceph_fs_client *fsc,
				goto out;
			}
		} else {
			root = d_obtain_alias(inode);
			root = d_obtain_root(inode);
		}
		ceph_init_dentry(root);
		dout("open_root_inode success, root dentry is %p\n", root);
+49 −20
Original line number Diff line number Diff line
@@ -1781,25 +1781,7 @@ struct dentry *d_find_any_alias(struct inode *inode)
}
EXPORT_SYMBOL(d_find_any_alias);

/**
 * d_obtain_alias - find or allocate a dentry for a given inode
 * @inode: inode to allocate the dentry for
 *
 * Obtain a dentry for an inode resulting from NFS filehandle conversion or
 * similar open by handle operations.  The returned dentry may be anonymous,
 * or may have a full name (if the inode was already in the cache).
 *
 * When called on a directory inode, we must ensure that the inode only ever
 * has one dentry.  If a dentry is found, that is returned instead of
 * allocating a new one.
 *
 * On successful return, the reference to the inode has been transferred
 * to the dentry.  In case of an error the reference on the inode is released.
 * To make it easier to use in export operations a %NULL or IS_ERR inode may
 * be passed in and will be the error will be propagate to the return value,
 * with a %NULL @inode replaced by ERR_PTR(-ESTALE).
 */
struct dentry *d_obtain_alias(struct inode *inode)
struct dentry *__d_obtain_alias(struct inode *inode, int disconnected)
{
	static const struct qstr anonstring = QSTR_INIT("/", 1);
	struct dentry *tmp;
@@ -1830,7 +1812,10 @@ struct dentry *d_obtain_alias(struct inode *inode)
	}

	/* attach a disconnected dentry */
	add_flags = d_flags_for_inode(inode) | DCACHE_DISCONNECTED;
	add_flags = d_flags_for_inode(inode);

	if (disconnected)
		add_flags |= DCACHE_DISCONNECTED;

	spin_lock(&tmp->d_lock);
	tmp->d_inode = inode;
@@ -1851,8 +1836,52 @@ struct dentry *d_obtain_alias(struct inode *inode)
	iput(inode);
	return res;
}

/**
 * d_obtain_alias - find or allocate a DISCONNECTED dentry for a given inode
 * @inode: inode to allocate the dentry for
 *
 * Obtain a dentry for an inode resulting from NFS filehandle conversion or
 * similar open by handle operations.  The returned dentry may be anonymous,
 * or may have a full name (if the inode was already in the cache).
 *
 * When called on a directory inode, we must ensure that the inode only ever
 * has one dentry.  If a dentry is found, that is returned instead of
 * allocating a new one.
 *
 * On successful return, the reference to the inode has been transferred
 * to the dentry.  In case of an error the reference on the inode is released.
 * To make it easier to use in export operations a %NULL or IS_ERR inode may
 * be passed in and the error will be propagated to the return value,
 * with a %NULL @inode replaced by ERR_PTR(-ESTALE).
 */
struct dentry *d_obtain_alias(struct inode *inode)
{
	return __d_obtain_alias(inode, 1);
}
EXPORT_SYMBOL(d_obtain_alias);

/**
 * d_obtain_root - find or allocate a dentry for a given inode
 * @inode: inode to allocate the dentry for
 *
 * Obtain an IS_ROOT dentry for the root of a filesystem.
 *
 * We must ensure that directory inodes only ever have one dentry.  If a
 * dentry is found, that is returned instead of allocating a new one.
 *
 * On successful return, the reference to the inode has been transferred
 * to the dentry.  In case of an error the reference on the inode is
 * released.  A %NULL or IS_ERR inode may be passed in and will be the
 * error will be propagate to the return value, with a %NULL @inode
 * replaced by ERR_PTR(-ESTALE).
 */
struct dentry *d_obtain_root(struct inode *inode)
{
	return __d_obtain_alias(inode, 0);
}
EXPORT_SYMBOL(d_obtain_root);

/**
 * d_add_ci - lookup or allocate new dentry with case-exact name
 * @inode:  the inode case-insensitive lookup has found
+1 −1
Original line number Diff line number Diff line
@@ -112,7 +112,7 @@ struct dentry *nfs_get_root(struct super_block *sb, struct nfs_fh *mntfh,
	 * if the dentry tree reaches them; however if the dentry already
	 * exists, we'll pick it up at this point and use it as the root
	 */
	ret = d_obtain_alias(inode);
	ret = d_obtain_root(inode);
	if (IS_ERR(ret)) {
		dprintk("nfs_get_root: get root dentry failed\n");
		goto out;
+1 −1
Original line number Diff line number Diff line
@@ -942,7 +942,7 @@ static int nilfs_get_root_dentry(struct super_block *sb,
			iput(inode);
		}
	} else {
		dentry = d_obtain_alias(inode);
		dentry = d_obtain_root(inode);
		if (IS_ERR(dentry)) {
			ret = PTR_ERR(dentry);
			goto failed_dentry;
Loading