aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-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