aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfsfh.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/nfsfh.c')
-rw-r--r--fs/nfsd/nfsfh.c57
1 files changed, 50 insertions, 7 deletions
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index 8d995bcef806..6ca2d24fc216 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -10,7 +10,6 @@
10 */ 10 */
11 11
12#include <linux/slab.h> 12#include <linux/slab.h>
13#include <linux/smp_lock.h>
14#include <linux/fs.h> 13#include <linux/fs.h>
15#include <linux/unistd.h> 14#include <linux/unistd.h>
16#include <linux/string.h> 15#include <linux/string.h>
@@ -324,7 +323,7 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry,
324 * 323 *
325 */ 324 */
326 325
327 u8 version = 1; 326 u8 version;
328 u8 fsid_type = 0; 327 u8 fsid_type = 0;
329 struct inode * inode = dentry->d_inode; 328 struct inode * inode = dentry->d_inode;
330 struct dentry *parent = dentry->d_parent; 329 struct dentry *parent = dentry->d_parent;
@@ -342,15 +341,59 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry,
342 * the reference filehandle (if it is in the same export) 341 * the reference filehandle (if it is in the same export)
343 * or the export options. 342 * or the export options.
344 */ 343 */
344 retry:
345 version = 1;
345 if (ref_fh && ref_fh->fh_export == exp) { 346 if (ref_fh && ref_fh->fh_export == exp) {
346 version = ref_fh->fh_handle.fh_version; 347 version = ref_fh->fh_handle.fh_version;
347 if (version == 0xca) 348 fsid_type = ref_fh->fh_handle.fh_fsid_type;
349
350 if (ref_fh == fhp)
351 fh_put(ref_fh);
352 ref_fh = NULL;
353
354 switch (version) {
355 case 0xca:
348 fsid_type = FSID_DEV; 356 fsid_type = FSID_DEV;
349 else 357 break;
350 fsid_type = ref_fh->fh_handle.fh_fsid_type; 358 case 1:
351 /* We know this version/type works for this export 359 break;
352 * so there is no need for further checks. 360 default:
361 goto retry;
362 }
363
364 /* Need to check that this type works for this
365 * export point. As the fsid -> filesystem mapping
366 * was guided by user-space, there is no guarantee
367 * that the filesystem actually supports that fsid
368 * type. If it doesn't we loop around again without
369 * ref_fh set.
353 */ 370 */
371 switch(fsid_type) {
372 case FSID_DEV:
373 if (!old_valid_dev(ex_dev))
374 goto retry;
375 /* FALL THROUGH */
376 case FSID_MAJOR_MINOR:
377 case FSID_ENCODE_DEV:
378 if (!(exp->ex_dentry->d_inode->i_sb->s_type->fs_flags
379 & FS_REQUIRES_DEV))
380 goto retry;
381 break;
382 case FSID_NUM:
383 if (! (exp->ex_flags & NFSEXP_FSID))
384 goto retry;
385 break;
386 case FSID_UUID8:
387 case FSID_UUID16:
388 if (!root_export)
389 goto retry;
390 /* fall through */
391 case FSID_UUID4_INUM:
392 case FSID_UUID16_INUM:
393 if (exp->ex_uuid == NULL)
394 goto retry;
395 break;
396 }
354 } else if (exp->ex_uuid) { 397 } else if (exp->ex_uuid) {
355 if (fhp->fh_maxsize >= 64) { 398 if (fhp->fh_maxsize >= 64) {
356 if (root_export) 399 if (root_export)