diff options
| author | Niels de Vos <ndevos@redhat.com> | 2016-05-19 12:53:09 +0200 | 
|---|---|---|
| committer | Jeff Darcy <jdarcy@redhat.com> | 2016-05-23 06:20:39 -0700 | 
| commit | 6c936a0da3f5f56dd711169f7eb8d335bbb8cdc7 (patch) | |
| tree | 60078d56701396ffaca73c62ad471818b7a2b85c | |
| parent | 5cf7a32be8d614e8cd89a01ac06e830cbd693929 (diff) | |
nfs: strip trailing / when clients do subdir mounts
Mounting a volume over NFS with a subdir followed by a / does not work:
  # mount -t nfs -o vers=3 storage.example.com:/media/installation/ /mnt
  mount.nfs: an incorrect mount option was specified
In the nfs.log:
  [client-rpc-fops.c:2930:client3_3_lookup_cbk] 0-media-client-0: remote operation failed. Path: /installation/ (00000000-0000-0000-0000-000000000000) [Invalid argument]
  [client-rpc-fops.c:2930:client3_3_lookup_cbk] 0-media-client-1: remote operation failed. Path: /installation/ (00000000-0000-0000-0000-000000000000) [Invalid argument]
  [mount3.c:1134:mnt3_resolve_subdir_cbk] 0-nfs: path=/installation/ (Invalid argument) [Invalid argument]
It is not possible to resolve paths with a trailing /. Stripping
trailing /'s from the subdir to mount is sufficient to make it work
again.
Change-Id: I4075d4cd351438de58e1ff81f0fb65a1ff076da4
BUG: 1337597
Signed-off-by: Niels de Vos <ndevos@redhat.com>
Reviewed-on: http://review.gluster.org/14421
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
Smoke: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: jiffin tony Thottan <jthottan@redhat.com>
CentOS-regression: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Jeff Darcy <jdarcy@redhat.com>
| -rw-r--r-- | tests/bugs/nfs/subdir-trailing-slash.t | 31 | ||||
| -rw-r--r-- | xlators/nfs/server/src/mount3.c | 5 | 
2 files changed, 36 insertions, 0 deletions
diff --git a/tests/bugs/nfs/subdir-trailing-slash.t b/tests/bugs/nfs/subdir-trailing-slash.t new file mode 100644 index 00000000000..a00959443d0 --- /dev/null +++ b/tests/bugs/nfs/subdir-trailing-slash.t @@ -0,0 +1,31 @@ +#!/bin/bash +# +# Verify that mounting a subdir over NFS works, even with a trailing / +# +# For example: +#    mount -t nfs server.example.com:/volume/subdir/ +# + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc +. $(dirname $0)/../../nfs.rc + + +cleanup; +TEST glusterd +TEST pidof glusterd + +TEST $CLI volume create $V0 $H0:$B0/$V0 +TEST $CLI volume set $V0 nfs.disable false + +TEST $CLI volume start $V0 +EXPECT_WITHIN $NFS_EXPORT_TIMEOUT "1" is_nfs_export_available + +TEST mount_nfs $H0:/$V0 $N0 nolock +TEST mkdir -p $N0/subdir +EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" force_umount $N0 + +TEST mount_nfs $H0:/$V0/subdir/ $N0 nolock +EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" force_umount $N0 + +cleanup diff --git a/xlators/nfs/server/src/mount3.c b/xlators/nfs/server/src/mount3.c index 7b49d097d96..cb8b9a1af2f 100644 --- a/xlators/nfs/server/src/mount3.c +++ b/xlators/nfs/server/src/mount3.c @@ -1524,6 +1524,7 @@ mnt3_resolve_subdir (rpcsvc_request_t *req, struct mount3_state *ms,          int                   ret = -EFAULT;          struct nfs3_fh        pfh = GF_NFS3FH_STATIC_INITIALIZER;          struct sockaddr_in    *sin = NULL; +        int                   len = -1;          if ((!req) || (!ms) || (!exp) || (!subdir))                  return ret; @@ -1551,7 +1552,10 @@ mnt3_resolve_subdir (rpcsvc_request_t *req, struct mount3_state *ms,          mres->exp = exp;          mres->mstate = ms;          mres->req = req; +          strncpy (mres->remainingdir, subdir, MNTPATHLEN); +        gf_path_strip_trailing_slashes (mres->remainingdir); +          if (gf_nfs_dvm_off (nfs_state (ms->nfsx)))                  pfh = nfs3_fh_build_indexed_root_fh (                                              mres->mstate->nfsx->children, @@ -2493,6 +2497,7 @@ mnt3svc_umnt (rpcsvc_request_t *req)          if (colon) {                  *colon= '\0';          } +        gf_path_strip_trailing_slashes (dirpath);          gf_msg_debug (GF_MNT, 0, "dirpath: %s, hostname: %s", dirpath,                        hostname);          ret = mnt3svc_umount (ms, dirpath, hostname);  | 
