diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-05-10 16:29:23 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-05-10 16:29:23 -0400 |
commit | c70422f760c120480fee4de6c38804c72aa26bc1 (patch) | |
tree | 9c61102379bbbf090c13c373ffdace76fe7711ef /fs/nfsd/vfs.c | |
parent | 73ccb023a2f25b72c4b95499ca24760588014614 (diff) | |
parent | b26b78cb726007533d81fdf90a62e915002ef5c8 (diff) |
Merge tag 'nfsd-4.12' of git://linux-nfs.org/~bfields/linux
Pull nfsd updates from Bruce Fields:
"Another RDMA update from Chuck Lever, and a bunch of miscellaneous
bugfixes"
* tag 'nfsd-4.12' of git://linux-nfs.org/~bfields/linux: (26 commits)
nfsd: Fix up the "supattr_exclcreat" attributes
nfsd: encoders mustn't use unitialized values in error cases
nfsd: fix undefined behavior in nfsd4_layout_verify
lockd: fix lockd shutdown race
NFSv4: Fix callback server shutdown
SUNRPC: Refactor svc_set_num_threads()
NFSv4.x/callback: Create the callback service through svc_create_pooled
lockd: remove redundant check on block
svcrdma: Clean out old XDR encoders
svcrdma: Remove the req_map cache
svcrdma: Remove unused RDMA Write completion handler
svcrdma: Reduce size of sge array in struct svc_rdma_op_ctxt
svcrdma: Clean up RPC-over-RDMA backchannel reply processing
svcrdma: Report Write/Reply chunk overruns
svcrdma: Clean up RDMA_ERROR path
svcrdma: Use rdma_rw API in RPC reply path
svcrdma: Introduce local rdma_rw API helpers
svcrdma: Clean up svc_rdma_get_inv_rkey()
svcrdma: Add helper to save pages under I/O
svcrdma: Eliminate RPCRDMA_SQ_DEPTH_MULT
...
Diffstat (limited to 'fs/nfsd/vfs.c')
-rw-r--r-- | fs/nfsd/vfs.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 9aaf6ca77569..2be32955d7f2 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -94,6 +94,12 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp, | |||
94 | err = follow_down(&path); | 94 | err = follow_down(&path); |
95 | if (err < 0) | 95 | if (err < 0) |
96 | goto out; | 96 | goto out; |
97 | if (path.mnt == exp->ex_path.mnt && path.dentry == dentry && | ||
98 | nfsd_mountpoint(dentry, exp) == 2) { | ||
99 | /* This is only a mountpoint in some other namespace */ | ||
100 | path_put(&path); | ||
101 | goto out; | ||
102 | } | ||
97 | 103 | ||
98 | exp2 = rqst_exp_get_by_name(rqstp, &path); | 104 | exp2 = rqst_exp_get_by_name(rqstp, &path); |
99 | if (IS_ERR(exp2)) { | 105 | if (IS_ERR(exp2)) { |
@@ -167,16 +173,26 @@ static int nfsd_lookup_parent(struct svc_rqst *rqstp, struct dentry *dparent, st | |||
167 | /* | 173 | /* |
168 | * For nfsd purposes, we treat V4ROOT exports as though there was an | 174 | * For nfsd purposes, we treat V4ROOT exports as though there was an |
169 | * export at *every* directory. | 175 | * export at *every* directory. |
176 | * We return: | ||
177 | * '1' if this dentry *must* be an export point, | ||
178 | * '2' if it might be, if there is really a mount here, and | ||
179 | * '0' if there is no chance of an export point here. | ||
170 | */ | 180 | */ |
171 | int nfsd_mountpoint(struct dentry *dentry, struct svc_export *exp) | 181 | int nfsd_mountpoint(struct dentry *dentry, struct svc_export *exp) |
172 | { | 182 | { |
173 | if (d_mountpoint(dentry)) | 183 | if (!d_inode(dentry)) |
184 | return 0; | ||
185 | if (exp->ex_flags & NFSEXP_V4ROOT) | ||
174 | return 1; | 186 | return 1; |
175 | if (nfsd4_is_junction(dentry)) | 187 | if (nfsd4_is_junction(dentry)) |
176 | return 1; | 188 | return 1; |
177 | if (!(exp->ex_flags & NFSEXP_V4ROOT)) | 189 | if (d_mountpoint(dentry)) |
178 | return 0; | 190 | /* |
179 | return d_inode(dentry) != NULL; | 191 | * Might only be a mountpoint in a different namespace, |
192 | * but we need to check. | ||
193 | */ | ||
194 | return 2; | ||
195 | return 0; | ||
180 | } | 196 | } |
181 | 197 | ||
182 | __be32 | 198 | __be32 |