From: David Howells <dhowells@redhat.com>
To: viro@ZenIV.linux.org.uk
Cc: dhowells@redhat.com, linux-fsdevel@vger.kernel.org,
linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org,
linux-kernel@vger.kernel.org, samba-technical@lists.samba.org,
linux-ext4@vger.kernel.org
Subject: [PATCH 14/18] xstat: NFS: Use d_automount() rather than abusing follow_link() [ver #6]
Date: Thu, 15 Jul 2010 03:17:26 +0100 [thread overview]
Message-ID: <20100715021726.5544.59242.stgit@warthog.procyon.org.uk> (raw)
In-Reply-To: <20100715021709.5544.64506.stgit@warthog.procyon.org.uk>
Make NFS use the new d_automount() dentry operation rather than abusing
follow_link() on directories.
Signed-off-by: David Howells <dhowells@redhat.com>
---
fs/nfs/dir.c | 2 +
fs/nfs/inode.c | 1 +
fs/nfs/internal.h | 1 +
fs/nfs/namespace.c | 87 ++++++++++++++++++++++++----------------------------
4 files changed, 44 insertions(+), 47 deletions(-)
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 782b431..d7e5810 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -927,6 +927,7 @@ const struct dentry_operations nfs_dentry_operations = {
.d_revalidate = nfs_lookup_revalidate,
.d_delete = nfs_dentry_delete,
.d_iput = nfs_dentry_iput,
+ .d_automount = nfs_d_automount,
};
static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
@@ -1002,6 +1003,7 @@ const struct dentry_operations nfs4_dentry_operations = {
.d_revalidate = nfs_open_revalidate,
.d_delete = nfs_dentry_delete,
.d_iput = nfs_dentry_iput,
+ .d_automount = nfs_d_automount,
};
/*
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 8c6de96..f9737bd 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -296,6 +296,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
inode->i_op = &nfs_mountpoint_inode_operations;
inode->i_fop = NULL;
set_bit(NFS_INO_MOUNTPOINT, &nfsi->flags);
+ inode->i_flags |= S_AUTOMOUNT;
}
} else if (S_ISLNK(inode->i_mode))
inode->i_op = &nfs_symlink_inode_operations;
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index d8bd619..48de6f8 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -238,6 +238,7 @@ extern char *nfs_path(const char *base,
const struct dentry *droot,
const struct dentry *dentry,
char *buffer, ssize_t buflen);
+extern struct vfsmount *nfs_d_automount(struct path *path);
/* getroot.c */
extern struct dentry *nfs_get_root(struct super_block *, struct nfs_fh *);
diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
index db6aa36..bf80079 100644
--- a/fs/nfs/namespace.c
+++ b/fs/nfs/namespace.c
@@ -88,9 +88,8 @@ Elong:
}
/*
- * nfs_follow_mountpoint - handle crossing a mountpoint on the server
- * @dentry - dentry of mountpoint
- * @nd - nameidata info
+ * nfs_d_automount - Handle crossing a mountpoint on the server
+ * @path - The mountpoint
*
* When we encounter a mountpoint on the server, we want to set up
* a mountpoint on the client too, to prevent inode numbers from
@@ -100,87 +99,81 @@ Elong:
* situation, and that different filesystems may want to use
* different security flavours.
*/
-static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
+struct vfsmount *nfs_d_automount(struct path *path)
{
struct vfsmount *mnt;
- struct nfs_server *server = NFS_SERVER(dentry->d_inode);
+ struct nfs_server *server = NFS_SERVER(path->dentry->d_inode);
struct dentry *parent;
struct nfs_fh *fh = NULL;
struct nfs_fattr *fattr = NULL;
int err;
- dprintk("--> nfs_follow_mountpoint()\n");
+ dprintk("--> nfs_d_automount()\n");
- err = -ESTALE;
- if (IS_ROOT(dentry))
- goto out_err;
+ mnt = ERR_PTR(-ESTALE);
+ if (IS_ROOT(path->dentry))
+ goto out_nofree;
- err = -ENOMEM;
+ mnt = ERR_PTR(-ENOMEM);
fh = nfs_alloc_fhandle();
fattr = nfs_alloc_fattr();
if (fh == NULL || fattr == NULL)
- goto out_err;
+ goto out;
dprintk("%s: enter\n", __func__);
- dput(nd->path.dentry);
- nd->path.dentry = dget(dentry);
- /* Look it up again */
- parent = dget_parent(nd->path.dentry);
+ /* Look it up again to get its attributes */
+ parent = dget_parent(path->dentry);
err = server->nfs_client->rpc_ops->lookup(parent->d_inode,
- &nd->path.dentry->d_name,
+ &path->dentry->d_name,
fh, fattr);
dput(parent);
- if (err != 0)
- goto out_err;
+ if (err != 0) {
+ mnt = ERR_PTR(err);
+ goto out;
+ }
if (fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL)
- mnt = nfs_do_refmount(nd->path.mnt, nd->path.dentry);
+ mnt = nfs_do_refmount(path->mnt, path->dentry);
else
- mnt = nfs_do_submount(nd->path.mnt, nd->path.dentry, fh,
- fattr);
- err = PTR_ERR(mnt);
+ mnt = nfs_do_submount(path->mnt, path->dentry, fh, fattr);
if (IS_ERR(mnt))
- goto out_err;
+ goto out;
mntget(mnt);
- err = do_add_mount(mnt, &nd->path, nd->path.mnt->mnt_flags|MNT_SHRINKABLE,
+ err = do_add_mount(mnt, path, path->mnt->mnt_flags | MNT_SHRINKABLE,
&nfs_automount_list);
- if (err < 0) {
+ switch (err) {
+ case 0:
+ dprintk("%s: done, success\n", __func__);
+ schedule_delayed_work(&nfs_automount_task, nfs_mountpoint_expiry_timeout);
+ break;
+ case -EBUSY:
+ /* someone else made a mount here whilst we were busy */
mntput(mnt);
- if (err == -EBUSY)
- goto out_follow;
- goto out_err;
+ dprintk("%s: done, collision\n", __func__);
+ mnt = NULL;
+ break;
+ default:
+ mntput(mnt);
+ dprintk("%s: done, error %d\n", __func__, err);
+ mnt = ERR_PTR(err);
+ break;
}
- path_put(&nd->path);
- nd->path.mnt = mnt;
- nd->path.dentry = dget(mnt->mnt_root);
- schedule_delayed_work(&nfs_automount_task, nfs_mountpoint_expiry_timeout);
+
out:
nfs_free_fattr(fattr);
nfs_free_fhandle(fh);
- dprintk("%s: done, returned %d\n", __func__, err);
-
- dprintk("<-- nfs_follow_mountpoint() = %d\n", err);
- return ERR_PTR(err);
-out_err:
- path_put(&nd->path);
- goto out;
-out_follow:
- while (d_mountpoint(nd->path.dentry) &&
- follow_down(&nd->path))
- ;
- err = 0;
- goto out;
+out_nofree:
+ dprintk("<-- nfs_follow_mountpoint() = %p\n", mnt);
+ return mnt;
}
const struct inode_operations nfs_mountpoint_inode_operations = {
- .follow_link = nfs_follow_mountpoint,
.getattr = nfs_getattr,
};
const struct inode_operations nfs_referral_inode_operations = {
- .follow_link = nfs_follow_mountpoint,
};
static void nfs_expire_automounts(struct work_struct *work)
next prev parent reply other threads:[~2010-07-15 2:19 UTC|newest]
Thread overview: 132+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-07-15 2:17 [PATCH 00/18] Extended file stat functions " David Howells
2010-07-15 2:17 ` [PATCH 01/18] Mark arguments to certain syscalls as being const " David Howells
2010-07-15 2:17 ` [PATCH 02/18] xstat: Add a pair of system calls to make extended file stats available " David Howells
2010-07-15 20:35 ` Arnd Bergmann
2010-07-15 21:53 ` David Howells
2010-07-16 6:22 ` Mark Harris
2010-07-16 10:24 ` David Howells
2010-07-16 11:02 ` Arnd Bergmann
2010-07-16 12:38 ` David Howells
2010-07-16 13:32 ` Arnd Bergmann
2010-07-17 5:51 ` Mark Harris
2010-07-17 9:00 ` Arnd Bergmann
2010-07-17 9:49 ` David Howells
2010-07-16 10:46 ` Arnd Bergmann
2010-07-16 15:10 ` David Howells
2010-07-18 8:48 ` Christoph Hellwig
2010-07-22 10:52 ` Jan Engelhardt
2010-07-22 12:25 ` David Howells
2010-07-19 14:05 ` David Howells
2010-07-19 15:17 ` Linus Torvalds
2010-07-19 16:15 ` David Howells
2010-07-19 16:51 ` Linus Torvalds
2010-07-19 17:26 ` David Howells
2010-07-19 17:46 ` Linus Torvalds
2010-07-20 8:28 ` Andreas Dilger
2010-07-22 10:35 ` Jan Engelhardt
2010-07-22 12:14 ` David Howells
2010-07-22 12:17 ` Volker Lendecke
2010-07-22 13:05 ` Jan Engelhardt
2010-07-22 15:14 ` Linus Torvalds
2010-07-22 15:36 ` Volker Lendecke
2010-07-22 15:47 ` Linus Torvalds
2010-07-22 16:06 ` Greg Freemyer
2010-07-22 16:07 ` Greg Freemyer
2010-07-22 16:25 ` Jan Engelhardt
2010-07-22 16:27 ` Jeremy Allison
2010-07-22 16:40 ` Linus Torvalds
2010-07-22 16:58 ` Trond Myklebust
2010-07-22 18:02 ` Jeremy Allison
2010-07-22 18:04 ` Volker Lendecke
2010-07-22 18:07 ` Jeremy Allison
2010-07-22 18:59 ` Trond Myklebust
2010-07-30 17:55 ` Phil Pishioneri
2010-07-30 18:11 ` Trond Myklebust
2010-07-30 18:19 ` Phil Pishioneri
2010-07-31 18:41 ` Andreas Dilger
2010-07-31 18:48 ` Jan Engelhardt
2010-07-31 19:03 ` Trond Myklebust
2010-07-31 21:20 ` Jan Engelhardt
2010-08-01 13:17 ` Jeff Layton
2010-07-22 18:05 ` Jan Engelhardt
2010-07-22 18:07 ` Jeremy Allison
2010-07-22 19:18 ` John Stoffel
2010-07-22 17:03 ` Jan Engelhardt
2010-07-22 17:16 ` Trond Myklebust
2010-07-22 17:36 ` Jan Engelhardt
2010-07-22 17:24 ` Linus Torvalds
2010-07-22 18:15 ` Jeremy Allison
2010-07-22 18:21 ` Benny Halevy
2010-07-22 18:45 ` Greg Freemyer
2010-07-22 19:53 ` Benny Halevy
2010-07-22 18:41 ` Greg Freemyer
2010-07-28 1:15 ` Neil Brown
2010-07-28 17:28 ` David Howells
2010-07-28 23:04 ` Neil Brown
2010-07-30 18:38 ` J. Bruce Fields
2010-08-01 13:40 ` Jeff Layton
2010-08-02 14:09 ` Greg Freemyer
2010-08-02 14:42 ` Jeff Layton
2010-07-29 16:15 ` David Howells
2010-08-03 1:13 ` Neil Brown
2010-07-22 17:12 ` Jim Rees
2010-07-22 17:32 ` Linus Torvalds
2010-07-23 1:03 ` tridge
2010-07-23 1:21 ` Ted Ts'o
2010-07-23 2:12 ` tridge
2010-07-23 9:14 ` Björn Jacke
2010-07-30 21:22 ` utz lehmann
2010-07-31 8:08 ` Jan Engelhardt
2010-07-31 14:43 ` utz lehmann
2010-08-01 13:25 ` Jeff Layton
2010-08-05 23:52 ` Jeremy Allison
2010-08-06 3:38 ` Neil Brown
2010-08-06 3:55 ` Steve French
2010-08-06 11:18 ` Jeff Layton
2010-08-06 23:30 ` Neil Brown
2010-08-06 23:58 ` Steve French
2010-08-07 0:29 ` Neil Brown
2010-08-07 2:42 ` Steve French
2010-08-07 2:54 ` Steve French
2010-08-07 3:32 ` Neil Brown
2010-08-07 10:34 ` Jeff Layton
2010-08-07 11:04 ` Neil Brown
2010-08-08 12:12 ` Jeremy Allison
2010-08-08 12:53 ` Jeff Layton
2010-08-08 13:05 ` Jeremy Allison
2010-08-13 12:54 ` J. Bruce Fields
2010-08-13 17:54 ` Jeremy Allison
2010-08-13 18:09 ` Steve French
2010-08-13 19:06 ` Jan Engelhardt
2010-08-13 19:19 ` Jeremy Allison
2010-08-16 18:04 ` J. Bruce Fields
2010-08-16 18:08 ` J. Bruce Fields
2010-08-16 19:07 ` Jeremy Allison
2010-08-08 23:07 ` Neil Brown
2010-07-22 15:46 ` Jan Engelhardt
2010-07-22 16:06 ` David Howells
[not found] ` <AANLkTikBCXK6uEw <AANLkTimdFCGSKLn7aGMpBMIauHTsHY7hpAAmpo6uTcnD@mail.gmail.com>
2010-07-31 16:53 ` David Howells
2010-07-31 18:05 ` utz lehmann
2010-07-31 19:26 ` David Howells
2010-07-15 2:17 ` [PATCH 03/18] AFS: Use i_generation not i_version for the vnode uniquifier " David Howells
2010-07-15 2:17 ` [PATCH 04/18] xstat: AFS: Return extended attributes " David Howells
2010-07-15 2:17 ` [PATCH 05/18] xstat: eCryptFS: " David Howells
2010-07-15 2:17 ` [PATCH 06/18] xstat: Ext4: " David Howells
2010-07-15 2:17 ` [PATCH 07/18] xstat: NFS: " David Howells
2010-07-15 2:17 ` [PATCH 08/18] xstat: CIFS: " David Howells
2010-07-15 2:17 ` [PATCH 09/18] xstat: Make special system filesystems return FS_SPECIAL_FL " David Howells
2010-07-18 8:49 ` Christoph Hellwig
2010-07-19 14:09 ` David Howells
2010-07-27 13:41 ` David Howells
2010-07-15 2:17 ` [PATCH 10/18] xstat: Make network filesystems return FS_REMOTE_FL " David Howells
2010-07-15 2:17 ` [PATCH 11/18] xstat: Make automounter filesystems return FS_AUTOMOUNT_FL " David Howells
2010-07-15 2:17 ` [PATCH 12/18] xstat: Add a dentry op to handle automounting rather than abusing follow_link() " David Howells
2010-07-18 8:50 ` Christoph Hellwig
2010-07-19 14:10 ` David Howells
2010-07-15 2:17 ` [PATCH 13/18] xstat: AFS: Use d_automount() " David Howells
2010-07-15 2:17 ` David Howells [this message]
2010-07-15 2:17 ` [PATCH 15/18] xstat: CIFS: " David Howells
2010-07-15 2:17 ` [PATCH 16/18] xstat: Remove the automount through follow_link() kludge code from pathwalk " David Howells
2010-07-15 2:17 ` [PATCH 17/18] xstat: Add an AT_NO_AUTOMOUNT flag to suppress terminal automount " David Howells
2010-07-15 2:17 ` [PATCH 18/18] xstat: Provide a mechanism to gather extra results for [f]xstat() " David Howells
2010-07-18 8:51 ` Christoph Hellwig
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20100715021726.5544.59242.stgit@warthog.procyon.org.uk \
--to=dhowells@redhat.com \
--cc=linux-cifs@vger.kernel.org \
--cc=linux-ext4@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-nfs@vger.kernel.org \
--cc=samba-technical@lists.samba.org \
--cc=viro@ZenIV.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome