nfsd: minor nfsd_lookup cleanup
authorJ. Bruce Fields <bfields@citi.umich.edu>
Sun, 27 Sep 2009 00:32:24 +0000 (20:32 -0400)
committerJ. Bruce Fields <bfields@citi.umich.edu>
Mon, 28 Sep 2009 16:07:53 +0000 (12:07 -0400)
Break out some of nfsd_lookup_dentry into helper functions.

Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
fs/nfsd/vfs.c

index b8ed58b..6385739 100644 (file)
@@ -141,6 +141,40 @@ out:
        return err;
 }
 
+static void follow_to_parent(struct path *path)
+{
+       struct dentry *dp;
+
+       while (path->dentry == path->mnt->mnt_root && follow_up(path))
+               ;
+       dp = dget_parent(path->dentry);
+       dput(path->dentry);
+       path->dentry = dp;
+}
+
+static int nfsd_lookup_parent(struct svc_rqst *rqstp, struct dentry *dparent, struct svc_export **exp, struct dentry **dentryp)
+{
+       struct svc_export *exp2;
+       struct path path = {.mnt = mntget((*exp)->ex_path.mnt),
+                           .dentry = dget(dparent)};
+
+       follow_to_parent(&path);
+
+       exp2 = rqst_exp_parent(rqstp, &path);
+       if (PTR_ERR(exp2) == -ENOENT) {
+               *dentryp = dget(dparent);
+       } else if (IS_ERR(exp2)) {
+               path_put(&path);
+               return PTR_ERR(exp2);
+       } else {
+               *dentryp = dget(path.dentry);
+               exp_put(*exp);
+               *exp = exp2;
+       }
+       path_put(&path);
+       return 0;
+}
+
 __be32
 nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp,
                   const char *name, unsigned int len,
@@ -173,31 +207,9 @@ nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp,
                        dentry = dget(dparent); /* .. == . just like at / */
                else {
                        /* checking mountpoint crossing is very different when stepping up */
-                       struct svc_export *exp2 = NULL;
-                       struct dentry *dp;
-                       struct path path = {.mnt = mntget(exp->ex_path.mnt),
-                                           .dentry = dget(dparent)};
-
-                       while (path.dentry == path.mnt->mnt_root &&
-                              follow_up(&path))
-                               ;
-                       dp = dget_parent(path.dentry);
-                       dput(path.dentry);
-                       path.dentry = dp;
-
-                       exp2 = rqst_exp_parent(rqstp, &path);
-                       if (PTR_ERR(exp2) == -ENOENT) {
-                               dentry = dget(dparent);
-                       } else if (IS_ERR(exp2)) {
-                               host_err = PTR_ERR(exp2);
-                               path_put(&path);
+                       host_err = nfsd_lookup_parent(rqstp, dparent, &exp, &dentry);
+                       if (host_err)
                                goto out_nfserr;
-                       } else {
-                               dentry = dget(path.dentry);
-                               exp_put(exp);
-                               exp = exp2;
-                       }
-                       path_put(&path);
                }
        } else {
                fh_lock(fhp);