From: "J. Bruce Fields" <bfields@redhat.com>
To: linux-fsdevel@vger.kernel.org
Cc: Christoph Hellwig <hch@infradead.org>,
Al Viro <viro@ZenIV.linux.org.uk>,
linux-nfs@vger.kernel.org, "J. Bruce Fields" <bfields@redhat.com>
Subject: [PATCH 2/5] exportfs: move most of reconnect_path to helper function
Date: Tue, 15 Oct 2013 16:39:30 -0400 [thread overview]
Message-ID: <1381869574-10662-3-git-send-email-bfields@redhat.com> (raw)
In-Reply-To: <1381869574-10662-1-git-send-email-bfields@redhat.com>
From: "J. Bruce Fields" <bfields@redhat.com>
Just cleanup, no change in functionality.
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
---
fs/exportfs/expfs.c | 147 +++++++++++++++++++++++++++------------------------
1 file changed, 79 insertions(+), 68 deletions(-)
diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c
index 455b0bb..63996d2 100644
--- a/fs/exportfs/expfs.c
+++ b/fs/exportfs/expfs.c
@@ -107,6 +107,82 @@ static void clear_disconnected(struct dentry *dentry)
}
/*
+ * Return the parent directory on success.
+ *
+ * Return NULL to keep trying.
+ *
+ * Otherwise return an error.
+ */
+static int reconnect_one(struct vfsmount *mnt, struct dentry *pd, char *nbuf, int *noprogress)
+{
+ struct dentry *ppd;
+ struct dentry *npd;
+ int err;
+ /*
+ * Getting the parent can't be supported generically, the
+ * locking is too icky.
+ *
+ * If it can't be done, we just return EACCES. If you were
+ * depending on the dcache finding the parent for you, you lose
+ * if there's a reboot or inodes get flushed.
+ */
+ ppd = ERR_PTR(-EACCES);
+
+ mutex_lock(&pd->d_inode->i_mutex);
+ if (mnt->mnt_sb->s_export_op->get_parent)
+ ppd = mnt->mnt_sb->s_export_op->get_parent(pd);
+ mutex_unlock(&pd->d_inode->i_mutex);
+
+ if (IS_ERR(ppd)) {
+ err = PTR_ERR(ppd);
+ dprintk("%s: get_parent of %ld failed, err %d\n",
+ __func__, dentry->d_inode->i_ino, err);
+ return err;
+ }
+
+ dprintk("%s: find name of %lu in %lu\n", __func__,
+ dentry->d_inode->i_ino, parent->d_inode->i_ino);
+ err = exportfs_get_name(mnt, ppd, nbuf, pd);
+ if (err) {
+ dput(ppd);
+ if (err == -ENOENT)
+ /* some race between get_parent and
+ * get_name? just try again
+ */
+ return 0;
+ return err;
+ }
+ dprintk("%s: found name: %s\n", __func__, nbuf);
+ mutex_lock(&ppd->d_inode->i_mutex);
+ npd = lookup_one_len(nbuf, ppd, strlen(nbuf));
+ mutex_unlock(&ppd->d_inode->i_mutex);
+ if (IS_ERR(npd)) {
+ err = PTR_ERR(npd);
+ dprintk("%s: lookup failed: %d\n",
+ __func__, err);
+ dput(ppd);
+ return err;
+ }
+ /* we didn't really want npd, we really wanted
+ * a side-effect of the lookup.
+ * hopefully, npd == pd, though it isn't really
+ * a problem if it isn't
+ */
+ if (npd == pd)
+ *noprogress = 0;
+ else
+ printk("%s: npd != pd\n", __func__);
+ dput(npd);
+ dput(ppd);
+ if (IS_ROOT(pd)) {
+ /* something went wrong, we have to give up */
+ dput(pd);
+ return -ESTALE;
+ }
+ return 0;
+}
+
+/*
* Make sure target_dir is fully connected to the dentry tree.
*
* It may already be, as the flag isn't always updated when connection happens.
@@ -140,75 +216,10 @@ reconnect_path(struct vfsmount *mnt, struct dentry *target_dir, char *nbuf)
/*
* We have hit the top of a disconnected path, try to
* find parent and connect.
- *
- * Racing with some other process renaming a directory
- * isn't much of a problem here. If someone renames
- * the directory, it will end up properly connected,
- * which is what we want
- *
- * Getting the parent can't be supported generically,
- * the locking is too icky.
- *
- * Instead we just return EACCES. If server reboots
- * or inodes get flushed, you lose
- */
- struct dentry *ppd = ERR_PTR(-EACCES);
- struct dentry *npd;
-
- mutex_lock(&pd->d_inode->i_mutex);
- if (mnt->mnt_sb->s_export_op->get_parent)
- ppd = mnt->mnt_sb->s_export_op->get_parent(pd);
- mutex_unlock(&pd->d_inode->i_mutex);
-
- if (IS_ERR(ppd)) {
- err = PTR_ERR(ppd);
- dprintk("%s: get_parent of %ld failed, err %d\n",
- __func__, pd->d_inode->i_ino, err);
- dput(pd);
- break;
- }
-
- dprintk("%s: find name of %lu in %lu\n", __func__,
- pd->d_inode->i_ino, ppd->d_inode->i_ino);
- err = exportfs_get_name(mnt, ppd, nbuf, pd);
- if (err) {
- dput(ppd);
- dput(pd);
- if (err == -ENOENT)
- /* some race between get_parent and
- * get_name? just try again
- */
- continue;
- break;
- }
- dprintk("%s: found name: %s\n", __func__, nbuf);
- mutex_lock(&ppd->d_inode->i_mutex);
- npd = lookup_one_len(nbuf, ppd, strlen(nbuf));
- mutex_unlock(&ppd->d_inode->i_mutex);
- if (IS_ERR(npd)) {
- err = PTR_ERR(npd);
- dprintk("%s: lookup failed: %d\n",
- __func__, err);
- dput(ppd);
- dput(pd);
- break;
- }
- /* we didn't really want npd, we really wanted
- * a side-effect of the lookup.
- * hopefully, npd == pd, though it isn't really
- * a problem if it isn't
*/
- if (npd == pd)
- noprogress = 0;
- else
- printk("%s: npd != pd\n", __func__);
- dput(npd);
- dput(ppd);
- if (IS_ROOT(pd)) {
- /* something went wrong, we have to give up */
- dput(pd);
- break;
- }
+ err = reconnect_one(mnt, pd, nbuf, &noprogress);
+ if (err)
+ return err;
}
dput(pd);
}
--
1.7.9.5
next prev parent reply other threads:[~2013-10-15 20:40 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-10-15 20:39 simplify reconnecting dentries looked up by filehandle J. Bruce Fields
2013-10-15 20:39 ` [PATCH 1/5] exportfs: clear DISCONNECTED on all parents sooner J. Bruce Fields
2013-10-16 7:13 ` Christoph Hellwig
2013-10-16 7:13 ` Christoph Hellwig
2013-10-16 13:56 ` J. Bruce Fields
2013-10-16 13:56 ` J. Bruce Fields
2013-10-15 20:39 ` J. Bruce Fields [this message]
2013-10-16 7:16 ` [PATCH 2/5] exportfs: move most of reconnect_path to helper function Christoph Hellwig
2013-10-16 7:16 ` Christoph Hellwig
2013-10-15 20:39 ` [PATCH 3/5] exportfs: make variable names more helpful J. Bruce Fields
2013-10-15 20:39 ` J. Bruce Fields
2013-10-16 7:18 ` Christoph Hellwig
2013-10-16 7:18 ` Christoph Hellwig
2013-10-15 20:39 ` [PATCH 4/5] exportfs: slight reorganization of reconnect loop J. Bruce Fields
2013-10-16 7:19 ` Christoph Hellwig
2013-10-15 20:39 ` [PATCH 5/5] exportfs: fix quadratic behavior in filehandle lookup J. Bruce Fields
2013-10-15 20:39 ` J. Bruce Fields
2013-10-16 8:04 ` Christoph Hellwig
2013-10-16 8:04 ` Christoph Hellwig
2013-10-16 18:29 ` J. Bruce Fields
2013-10-16 19:22 ` J. Bruce Fields
2013-10-16 22:00 ` J. Bruce Fields
2013-10-16 18:24 ` simplify reconnecting dentries looked up by filehandle Christoph Hellwig
2013-10-16 18:24 ` 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=1381869574-10662-3-git-send-email-bfields@redhat.com \
--to=bfields@redhat.com \
--cc=hch@infradead.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-nfs@vger.kernel.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.