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.c145
1 files changed, 72 insertions, 73 deletions
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index a0b4282cb284..c2660cbfcd96 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -9,7 +9,6 @@
9 * ... and again Southern-Winter 2001 to support export_operations 9 * ... and again Southern-Winter 2001 to support export_operations
10 */ 10 */
11 11
12#include <linux/sched.h>
13#include <linux/slab.h> 12#include <linux/slab.h>
14#include <linux/smp_lock.h> 13#include <linux/smp_lock.h>
15#include <linux/fs.h> 14#include <linux/fs.h>
@@ -119,9 +118,6 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
119 118
120 dprintk("nfsd: fh_verify(%s)\n", SVCFH_fmt(fhp)); 119 dprintk("nfsd: fh_verify(%s)\n", SVCFH_fmt(fhp));
121 120
122 /* keep this filehandle for possible reference when encoding attributes */
123 rqstp->rq_reffh = fh;
124
125 if (!fhp->fh_dentry) { 121 if (!fhp->fh_dentry) {
126 __u32 *datap=NULL; 122 __u32 *datap=NULL;
127 __u32 tfh[3]; /* filehandle fragment for oldstyle filehandles */ 123 __u32 tfh[3]; /* filehandle fragment for oldstyle filehandles */
@@ -146,10 +142,10 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
146 } 142 }
147 len = key_len(fh->fh_fsid_type) / 4; 143 len = key_len(fh->fh_fsid_type) / 4;
148 if (len == 0) goto out; 144 if (len == 0) goto out;
149 if (fh->fh_fsid_type == 2) { 145 if (fh->fh_fsid_type == FSID_MAJOR_MINOR) {
150 /* deprecated, convert to type 3 */ 146 /* deprecated, convert to type 3 */
151 len = 3; 147 len = key_len(FSID_ENCODE_DEV)/4;
152 fh->fh_fsid_type = 3; 148 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]))); 149 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]; 150 fh->fh_fsid[1] = fh->fh_fsid[2];
155 } 151 }
@@ -164,8 +160,9 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
164 /* assume old filehandle format */ 160 /* assume old filehandle format */
165 xdev = old_decode_dev(fh->ofh_xdev); 161 xdev = old_decode_dev(fh->ofh_xdev);
166 xino = u32_to_ino_t(fh->ofh_xino); 162 xino = u32_to_ino_t(fh->ofh_xino);
167 mk_fsid_v0(tfh, xdev, xino); 163 mk_fsid(FSID_DEV, tfh, xdev, xino, 0, NULL);
168 exp = exp_find(rqstp->rq_client, 0, tfh, &rqstp->rq_chandle); 164 exp = exp_find(rqstp->rq_client, FSID_DEV, tfh,
165 &rqstp->rq_chandle);
169 } 166 }
170 167
171 if (IS_ERR(exp) && (PTR_ERR(exp) == -EAGAIN 168 if (IS_ERR(exp) && (PTR_ERR(exp) == -EAGAIN
@@ -212,7 +209,7 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
212 fileid_type = 2; 209 fileid_type = 2;
213 } else 210 } else
214 fileid_type = fh->fh_fileid_type; 211 fileid_type = fh->fh_fileid_type;
215 212
216 if (fileid_type == 0) 213 if (fileid_type == 0)
217 dentry = dget(exp->ex_dentry); 214 dentry = dget(exp->ex_dentry);
218 else { 215 else {
@@ -292,7 +289,7 @@ static inline int _fh_update(struct dentry *dentry, struct svc_export *exp,
292 __u32 *datap, int *maxsize) 289 __u32 *datap, int *maxsize)
293{ 290{
294 struct export_operations *nop = exp->ex_mnt->mnt_sb->s_export_op; 291 struct export_operations *nop = exp->ex_mnt->mnt_sb->s_export_op;
295 292
296 if (dentry == exp->ex_dentry) { 293 if (dentry == exp->ex_dentry) {
297 *maxsize = 0; 294 *maxsize = 0;
298 return 0; 295 return 0;
@@ -317,7 +314,8 @@ static inline void _fh_update_old(struct dentry *dentry,
317} 314}
318 315
319__be32 316__be32
320fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, struct svc_fh *ref_fh) 317fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry,
318 struct svc_fh *ref_fh)
321{ 319{
322 /* ref_fh is a reference file handle. 320 /* ref_fh is a reference file handle.
323 * if it is non-null and for the same filesystem, then we should compose 321 * if it is non-null and for the same filesystem, then we should compose
@@ -327,12 +325,13 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, st
327 * 325 *
328 */ 326 */
329 327
330 u8 ref_fh_version = 0; 328 u8 version = 1;
331 u8 ref_fh_fsid_type = 0; 329 u8 fsid_type = 0;
332 struct inode * inode = dentry->d_inode; 330 struct inode * inode = dentry->d_inode;
333 struct dentry *parent = dentry->d_parent; 331 struct dentry *parent = dentry->d_parent;
334 __u32 *datap; 332 __u32 *datap;
335 dev_t ex_dev = exp->ex_dentry->d_inode->i_sb->s_dev; 333 dev_t ex_dev = exp->ex_dentry->d_inode->i_sb->s_dev;
334 int root_export = (exp->ex_dentry == exp->ex_dentry->d_sb->s_root);
336 335
337 dprintk("nfsd: fh_compose(exp %02x:%02x/%ld %s/%s, ino=%ld)\n", 336 dprintk("nfsd: fh_compose(exp %02x:%02x/%ld %s/%s, ino=%ld)\n",
338 MAJOR(ex_dev), MINOR(ex_dev), 337 MAJOR(ex_dev), MINOR(ex_dev),
@@ -340,57 +339,64 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, st
340 parent->d_name.name, dentry->d_name.name, 339 parent->d_name.name, dentry->d_name.name,
341 (inode ? inode->i_ino : 0)); 340 (inode ? inode->i_ino : 0));
342 341
342 /* Choose filehandle version and fsid type based on
343 * the reference filehandle (if it is in the same export)
344 * or the export options.
345 */
343 if (ref_fh && ref_fh->fh_export == exp) { 346 if (ref_fh && ref_fh->fh_export == exp) {
344 ref_fh_version = ref_fh->fh_handle.fh_version; 347 version = ref_fh->fh_handle.fh_version;
345 if (ref_fh_version == 0xca) 348 if (version == 0xca)
346 ref_fh_fsid_type = 0; 349 fsid_type = FSID_DEV;
347 else 350 else
348 ref_fh_fsid_type = ref_fh->fh_handle.fh_fsid_type; 351 fsid_type = ref_fh->fh_handle.fh_fsid_type;
349 if (ref_fh_fsid_type > 3) 352 /* We know this version/type works for this export
350 ref_fh_fsid_type = 0; 353 * so there is no need for further checks.
351 354 */
352 /* make sure ref_fh type works for given export */ 355 } else if (exp->ex_uuid) {
353 if (ref_fh_fsid_type == 1 && 356 if (fhp->fh_maxsize >= 64) {
354 !(exp->ex_flags & NFSEXP_FSID)) { 357 if (root_export)
355 /* if we don't have an fsid, we cannot provide one... */ 358 fsid_type = FSID_UUID16;
356 ref_fh_fsid_type = 0; 359 else
360 fsid_type = FSID_UUID16_INUM;
361 } else {
362 if (root_export)
363 fsid_type = FSID_UUID8;
364 else
365 fsid_type = FSID_UUID4_INUM;
357 } 366 }
358 } else if (exp->ex_flags & NFSEXP_FSID) 367 } else if (exp->ex_flags & NFSEXP_FSID)
359 ref_fh_fsid_type = 1; 368 fsid_type = FSID_NUM;
360 369 else if (!old_valid_dev(ex_dev))
361 if (!old_valid_dev(ex_dev) && ref_fh_fsid_type == 0) {
362 /* for newer device numbers, we must use a newer fsid format */ 370 /* for newer device numbers, we must use a newer fsid format */
363 ref_fh_version = 1; 371 fsid_type = FSID_ENCODE_DEV;
364 ref_fh_fsid_type = 3; 372 else
365 } 373 fsid_type = FSID_DEV;
366 if (old_valid_dev(ex_dev) &&
367 (ref_fh_fsid_type == 2 || ref_fh_fsid_type == 3))
368 /* must use type1 for smaller device numbers */
369 ref_fh_fsid_type = 0;
370 374
371 if (ref_fh == fhp) 375 if (ref_fh == fhp)
372 fh_put(ref_fh); 376 fh_put(ref_fh);
373 377
374 if (fhp->fh_locked || fhp->fh_dentry) { 378 if (fhp->fh_locked || fhp->fh_dentry) {
375 printk(KERN_ERR "fh_compose: fh %s/%s not initialized!\n", 379 printk(KERN_ERR "fh_compose: fh %s/%s not initialized!\n",
376 parent->d_name.name, dentry->d_name.name); 380 parent->d_name.name, dentry->d_name.name);
377 } 381 }
378 if (fhp->fh_maxsize < NFS_FHSIZE) 382 if (fhp->fh_maxsize < NFS_FHSIZE)
379 printk(KERN_ERR "fh_compose: called with maxsize %d! %s/%s\n", 383 printk(KERN_ERR "fh_compose: called with maxsize %d! %s/%s\n",
380 fhp->fh_maxsize, parent->d_name.name, dentry->d_name.name); 384 fhp->fh_maxsize,
385 parent->d_name.name, dentry->d_name.name);
381 386
382 fhp->fh_dentry = dget(dentry); /* our internal copy */ 387 fhp->fh_dentry = dget(dentry); /* our internal copy */
383 fhp->fh_export = exp; 388 fhp->fh_export = exp;
384 cache_get(&exp->h); 389 cache_get(&exp->h);
385 390
386 if (ref_fh_version == 0xca) { 391 if (version == 0xca) {
387 /* old style filehandle please */ 392 /* old style filehandle please */
388 memset(&fhp->fh_handle.fh_base, 0, NFS_FHSIZE); 393 memset(&fhp->fh_handle.fh_base, 0, NFS_FHSIZE);
389 fhp->fh_handle.fh_size = NFS_FHSIZE; 394 fhp->fh_handle.fh_size = NFS_FHSIZE;
390 fhp->fh_handle.ofh_dcookie = 0xfeebbaca; 395 fhp->fh_handle.ofh_dcookie = 0xfeebbaca;
391 fhp->fh_handle.ofh_dev = old_encode_dev(ex_dev); 396 fhp->fh_handle.ofh_dev = old_encode_dev(ex_dev);
392 fhp->fh_handle.ofh_xdev = fhp->fh_handle.ofh_dev; 397 fhp->fh_handle.ofh_xdev = fhp->fh_handle.ofh_dev;
393 fhp->fh_handle.ofh_xino = ino_t_to_u32(exp->ex_dentry->d_inode->i_ino); 398 fhp->fh_handle.ofh_xino =
399 ino_t_to_u32(exp->ex_dentry->d_inode->i_ino);
394 fhp->fh_handle.ofh_dirino = ino_t_to_u32(parent_ino(dentry)); 400 fhp->fh_handle.ofh_dirino = ino_t_to_u32(parent_ino(dentry));
395 if (inode) 401 if (inode)
396 _fh_update_old(dentry, exp, &fhp->fh_handle); 402 _fh_update_old(dentry, exp, &fhp->fh_handle);
@@ -399,38 +405,12 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, st
399 fhp->fh_handle.fh_version = 1; 405 fhp->fh_handle.fh_version = 1;
400 fhp->fh_handle.fh_auth_type = 0; 406 fhp->fh_handle.fh_auth_type = 0;
401 datap = fhp->fh_handle.fh_auth+0; 407 datap = fhp->fh_handle.fh_auth+0;
402 fhp->fh_handle.fh_fsid_type = ref_fh_fsid_type; 408 fhp->fh_handle.fh_fsid_type = fsid_type;
403 switch (ref_fh_fsid_type) { 409 mk_fsid(fsid_type, datap, ex_dev,
404 case 0: 410 exp->ex_dentry->d_inode->i_ino,
405 /* 411 exp->ex_fsid, exp->ex_uuid);
406 * fsid_type 0: 412
407 * 2byte major, 2byte minor, 4byte inode 413 len = key_len(fsid_type);
408 */
409 mk_fsid_v0(datap, ex_dev,
410 exp->ex_dentry->d_inode->i_ino);
411 break;
412 case 1:
413 /* fsid_type 1 == 4 bytes filesystem id */
414 mk_fsid_v1(datap, exp->ex_fsid);
415 break;
416 case 2:
417 /*
418 * fsid_type 2:
419 * 4byte major, 4byte minor, 4byte inode
420 */
421 mk_fsid_v2(datap, ex_dev,
422 exp->ex_dentry->d_inode->i_ino);
423 break;
424 case 3:
425 /*
426 * fsid_type 3:
427 * 4byte devicenumber, 4byte inode
428 */
429 mk_fsid_v3(datap, ex_dev,
430 exp->ex_dentry->d_inode->i_ino);
431 break;
432 }
433 len = key_len(ref_fh_fsid_type);
434 datap += len/4; 414 datap += len/4;
435 fhp->fh_handle.fh_size = 4 + len; 415 fhp->fh_handle.fh_size = 4 + len;
436 416
@@ -457,7 +437,7 @@ fh_update(struct svc_fh *fhp)
457{ 437{
458 struct dentry *dentry; 438 struct dentry *dentry;
459 __u32 *datap; 439 __u32 *datap;
460 440
461 if (!fhp->fh_dentry) 441 if (!fhp->fh_dentry)
462 goto out_bad; 442 goto out_bad;
463 443
@@ -534,3 +514,22 @@ char * SVCFH_fmt(struct svc_fh *fhp)
534 fh->fh_base.fh_pad[5]); 514 fh->fh_base.fh_pad[5]);
535 return buf; 515 return buf;
536} 516}
517
518enum fsid_source fsid_source(struct svc_fh *fhp)
519{
520 if (fhp->fh_handle.fh_version != 1)
521 return FSIDSOURCE_DEV;
522 switch(fhp->fh_handle.fh_fsid_type) {
523 case FSID_DEV:
524 case FSID_ENCODE_DEV:
525 case FSID_MAJOR_MINOR:
526 return FSIDSOURCE_DEV;
527 case FSID_NUM:
528 return FSIDSOURCE_FSID;
529 default:
530 if (fhp->fh_export->ex_flags & NFSEXP_FSID)
531 return FSIDSOURCE_FSID;
532 else
533 return FSIDSOURCE_UUID;
534 }
535}