summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBipin Kunal <bkunal@redhat.com>2017-02-27 15:23:04 +0530
committerNiels de Vos <ndevos@redhat.com>2017-04-29 11:20:30 +0000
commit767047377acee40f40237d2aca45cd94391cba37 (patch)
tree1ae06bdf41c6a6d2e64c68c835872f7d46a5414e
parent57b481a071c13078c603cf2d96f9a04b9ebc39b4 (diff)
nfs: make subdir mounting work for Solaris 10 clients
This fixes the segfault caused by solaris client in Gluster/NFS. Volname was not being parsed properly, Instead of volume name complete path was being used in nfs_mntpath_to_xlator(). Fixed it by striping volume name from complete path in nfs_mntpath_to_xlator(). Modified function name nfs3_funge_solaris_zerolen_fh() to nfs3_funge_webnfs_zerolen_fh() as zero-filled filehandle is specific to WebNFS. RFC : https://tools.ietf.org/html/rfc2055 Solaris uses WebNFS, the zero-filled FH is defined in the WebNFS spec. Logic was even added in fuction nfs3_funge_webnfs_zerolen_fh() to send subdir path in function glfs_resolve_at() instead of complete path for subdir mount. > Change-Id: I19aae3547b8910e7ed4974ee5385424cab3e834a > BUG: 1426667 > Signed-off-by: Bipin Kunal <bkunal@redhat.com> > Reviewed-on: https://review.gluster.org/16770 > Reviewed-by: Niels de Vos <ndevos@redhat.com> > Smoke: Gluster Build System <jenkins@build.gluster.org> > NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> > CentOS-regression: Gluster Build System <jenkins@build.gluster.org> > (cherry picked from commit 40e571339b3c19ab2a5b6a93bc46eadf2252d006) Change-Id: I21ebb1d104b6eb914af5f26a6906f161c132179c BUG: 1440228 Signed-off-by: Bipin Kunal <bkunal@redhat.com> Reviewed-on: https://review.gluster.org/17017 CentOS-regression: Gluster Build System <jenkins@build.gluster.org> Reviewed-by: Niels de Vos <ndevos@redhat.com> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> Smoke: Gluster Build System <jenkins@build.gluster.org>
-rw-r--r--api/src/glfs-resolve.c6
-rw-r--r--xlators/nfs/server/src/nfs-common.c18
-rw-r--r--xlators/nfs/server/src/nfs3.c96
3 files changed, 89 insertions, 31 deletions
diff --git a/api/src/glfs-resolve.c b/api/src/glfs-resolve.c
index f8b437bab0e..d495cd21413 100644
--- a/api/src/glfs-resolve.c
+++ b/api/src/glfs-resolve.c
@@ -385,6 +385,9 @@ priv_glfs_resolve_at (struct glfs *fs, xlator_t *subvol, inode_t *at,
int ret = -1;
struct iatt ciatt = {0, };
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
path = gf_strdup (origpath);
if (!path) {
errno = ENOMEM;
@@ -510,9 +513,10 @@ priv_glfs_resolve_at (struct glfs *fs, xlator_t *subvol, inode_t *at,
}
out:
GF_FREE (path);
+ __GLFS_EXIT_FS;
/* do NOT loc_wipe here as only last component might be missing */
-
+invalid_fs:
return ret;
}
diff --git a/xlators/nfs/server/src/nfs-common.c b/xlators/nfs/server/src/nfs-common.c
index af37f6b264c..526918872d7 100644
--- a/xlators/nfs/server/src/nfs-common.c
+++ b/xlators/nfs/server/src/nfs-common.c
@@ -73,10 +73,11 @@ nfs_xlator_to_xlid (xlator_list_t *cl, xlator_t *xl)
xlator_t *
nfs_mntpath_to_xlator (xlator_list_t *cl, char *path)
{
- char *volname = NULL;
- char *volptr = NULL;
- size_t pathlen;
+ char *volname = NULL;
+ char *volptr = NULL;
+ size_t pathlen = -1;
xlator_t *targetxl = NULL;
+ int i = 0;
if ((!cl) || (!path))
return NULL;
@@ -89,10 +90,17 @@ nfs_mntpath_to_xlator (xlator_list_t *cl, char *path)
else
volptr = &volname[0];
- if (pathlen && volname[pathlen - 1] == '/')
- volname[pathlen - 1] = '\0';
+ for (i = 0; i < pathlen; i++) {
+ if (volname[i] == '/') {
+ volname[i] = '\0';
+ break;
+ }
+ }
while (cl) {
+ gf_msg_trace (GF_NFS, 0, "Volptr: %s and cl->xlator->name: %s",
+ volptr, cl->xlator->name);
+
if (strcmp (volptr, cl->xlator->name) == 0) {
targetxl = cl->xlator;
break;
diff --git a/xlators/nfs/server/src/nfs3.c b/xlators/nfs/server/src/nfs3.c
index 64287c5b1bd..8b1d62b46ac 100644
--- a/xlators/nfs/server/src/nfs3.c
+++ b/xlators/nfs/server/src/nfs3.c
@@ -28,6 +28,7 @@
#include "xdr-rpc.h"
#include "xdr-generic.h"
#include "nfs-messages.h"
+#include "glfs-internal.h"
#include <sys/socket.h>
#include <sys/uio.h>
@@ -348,28 +349,68 @@ out:
}
-#define nfs3_funge_solaris_zerolen_fh(nfs3st, fhd, enam, nfsst, erl) \
- do { \
- xlator_t *fungexl = NULL; \
- uuid_t zero = {0, }; \
- fungexl =nfs_mntpath_to_xlator ((nfs3st)->exportslist,enam);\
- if (!fungexl) { \
- (nfsst) = NFS3ERR_NOENT; \
- goto erl; \
- } \
- \
- gf_uuid_copy ((fhd)->gfid, zero); \
- (fhd)->gfid[15] = 1; \
- (enam) = NULL; \
- if ((gf_nfs_dvm_off (nfs_state (nfs3st->nfsx)))) \
- (fhd)->exportid[15] = nfs_xlator_to_xlid ((nfs3st)->exportslist, fungexl); \
- else { \
- if(__nfs3_get_volume_id ((nfs3st), fungexl, (fhd)->exportid) < 0) { \
- (nfsst) = NFS3ERR_STALE; \
- goto erl; \
- } \
- } \
- } while (0) \
+static enum nfsstat3
+nfs3_funge_webnfs_zerolen_fh (struct nfs3_state *nfs3st, struct nfs3_fh *fhd,
+ char *name)
+{
+ xlator_t *fungexl = NULL;
+ glfs_t *fs = NULL;
+ loc_t loc = { 0, };
+ enum nfsstat3 nfsstat = NFS3ERR_SERVERFAULT;
+ int ret = -1;
+ size_t namelen = -1;
+
+ fungexl = nfs_mntpath_to_xlator (nfs3st->exportslist, name);
+ if (!fungexl) {
+ nfsstat = NFS3ERR_NOENT;
+ goto out;
+ }
+
+ /* glfs_resolve_at copied from UDP MNT support */
+ fs = glfs_new_from_ctx (fungexl->ctx);
+ if (!fs) {
+ nfsstat = NFS3ERR_NOENT;
+ goto out;
+ }
+
+ /* strip volname/ from 'name' */
+ namelen = strlen(name);
+ while (namelen != 0) {
+ name++;
+ if (name[0] == '/') {
+ break;
+ }
+ namelen--;
+ }
+ gf_msg_debug (GF_NFS, 0, "NAME :%s ", name);
+
+ ret = glfs_resolve_at (fs, fungexl, NULL, name, &loc, NULL, 1, 0);
+ if (ret != 0) {
+ nfsstat = NFS3ERR_NOENT;
+ goto out;
+ }
+
+ /* resolved subdir, copy gfid for the fh */
+ gf_uuid_copy (fhd->gfid, loc.gfid);
+ loc_wipe (&loc);
+
+ if (gf_nfs_dvm_off (nfs_state (nfs3st->nfsx)))
+ fhd->exportid[15] = nfs_xlator_to_xlid (nfs3st->exportslist,
+ fungexl);
+ else {
+ if (__nfs3_get_volume_id (nfs3st, fungexl, fhd->exportid) < 0) {
+ nfsstat = NFS3ERR_STALE;
+ goto out;
+ }
+ }
+
+ nfsstat = NFS3_OK;
+out:
+ if (fs)
+ glfs_free_from_ctx (fs);
+
+ return nfsstat;
+}
#define nfs3_volume_started_check(nf3stt, vlm, rtval, erlbl) \
@@ -1495,9 +1536,14 @@ nfs3_lookup (rpcsvc_request_t *req, struct nfs3_fh *fh, int fhlen, char *name)
nfs3_log_fh_entry_call (rpcsvc_request_xid (req), "LOOKUP", fh,
name);
nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret);
- if (nfs3_solaris_zerolen_fh (fh, fhlen))
- nfs3_funge_solaris_zerolen_fh (nfs3, fh, name, stat, nfs3err);
- else
+ if (nfs3_solaris_zerolen_fh (fh, fhlen)) {
+ stat = nfs3_funge_webnfs_zerolen_fh (nfs3, fh, name);
+ if (stat != NFS3_OK)
+ goto nfs3err;
+
+ /* this fh means we're doing a mount, name is no more useful */
+ name = NULL;
+ } else
nfs3_validate_gluster_fh (fh, stat, nfs3err);
nfs3_validate_strlen_or_goto (name, NFS_NAME_MAX, nfs3err, stat, ret);
nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err);