diff options
author | NeilBrown <neilb@suse.de> | 2007-02-14 03:33:12 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-14 11:09:53 -0500 |
commit | af6a4e280e3ff453653f39190b57b345ff0bec16 (patch) | |
tree | 4895c90613737db7354f43431ed10a55dc0c98f0 /fs/nfsd/nfsfh.c | |
parent | 982aedfd091e6d9831216f8519f12242091be4fd (diff) |
[PATCH] knfsd: add some new fsid types
Add support for using a filesystem UUID to identify and export point in the
filehandle.
For NFSv2, this UUID is xor-ed down to 4 or 8 bytes so that it doesn't take up
too much room. For NFSv3+, we use the full 16 bytes, and possibly also a
64bit inode number for exports beneath the root of a filesystem.
When generating an fsid to return in 'stat' information, use the UUID (hashed
down to size) if it is available and a small 'fsid' was not specifically
provided.
Signed-off-by: Neil Brown <neilb@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/nfsd/nfsfh.c')
-rw-r--r-- | fs/nfsd/nfsfh.c | 88 |
1 files changed, 46 insertions, 42 deletions
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 12c5e7421374..286bc4d356f4 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c | |||
@@ -119,9 +119,6 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) | |||
119 | 119 | ||
120 | dprintk("nfsd: fh_verify(%s)\n", SVCFH_fmt(fhp)); | 120 | dprintk("nfsd: fh_verify(%s)\n", SVCFH_fmt(fhp)); |
121 | 121 | ||
122 | /* keep this filehandle for possible reference when encoding attributes */ | ||
123 | rqstp->rq_reffh = fh; | ||
124 | |||
125 | if (!fhp->fh_dentry) { | 122 | if (!fhp->fh_dentry) { |
126 | __u32 *datap=NULL; | 123 | __u32 *datap=NULL; |
127 | __u32 tfh[3]; /* filehandle fragment for oldstyle filehandles */ | 124 | __u32 tfh[3]; /* filehandle fragment for oldstyle filehandles */ |
@@ -146,10 +143,10 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) | |||
146 | } | 143 | } |
147 | len = key_len(fh->fh_fsid_type) / 4; | 144 | len = key_len(fh->fh_fsid_type) / 4; |
148 | if (len == 0) goto out; | 145 | if (len == 0) goto out; |
149 | if (fh->fh_fsid_type == 2) { | 146 | if (fh->fh_fsid_type == FSID_MAJOR_MINOR) { |
150 | /* deprecated, convert to type 3 */ | 147 | /* deprecated, convert to type 3 */ |
151 | len = 3; | 148 | len = key_len(FSID_ENCODE_DEV)/4; |
152 | fh->fh_fsid_type = 3; | 149 | fh->fh_fsid_type = FSID_ENCODE_DEV; |
153 | fh->fh_fsid[0] = new_encode_dev(MKDEV(ntohl(fh->fh_fsid[0]), ntohl(fh->fh_fsid[1]))); | 150 | fh->fh_fsid[0] = new_encode_dev(MKDEV(ntohl(fh->fh_fsid[0]), ntohl(fh->fh_fsid[1]))); |
154 | fh->fh_fsid[1] = fh->fh_fsid[2]; | 151 | fh->fh_fsid[1] = fh->fh_fsid[2]; |
155 | } | 152 | } |
@@ -164,8 +161,9 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) | |||
164 | /* assume old filehandle format */ | 161 | /* assume old filehandle format */ |
165 | xdev = old_decode_dev(fh->ofh_xdev); | 162 | xdev = old_decode_dev(fh->ofh_xdev); |
166 | xino = u32_to_ino_t(fh->ofh_xino); | 163 | xino = u32_to_ino_t(fh->ofh_xino); |
167 | mk_fsid_v0(tfh, xdev, xino); | 164 | mk_fsid(FSID_DEV, tfh, xdev, xino, 0, NULL); |
168 | exp = exp_find(rqstp->rq_client, 0, tfh, &rqstp->rq_chandle); | 165 | exp = exp_find(rqstp->rq_client, FSID_DEV, tfh, |
166 | &rqstp->rq_chandle); | ||
169 | } | 167 | } |
170 | 168 | ||
171 | if (IS_ERR(exp) && (PTR_ERR(exp) == -EAGAIN | 169 | if (IS_ERR(exp) && (PTR_ERR(exp) == -EAGAIN |
@@ -334,6 +332,7 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, | |||
334 | struct dentry *parent = dentry->d_parent; | 332 | struct dentry *parent = dentry->d_parent; |
335 | __u32 *datap; | 333 | __u32 *datap; |
336 | dev_t ex_dev = exp->ex_dentry->d_inode->i_sb->s_dev; | 334 | dev_t ex_dev = exp->ex_dentry->d_inode->i_sb->s_dev; |
335 | int root_export = (exp->ex_dentry == exp->ex_dentry->d_sb->s_root); | ||
337 | 336 | ||
338 | dprintk("nfsd: fh_compose(exp %02x:%02x/%ld %s/%s, ino=%ld)\n", | 337 | dprintk("nfsd: fh_compose(exp %02x:%02x/%ld %s/%s, ino=%ld)\n", |
339 | MAJOR(ex_dev), MINOR(ex_dev), | 338 | MAJOR(ex_dev), MINOR(ex_dev), |
@@ -348,19 +347,31 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, | |||
348 | if (ref_fh && ref_fh->fh_export == exp) { | 347 | if (ref_fh && ref_fh->fh_export == exp) { |
349 | version = ref_fh->fh_handle.fh_version; | 348 | version = ref_fh->fh_handle.fh_version; |
350 | if (version == 0xca) | 349 | if (version == 0xca) |
351 | fsid_type = 0; | 350 | fsid_type = FSID_DEV; |
352 | else | 351 | else |
353 | fsid_type = ref_fh->fh_handle.fh_fsid_type; | 352 | fsid_type = ref_fh->fh_handle.fh_fsid_type; |
354 | /* We know this version/type works for this export | 353 | /* We know this version/type works for this export |
355 | * so there is no need for further checks. | 354 | * so there is no need for further checks. |
356 | */ | 355 | */ |
356 | } else if (exp->ex_uuid) { | ||
357 | if (fhp->fh_maxsize >= 64) { | ||
358 | if (root_export) | ||
359 | fsid_type = FSID_UUID16; | ||
360 | else | ||
361 | fsid_type = FSID_UUID16_INUM; | ||
362 | } else { | ||
363 | if (root_export) | ||
364 | fsid_type = FSID_UUID8; | ||
365 | else | ||
366 | fsid_type = FSID_UUID4_INUM; | ||
367 | } | ||
357 | } else if (exp->ex_flags & NFSEXP_FSID) | 368 | } else if (exp->ex_flags & NFSEXP_FSID) |
358 | fsid_type = 1; | 369 | fsid_type = FSID_NUM; |
359 | else if (!old_valid_dev(ex_dev)) | 370 | else if (!old_valid_dev(ex_dev)) |
360 | /* for newer device numbers, we must use a newer fsid format */ | 371 | /* for newer device numbers, we must use a newer fsid format */ |
361 | fsid_type = 3; | 372 | fsid_type = FSID_ENCODE_DEV; |
362 | else | 373 | else |
363 | fsid_type = 0; | 374 | fsid_type = FSID_DEV; |
364 | 375 | ||
365 | if (ref_fh == fhp) | 376 | if (ref_fh == fhp) |
366 | fh_put(ref_fh); | 377 | fh_put(ref_fh); |
@@ -396,36 +407,10 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, | |||
396 | fhp->fh_handle.fh_auth_type = 0; | 407 | fhp->fh_handle.fh_auth_type = 0; |
397 | datap = fhp->fh_handle.fh_auth+0; | 408 | datap = fhp->fh_handle.fh_auth+0; |
398 | fhp->fh_handle.fh_fsid_type = fsid_type; | 409 | fhp->fh_handle.fh_fsid_type = fsid_type; |
399 | switch (fsid_type) { | 410 | mk_fsid(fsid_type, datap, ex_dev, |
400 | case 0: | 411 | exp->ex_dentry->d_inode->i_ino, |
401 | /* | 412 | exp->ex_fsid, exp->ex_uuid); |
402 | * fsid_type 0: | 413 | |
403 | * 2byte major, 2byte minor, 4byte inode | ||
404 | */ | ||
405 | mk_fsid_v0(datap, ex_dev, | ||
406 | exp->ex_dentry->d_inode->i_ino); | ||
407 | break; | ||
408 | case 1: | ||
409 | /* fsid_type 1 == 4 bytes filesystem id */ | ||
410 | mk_fsid_v1(datap, exp->ex_fsid); | ||
411 | break; | ||
412 | case 2: | ||
413 | /* | ||
414 | * fsid_type 2: | ||
415 | * 4byte major, 4byte minor, 4byte inode | ||
416 | */ | ||
417 | mk_fsid_v2(datap, ex_dev, | ||
418 | exp->ex_dentry->d_inode->i_ino); | ||
419 | break; | ||
420 | case 3: | ||
421 | /* | ||
422 | * fsid_type 3: | ||
423 | * 4byte devicenumber, 4byte inode | ||
424 | */ | ||
425 | mk_fsid_v3(datap, ex_dev, | ||
426 | exp->ex_dentry->d_inode->i_ino); | ||
427 | break; | ||
428 | } | ||
429 | len = key_len(fsid_type); | 414 | len = key_len(fsid_type); |
430 | datap += len/4; | 415 | datap += len/4; |
431 | fhp->fh_handle.fh_size = 4 + len; | 416 | fhp->fh_handle.fh_size = 4 + len; |
@@ -530,3 +515,22 @@ char * SVCFH_fmt(struct svc_fh *fhp) | |||
530 | fh->fh_base.fh_pad[5]); | 515 | fh->fh_base.fh_pad[5]); |
531 | return buf; | 516 | return buf; |
532 | } | 517 | } |
518 | |||
519 | enum fsid_source fsid_source(struct svc_fh *fhp) | ||
520 | { | ||
521 | if (fhp->fh_handle.fh_version != 1) | ||
522 | return FSIDSOURCE_DEV; | ||
523 | switch(fhp->fh_handle.fh_fsid_type) { | ||
524 | case FSID_DEV: | ||
525 | case FSID_ENCODE_DEV: | ||
526 | case FSID_MAJOR_MINOR: | ||
527 | return FSIDSOURCE_DEV; | ||
528 | case FSID_NUM: | ||
529 | return FSIDSOURCE_FSID; | ||
530 | default: | ||
531 | if (fhp->fh_export->ex_flags & NFSEXP_FSID) | ||
532 | return FSIDSOURCE_FSID; | ||
533 | else | ||
534 | return FSIDSOURCE_UUID; | ||
535 | } | ||
536 | } | ||