Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

NeilBrown and committed by
Linus Torvalds
982aedfd 8971a101

+60 -64
+60 -64
fs/nfsd/nfsfh.c
··· 212 212 fileid_type = 2; 213 213 } else 214 214 fileid_type = fh->fh_fileid_type; 215 - 215 + 216 216 if (fileid_type == 0) 217 217 dentry = dget(exp->ex_dentry); 218 218 else { ··· 292 292 __u32 *datap, int *maxsize) 293 293 { 294 294 struct export_operations *nop = exp->ex_mnt->mnt_sb->s_export_op; 295 - 295 + 296 296 if (dentry == exp->ex_dentry) { 297 297 *maxsize = 0; 298 298 return 0; ··· 317 317 } 318 318 319 319 __be32 320 - fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, struct svc_fh *ref_fh) 320 + fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, 321 + struct svc_fh *ref_fh) 321 322 { 322 323 /* ref_fh is a reference file handle. 323 324 * if it is non-null and for the same filesystem, then we should compose ··· 328 327 * 329 328 */ 330 329 331 - u8 ref_fh_version = 0; 332 - u8 ref_fh_fsid_type = 0; 330 + u8 version = 1; 331 + u8 fsid_type = 0; 333 332 struct inode * inode = dentry->d_inode; 334 333 struct dentry *parent = dentry->d_parent; 335 334 __u32 *datap; ··· 341 340 parent->d_name.name, dentry->d_name.name, 342 341 (inode ? inode->i_ino : 0)); 343 342 343 + /* Choose filehandle version and fsid type based on 344 + * the reference filehandle (if it is in the same export) 345 + * or the export options. 346 + */ 344 347 if (ref_fh && ref_fh->fh_export == exp) { 345 - ref_fh_version = ref_fh->fh_handle.fh_version; 346 - if (ref_fh_version == 0xca) 347 - ref_fh_fsid_type = 0; 348 + version = ref_fh->fh_handle.fh_version; 349 + if (version == 0xca) 350 + fsid_type = 0; 348 351 else 349 - ref_fh_fsid_type = ref_fh->fh_handle.fh_fsid_type; 350 - if (ref_fh_fsid_type > 3) 351 - ref_fh_fsid_type = 0; 352 - 353 - /* make sure ref_fh type works for given export */ 354 - if (ref_fh_fsid_type == 1 && 355 - !(exp->ex_flags & NFSEXP_FSID)) { 356 - /* if we don't have an fsid, we cannot provide one... */ 357 - ref_fh_fsid_type = 0; 358 - } 352 + fsid_type = ref_fh->fh_handle.fh_fsid_type; 353 + /* We know this version/type works for this export 354 + * so there is no need for further checks. 355 + */ 359 356 } else if (exp->ex_flags & NFSEXP_FSID) 360 - ref_fh_fsid_type = 1; 361 - 362 - if (!old_valid_dev(ex_dev) && ref_fh_fsid_type == 0) { 357 + fsid_type = 1; 358 + else if (!old_valid_dev(ex_dev)) 363 359 /* for newer device numbers, we must use a newer fsid format */ 364 - ref_fh_version = 1; 365 - ref_fh_fsid_type = 3; 366 - } 367 - if (old_valid_dev(ex_dev) && 368 - (ref_fh_fsid_type == 2 || ref_fh_fsid_type == 3)) 369 - /* must use type1 for smaller device numbers */ 370 - ref_fh_fsid_type = 0; 360 + fsid_type = 3; 361 + else 362 + fsid_type = 0; 371 363 372 364 if (ref_fh == fhp) 373 365 fh_put(ref_fh); 374 366 375 367 if (fhp->fh_locked || fhp->fh_dentry) { 376 368 printk(KERN_ERR "fh_compose: fh %s/%s not initialized!\n", 377 - parent->d_name.name, dentry->d_name.name); 369 + parent->d_name.name, dentry->d_name.name); 378 370 } 379 371 if (fhp->fh_maxsize < NFS_FHSIZE) 380 372 printk(KERN_ERR "fh_compose: called with maxsize %d! %s/%s\n", 381 - fhp->fh_maxsize, parent->d_name.name, dentry->d_name.name); 373 + fhp->fh_maxsize, 374 + parent->d_name.name, dentry->d_name.name); 382 375 383 376 fhp->fh_dentry = dget(dentry); /* our internal copy */ 384 377 fhp->fh_export = exp; 385 378 cache_get(&exp->h); 386 379 387 - if (ref_fh_version == 0xca) { 380 + if (version == 0xca) { 388 381 /* old style filehandle please */ 389 382 memset(&fhp->fh_handle.fh_base, 0, NFS_FHSIZE); 390 383 fhp->fh_handle.fh_size = NFS_FHSIZE; 391 384 fhp->fh_handle.ofh_dcookie = 0xfeebbaca; 392 385 fhp->fh_handle.ofh_dev = old_encode_dev(ex_dev); 393 386 fhp->fh_handle.ofh_xdev = fhp->fh_handle.ofh_dev; 394 - fhp->fh_handle.ofh_xino = ino_t_to_u32(exp->ex_dentry->d_inode->i_ino); 387 + fhp->fh_handle.ofh_xino = 388 + ino_t_to_u32(exp->ex_dentry->d_inode->i_ino); 395 389 fhp->fh_handle.ofh_dirino = ino_t_to_u32(parent_ino(dentry)); 396 390 if (inode) 397 391 _fh_update_old(dentry, exp, &fhp->fh_handle); ··· 395 399 fhp->fh_handle.fh_version = 1; 396 400 fhp->fh_handle.fh_auth_type = 0; 397 401 datap = fhp->fh_handle.fh_auth+0; 398 - fhp->fh_handle.fh_fsid_type = ref_fh_fsid_type; 399 - switch (ref_fh_fsid_type) { 400 - case 0: 401 - /* 402 - * fsid_type 0: 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; 402 + fhp->fh_handle.fh_fsid_type = fsid_type; 403 + switch (fsid_type) { 404 + case 0: 405 + /* 406 + * fsid_type 0: 407 + * 2byte major, 2byte minor, 4byte inode 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; 428 432 } 429 - len = key_len(ref_fh_fsid_type); 433 + len = key_len(fsid_type); 430 434 datap += len/4; 431 435 fhp->fh_handle.fh_size = 4 + len; 432 436 ··· 453 457 { 454 458 struct dentry *dentry; 455 459 __u32 *datap; 456 - 460 + 457 461 if (!fhp->fh_dentry) 458 462 goto out_bad; 459 463