aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2007-02-14 03:33:11 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-14 11:09:53 -0500
commit982aedfd091e6d9831216f8519f12242091be4fd (patch)
tree88dd7b785c86f29ad68d6a116d39a037d64929d0
parent8971a1016b9db4164c3c1b47ae1fde2818becf91 (diff)
[PATCH] knfsd: tidy up choice of filesystem-identifier when creating a filehandle
If we are using the same version/fsid as a current filehandle, then there is no need to verify the the numbers are valid for this export, and they must be (we used them to find this export). This allows us to simplify the fsid selection code. Also change "ref_fh_version" and "ref_fh_fsid_type" to "version" and "fsid_type", as the important thing isn't that they are the version/type of the reference filehandle, but they are the chosen type for the new filehandle. And tidy up some indenting. 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>
-rw-r--r--fs/nfsd/nfsfh.c124
1 files changed, 60 insertions, 64 deletions
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index a0b4282cb284..12c5e7421374 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -212,7 +212,7 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
212 fileid_type = 2; 212 fileid_type = 2;
213 } else 213 } else
214 fileid_type = fh->fh_fileid_type; 214 fileid_type = fh->fh_fileid_type;
215 215
216 if (fileid_type == 0) 216 if (fileid_type == 0)
217 dentry = dget(exp->ex_dentry); 217 dentry = dget(exp->ex_dentry);
218 else { 218 else {
@@ -292,7 +292,7 @@ static inline int _fh_update(struct dentry *dentry, struct svc_export *exp,
292 __u32 *datap, int *maxsize) 292 __u32 *datap, int *maxsize)
293{ 293{
294 struct export_operations *nop = exp->ex_mnt->mnt_sb->s_export_op; 294 struct export_operations *nop = exp->ex_mnt->mnt_sb->s_export_op;
295 295
296 if (dentry == exp->ex_dentry) { 296 if (dentry == exp->ex_dentry) {
297 *maxsize = 0; 297 *maxsize = 0;
298 return 0; 298 return 0;
@@ -317,7 +317,8 @@ static inline void _fh_update_old(struct dentry *dentry,
317} 317}
318 318
319__be32 319__be32
320fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, struct svc_fh *ref_fh) 320fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry,
321 struct svc_fh *ref_fh)
321{ 322{
322 /* ref_fh is a reference file handle. 323 /* ref_fh is a reference file handle.
323 * if it is non-null and for the same filesystem, then we should compose 324 * if it is non-null and for the same filesystem, then we should compose
@@ -327,8 +328,8 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, st
327 * 328 *
328 */ 329 */
329 330
330 u8 ref_fh_version = 0; 331 u8 version = 1;
331 u8 ref_fh_fsid_type = 0; 332 u8 fsid_type = 0;
332 struct inode * inode = dentry->d_inode; 333 struct inode * inode = dentry->d_inode;
333 struct dentry *parent = dentry->d_parent; 334 struct dentry *parent = dentry->d_parent;
334 __u32 *datap; 335 __u32 *datap;
@@ -340,57 +341,52 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, st
340 parent->d_name.name, dentry->d_name.name, 341 parent->d_name.name, dentry->d_name.name,
341 (inode ? inode->i_ino : 0)); 342 (inode ? inode->i_ino : 0));
342 343
344 /* Choose filehandle version and fsid type based on
345 * the reference filehandle (if it is in the same export)
346 * or the export options.
347 */
343 if (ref_fh && ref_fh->fh_export == exp) { 348 if (ref_fh && ref_fh->fh_export == exp) {
344 ref_fh_version = ref_fh->fh_handle.fh_version; 349 version = ref_fh->fh_handle.fh_version;
345 if (ref_fh_version == 0xca) 350 if (version == 0xca)
346 ref_fh_fsid_type = 0; 351 fsid_type = 0;
347 else 352 else
348 ref_fh_fsid_type = ref_fh->fh_handle.fh_fsid_type; 353 fsid_type = ref_fh->fh_handle.fh_fsid_type;
349 if (ref_fh_fsid_type > 3) 354 /* We know this version/type works for this export
350 ref_fh_fsid_type = 0; 355 * so there is no need for further checks.
351 356 */
352 /* make sure ref_fh type works for given export */
353 if (ref_fh_fsid_type == 1 &&
354 !(exp->ex_flags & NFSEXP_FSID)) {
355 /* if we don't have an fsid, we cannot provide one... */
356 ref_fh_fsid_type = 0;
357 }
358 } else if (exp->ex_flags & NFSEXP_FSID) 357 } else if (exp->ex_flags & NFSEXP_FSID)
359 ref_fh_fsid_type = 1; 358 fsid_type = 1;
360 359 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 */ 360 /* for newer device numbers, we must use a newer fsid format */
363 ref_fh_version = 1; 361 fsid_type = 3;
364 ref_fh_fsid_type = 3; 362 else
365 } 363 fsid_type = 0;
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 364
371 if (ref_fh == fhp) 365 if (ref_fh == fhp)
372 fh_put(ref_fh); 366 fh_put(ref_fh);
373 367
374 if (fhp->fh_locked || fhp->fh_dentry) { 368 if (fhp->fh_locked || fhp->fh_dentry) {
375 printk(KERN_ERR "fh_compose: fh %s/%s not initialized!\n", 369 printk(KERN_ERR "fh_compose: fh %s/%s not initialized!\n",
376 parent->d_name.name, dentry->d_name.name); 370 parent->d_name.name, dentry->d_name.name);
377 } 371 }
378 if (fhp->fh_maxsize < NFS_FHSIZE) 372 if (fhp->fh_maxsize < NFS_FHSIZE)
379 printk(KERN_ERR "fh_compose: called with maxsize %d! %s/%s\n", 373 printk(KERN_ERR "fh_compose: called with maxsize %d! %s/%s\n",
380 fhp->fh_maxsize, parent->d_name.name, dentry->d_name.name); 374 fhp->fh_maxsize,
375 parent->d_name.name, dentry->d_name.name);
381 376
382 fhp->fh_dentry = dget(dentry); /* our internal copy */ 377 fhp->fh_dentry = dget(dentry); /* our internal copy */
383 fhp->fh_export = exp; 378 fhp->fh_export = exp;
384 cache_get(&exp->h); 379 cache_get(&exp->h);
385 380
386 if (ref_fh_version == 0xca) { 381 if (version == 0xca) {
387 /* old style filehandle please */ 382 /* old style filehandle please */
388 memset(&fhp->fh_handle.fh_base, 0, NFS_FHSIZE); 383 memset(&fhp->fh_handle.fh_base, 0, NFS_FHSIZE);
389 fhp->fh_handle.fh_size = NFS_FHSIZE; 384 fhp->fh_handle.fh_size = NFS_FHSIZE;
390 fhp->fh_handle.ofh_dcookie = 0xfeebbaca; 385 fhp->fh_handle.ofh_dcookie = 0xfeebbaca;
391 fhp->fh_handle.ofh_dev = old_encode_dev(ex_dev); 386 fhp->fh_handle.ofh_dev = old_encode_dev(ex_dev);
392 fhp->fh_handle.ofh_xdev = fhp->fh_handle.ofh_dev; 387 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); 388 fhp->fh_handle.ofh_xino =
389 ino_t_to_u32(exp->ex_dentry->d_inode->i_ino);
394 fhp->fh_handle.ofh_dirino = ino_t_to_u32(parent_ino(dentry)); 390 fhp->fh_handle.ofh_dirino = ino_t_to_u32(parent_ino(dentry));
395 if (inode) 391 if (inode)
396 _fh_update_old(dentry, exp, &fhp->fh_handle); 392 _fh_update_old(dentry, exp, &fhp->fh_handle);
@@ -399,38 +395,38 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, st
399 fhp->fh_handle.fh_version = 1; 395 fhp->fh_handle.fh_version = 1;
400 fhp->fh_handle.fh_auth_type = 0; 396 fhp->fh_handle.fh_auth_type = 0;
401 datap = fhp->fh_handle.fh_auth+0; 397 datap = fhp->fh_handle.fh_auth+0;
402 fhp->fh_handle.fh_fsid_type = ref_fh_fsid_type; 398 fhp->fh_handle.fh_fsid_type = fsid_type;
403 switch (ref_fh_fsid_type) { 399 switch (fsid_type) {
404 case 0: 400 case 0:
405 /* 401 /*
406 * fsid_type 0: 402 * fsid_type 0:
407 * 2byte major, 2byte minor, 4byte inode 403 * 2byte major, 2byte minor, 4byte inode
408 */ 404 */
409 mk_fsid_v0(datap, ex_dev, 405 mk_fsid_v0(datap, ex_dev,
410 exp->ex_dentry->d_inode->i_ino); 406 exp->ex_dentry->d_inode->i_ino);
411 break; 407 break;
412 case 1: 408 case 1:
413 /* fsid_type 1 == 4 bytes filesystem id */ 409 /* fsid_type 1 == 4 bytes filesystem id */
414 mk_fsid_v1(datap, exp->ex_fsid); 410 mk_fsid_v1(datap, exp->ex_fsid);
415 break; 411 break;
416 case 2: 412 case 2:
417 /* 413 /*
418 * fsid_type 2: 414 * fsid_type 2:
419 * 4byte major, 4byte minor, 4byte inode 415 * 4byte major, 4byte minor, 4byte inode
420 */ 416 */
421 mk_fsid_v2(datap, ex_dev, 417 mk_fsid_v2(datap, ex_dev,
422 exp->ex_dentry->d_inode->i_ino); 418 exp->ex_dentry->d_inode->i_ino);
423 break; 419 break;
424 case 3: 420 case 3:
425 /* 421 /*
426 * fsid_type 3: 422 * fsid_type 3:
427 * 4byte devicenumber, 4byte inode 423 * 4byte devicenumber, 4byte inode
428 */ 424 */
429 mk_fsid_v3(datap, ex_dev, 425 mk_fsid_v3(datap, ex_dev,
430 exp->ex_dentry->d_inode->i_ino); 426 exp->ex_dentry->d_inode->i_ino);
431 break; 427 break;
432 } 428 }
433 len = key_len(ref_fh_fsid_type); 429 len = key_len(fsid_type);
434 datap += len/4; 430 datap += len/4;
435 fhp->fh_handle.fh_size = 4 + len; 431 fhp->fh_handle.fh_size = 4 + len;
436 432
@@ -457,7 +453,7 @@ fh_update(struct svc_fh *fhp)
457{ 453{
458 struct dentry *dentry; 454 struct dentry *dentry;
459 __u32 *datap; 455 __u32 *datap;
460 456
461 if (!fhp->fh_dentry) 457 if (!fhp->fh_dentry)
462 goto out_bad; 458 goto out_bad;
463 459