From cbba1c3f55a7f73791310085b5d9bc65008f0b9b Mon Sep 17 00:00:00 2001 From: Shehjar Tikoo Date: Wed, 29 Dec 2010 05:42:02 +0000 Subject: nfs3: Force root lookup before starting fh resolution Signed-off-by: Shehjar Tikoo Signed-off-by: Anand V. Avati BUG: 2200 (cp dies with "Invalid argument" after failover) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=2200 --- xlators/nfs/server/src/nfs3-helpers.c | 95 ++++++++++++++++++++++++++++++++--- xlators/nfs/server/src/nfs3.c | 38 ++++++++++++++ xlators/nfs/server/src/nfs3.h | 1 + 3 files changed, 127 insertions(+), 7 deletions(-) diff --git a/xlators/nfs/server/src/nfs3-helpers.c b/xlators/nfs/server/src/nfs3-helpers.c index a74a9041290..05baee3aaeb 100644 --- a/xlators/nfs/server/src/nfs3-helpers.c +++ b/xlators/nfs/server/src/nfs3-helpers.c @@ -37,6 +37,13 @@ #include "iatt.h" #include +extern int +nfs3_set_root_looked_up (struct nfs3_state *nfs3, struct nfs3_fh *rootfh); + +extern int +nfs3_is_root_looked_up (struct nfs3_state *nfs3, struct nfs3_fh *rootfh); + + #define nfs3_call_resume(cst) \ do { \ if (((cst)) && (cst)->resume_fn) \ @@ -3116,6 +3123,85 @@ nfs3_fh_resolve_entry (nfs3_call_state_t *cs) return 0; } + +int +nfs3_fh_resolve_resume (nfs3_call_state_t *cs) +{ + int ret = -EFAULT; + + if (!cs) + return ret; + + if (cs->resolve_ret < 0) + goto err_resume_call; + + if (!cs->resolventry) + ret = nfs3_fh_resolve_inode (cs); + else + ret = nfs3_fh_resolve_entry (cs); + +err_resume_call: + if (ret < 0) + nfs3_call_resume (cs); + + return ret; +} + + +int32_t +nfs3_fh_resolve_root_lookup_cbk (call_frame_t *frame, void *cookie, + xlator_t *this, int32_t op_ret, + int32_t op_errno, inode_t *inode, + struct iatt *buf, dict_t *xattr, + struct iatt *postparent) +{ + nfs3_call_state_t *cs = NULL; + + cs = frame->local; + cs->resolve_ret = op_ret; + cs->resolve_errno = op_errno; + + if (op_ret == -1) { + gf_log (GF_NFS3, GF_LOG_TRACE, "Lookup failed: %s: %s", + cs->resolvedloc.path, strerror (op_errno)); + goto err; + } else + gf_log (GF_NFS3, GF_LOG_TRACE, "Entry looked up: %s", + cs->resolvedloc.path); + + nfs3_set_root_looked_up (cs->nfs3state, &cs->resolvefh); +err: + nfs3_fh_resolve_resume (cs); + return 0; +} + + +int +nfs3_fh_resolve_root (nfs3_call_state_t *cs) +{ + int ret = -EFAULT; + nfs_user_t nfu = {0, }; + + if (!cs) + return ret; + + if (nfs3_is_root_looked_up (cs->nfs3state, &cs->resolvefh)) { + ret = nfs3_fh_resolve_resume (cs); + goto out; + } + + nfs_user_root_create (&nfu); + gf_log (GF_NFS3, GF_LOG_TRACE, "Root needs lookup"); + ret = nfs_root_loc_fill (cs->vol->itable, &cs->resolvedloc); + + ret = nfs_lookup (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc, + nfs3_fh_resolve_root_lookup_cbk, cs); + +out: + return ret; +} + + int nfs3_fh_resolve_and_resume (nfs3_call_state_t *cs, struct nfs3_fh *fh, char *entry, nfs3_resume_fn_t resum_fn) @@ -3136,18 +3222,13 @@ nfs3_fh_resolve_and_resume (nfs3_call_state_t *cs, struct nfs3_fh *fh, * * b. (fh, basename) resolution */ - if (!entry) /* a */ - ret = nfs3_fh_resolve_inode (cs); - else { /* b */ + if (entry) { /* b */ cs->resolventry = gf_strdup (entry); if (!cs->resolventry) goto err; - - ret = nfs3_fh_resolve_entry (cs); } + ret = nfs3_fh_resolve_root (cs); err: return ret; } - - diff --git a/xlators/nfs/server/src/nfs3.c b/xlators/nfs/server/src/nfs3.c index 46f7f7c5ce2..de32a2de05e 100644 --- a/xlators/nfs/server/src/nfs3.c +++ b/xlators/nfs/server/src/nfs3.c @@ -174,6 +174,44 @@ out: } +int +nfs3_is_root_looked_up (struct nfs3_state *nfs3, struct nfs3_fh *rootfh) +{ + struct nfs3_export *exp = NULL; + int ret = 0; + + if ((!nfs3) || (!rootfh)) + return 0; + + exp = __nfs3_get_export_by_exportid (nfs3, rootfh->exportid); + if (!exp) + goto out; + + ret = exp->rootlookedup; +out: + return ret; +} + + +int +nfs3_set_root_looked_up (struct nfs3_state *nfs3, struct nfs3_fh *rootfh) +{ + struct nfs3_export *exp = NULL; + int ret = 0; + + if ((!nfs3) || (!rootfh)) + return 0; + + exp = __nfs3_get_export_by_exportid (nfs3, rootfh->exportid); + if (!exp) + goto out; + + exp->rootlookedup = 1; +out: + return ret; +} + + #define nfs3_map_fh_to_volume(nfs3state, handle, rqst, volume, status, label) \ do { \ volume = nfs3_fh_to_xlator ((nfs3state), handle); \ diff --git a/xlators/nfs/server/src/nfs3.h b/xlators/nfs/server/src/nfs3.h index 7301fe0d8ca..bf4371a8a45 100644 --- a/xlators/nfs/server/src/nfs3.h +++ b/xlators/nfs/server/src/nfs3.h @@ -88,6 +88,7 @@ struct nfs3_export { int access; int trusted_sync; int trusted_write; + int rootlookedup; }; #define GF_NFS3_DEFAULT_VOLACCESS (GF_NFS3_VOLACCESS_RW) -- cgit