summaryrefslogtreecommitdiffstats
path: root/xlators
diff options
context:
space:
mode:
authorShehjar Tikoo <shehjart@gluster.com>2010-12-29 05:42:02 +0000
committerAnand V. Avati <avati@dev.gluster.com>2010-12-29 10:20:50 -0800
commitcbba1c3f55a7f73791310085b5d9bc65008f0b9b (patch)
treef1d09a4bf3524b1879e9918ceb2e58d2671036f1 /xlators
parent165efc45ab5518033612a58c1ac51243eb6bcef8 (diff)
nfs3: Force root lookup before starting fh resolution
Signed-off-by: Shehjar Tikoo <shehjart@gluster.com> Signed-off-by: Anand V. Avati <avati@dev.gluster.com> BUG: 2200 (cp dies with "Invalid argument" after failover) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=2200
Diffstat (limited to 'xlators')
-rw-r--r--xlators/nfs/server/src/nfs3-helpers.c95
-rw-r--r--xlators/nfs/server/src/nfs3.c38
-rw-r--r--xlators/nfs/server/src/nfs3.h1
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 a74a90412..05baee3aa 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 <string.h>
+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 46f7f7c5c..de32a2de0 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 7301fe0d8..bf4371a8a 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)