diff options
Diffstat (limited to 'fs/nfsd/nfsfh.c')
-rw-r--r-- | fs/nfsd/nfsfh.c | 124 |
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 |
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 | /* 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 | ||