diff options
| author | Shehjar Tikoo <shehjart@gluster.com> | 2010-05-31 22:43:53 +0000 | 
|---|---|---|
| committer | Anand V. Avati <avati@dev.gluster.com> | 2010-06-01 00:23:51 -0700 | 
| commit | 7cda6661979dfec1614575a9729b84cbf49e6b25 (patch) | |
| tree | 515dc223f685190243b1a1338c3b0929b6244d45 /xlators/nfs | |
| parent | da08199c57cedb3dc922ed6bec07932cd2aefabd (diff) | |
nfs3: Special-case the lookup for parent dir of root
When a lookup request comes in for (rootfh, ".."), we need to handle
it in a way that returns the attributes and handle of the root dir.
Not doing so crashes nfsx because the inode table is not able to
find a inode for the root's parent. This inode was being referenced in
nfs3_lookup_parentdir_resume when filling a loc for the lookup fop.
For the record, such a lookup request is sent by vmkernel.
Signed-off-by: Shehjar Tikoo <shehjart@gluster.com>
Signed-off-by: Anand V. Avati <avati@dev.gluster.com>
BUG: 942 (NFS crashes as a vmware ESX data store)
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=942
Diffstat (limited to 'xlators/nfs')
| -rw-r--r-- | xlators/nfs/server/src/nfs3.c | 38 | 
1 files changed, 31 insertions, 7 deletions
diff --git a/xlators/nfs/server/src/nfs3.c b/xlators/nfs/server/src/nfs3.c index f09ed95d9da..fda6d6413bf 100644 --- a/xlators/nfs/server/src/nfs3.c +++ b/xlators/nfs/server/src/nfs3.c @@ -895,7 +895,15 @@ nfs3svc_lookup_parentdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  goto xmit_res;          } -        nfs3_fh_build_parent_fh (&cs->fh, buf, &newfh); +        /* If the buf inode shows that this is a root dir's buf, then the file +         * handle needs to be specially crafted, in all other cases, we'll just +         * create the handle normally using the buffer of the parent dir. +         */ +        if (buf->ia_ino != 1) +                nfs3_fh_build_parent_fh (&cs->fh, buf, &newfh); +        else +                newfh = nfs3_fh_build_root_fh (cs->nfs3state->exportslist, +                                               cs->vol, *buf);  xmit_res:          nfs3_log_newfh_res (rpcsvc_request_xid (cs->req), "LOOKUP", status, @@ -926,18 +934,34 @@ nfs3_lookup_parentdir_resume (void *carg)          /* At this point now, the loc in cs is for the directory file handle           * sent by the client. This loc needs to be transformed into a loc that           * represents the parent dir of cs->resolvedloc.inode. +         * +         * EXCEPT in the case where the .. is a parent of the root directory. +         * In this case we'll be returning the file handle and attributes of the +         * root itself.           */          nfs_request_user_init (&nfu, cs->req);          /* Save the file handle from the LOOKUP request. We'll use this to -         * build the file handle of the parent directory. +         * build the file handle of the parent directory in case the parent is +         * not root dir.           */          cs->fh = cs->resolvefh; -        parent = inode_ref (cs->resolvedloc.parent); -        nfs_loc_wipe (&cs->resolvedloc); -        ret = nfs_inode_loc_fill (parent, &cs->resolvedloc); -        if (ret < 0) -                goto errtostat; + +        /* If fh is that of the root, the resolvedloc will already contain +         * the loc for root. After that, we'll send lookup for the root dir +         * itself since we cannot send the lookup on the parent of root. +         * +         * For all other cases, we'll send the lookup on the parent of the +         * given directory file handle. +         */ +        if (!nfs3_fh_is_root_fh (&cs->fh)) { +                parent = inode_ref (cs->resolvedloc.parent); +                nfs_loc_wipe (&cs->resolvedloc); +                ret = nfs_inode_loc_fill (parent, &cs->resolvedloc); + +                if (ret < 0) +                        goto errtostat; +        }          ret = nfs_lookup (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,                            nfs3svc_lookup_parentdir_cbk, cs);  | 
