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.c152
1 files changed, 76 insertions, 76 deletions
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index c59d6fbb7a6b..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>
@@ -20,6 +19,7 @@
20#include <linux/mount.h> 19#include <linux/mount.h>
21#include <asm/pgtable.h> 20#include <asm/pgtable.h>
22 21
22#include <linux/sunrpc/clnt.h>
23#include <linux/sunrpc/svc.h> 23#include <linux/sunrpc/svc.h>
24#include <linux/nfsd/nfsd.h> 24#include <linux/nfsd/nfsd.h>
25 25
@@ -118,9 +118,6 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
118 118
119 dprintk("nfsd: fh_verify(%s)\n", SVCFH_fmt(fhp)); 119 dprintk("nfsd: fh_verify(%s)\n", SVCFH_fmt(fhp));
120 120
121 /* keep this filehandle for possible reference when encoding attributes */
122 rqstp->rq_reffh = fh;
123
124 if (!fhp->fh_dentry) { 121 if (!fhp->fh_dentry) {
125 __u32 *datap=NULL; 122 __u32 *datap=NULL;
126 __u32 tfh[3]; /* filehandle fragment for oldstyle filehandles */ 123 __u32 tfh[3]; /* filehandle fragment for oldstyle filehandles */
@@ -145,10 +142,10 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
145 } 142 }
146 len = key_len(fh->fh_fsid_type) / 4; 143 len = key_len(fh->fh_fsid_type) / 4;
147 if (len == 0) goto out; 144 if (len == 0) goto out;
148 if (fh->fh_fsid_type == 2) { 145 if (fh->fh_fsid_type == FSID_MAJOR_MINOR) {
149 /* deprecated, convert to type 3 */ 146 /* deprecated, convert to type 3 */
150 len = 3; 147 len = key_len(FSID_ENCODE_DEV)/4;
151 fh->fh_fsid_type = 3; 148 fh->fh_fsid_type = FSID_ENCODE_DEV;
152 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])));
153 fh->fh_fsid[1] = fh->fh_fsid[2]; 150 fh->fh_fsid[1] = fh->fh_fsid[2];
154 } 151 }
@@ -163,8 +160,9 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
163 /* assume old filehandle format */ 160 /* assume old filehandle format */
164 xdev = old_decode_dev(fh->ofh_xdev); 161 xdev = old_decode_dev(fh->ofh_xdev);
165 xino = u32_to_ino_t(fh->ofh_xino); 162 xino = u32_to_ino_t(fh->ofh_xino);
166 mk_fsid_v0(tfh, xdev, xino); 163 mk_fsid(FSID_DEV, tfh, xdev, xino, 0, NULL);
167 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);
168 } 166 }
169 167
170 if (IS_ERR(exp) && (PTR_ERR(exp) == -EAGAIN 168 if (IS_ERR(exp) && (PTR_ERR(exp) == -EAGAIN
@@ -180,10 +178,10 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
180 /* Check if the request originated from a secure port. */ 178 /* Check if the request originated from a secure port. */
181 error = nfserr_perm; 179 error = nfserr_perm;
182 if (!rqstp->rq_secure && EX_SECURE(exp)) { 180 if (!rqstp->rq_secure && EX_SECURE(exp)) {
181 char buf[RPC_MAX_ADDRBUFLEN];
183 printk(KERN_WARNING 182 printk(KERN_WARNING
184 "nfsd: request from insecure port (%u.%u.%u.%u:%d)!\n", 183 "nfsd: request from insecure port %s!\n",
185 NIPQUAD(rqstp->rq_addr.sin_addr.s_addr), 184 svc_print_addr(rqstp, buf, sizeof(buf)));
186 ntohs(rqstp->rq_addr.sin_port));
187 goto out; 185 goto out;
188 } 186 }
189 187
@@ -211,7 +209,7 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
211 fileid_type = 2; 209 fileid_type = 2;
212 } else 210 } else
213 fileid_type = fh->fh_fileid_type; 211 fileid_type = fh->fh_fileid_type;
214 212
215 if (fileid_type == 0) 213 if (fileid_type == 0)
216 dentry = dget(exp->ex_dentry); 214 dentry = dget(exp->ex_dentry);
217 else { 215 else {
@@ -291,7 +289,7 @@ static inline int _fh_update(struct dentry *dentry, struct svc_export *exp,
291 __u32 *datap, int *maxsize) 289 __u32 *datap, int *maxsize)
292{ 290{
293 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;
294 292
295 if (dentry == exp->ex_dentry) { 293 if (dentry == exp->ex_dentry) {
296 *maxsize = 0; 294 *maxsize = 0;
297 return 0; 295 return 0;
@@ -316,7 +314,8 @@ static inline void _fh_update_old(struct dentry *dentry,
316} 314}
317 315
318__be32 316__be32
319fh_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)
320{ 319{
321 /* ref_fh is a reference file handle. 320 /* ref_fh is a reference file handle.
322 * 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
@@ -326,12 +325,13 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, st
326 * 325 *
327 */ 326 */
328 327
329 u8 ref_fh_version = 0; 328 u8 version = 1;
330 u8 ref_fh_fsid_type = 0; 329 u8 fsid_type = 0;
331 struct inode * inode = dentry->d_inode; 330 struct inode * inode = dentry->d_inode;
332 struct dentry *parent = dentry->d_parent; 331 struct dentry *parent = dentry->d_parent;
333 __u32 *datap; 332 __u32 *datap;
334 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);
335 335
336 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",
337 MAJOR(ex_dev), MINOR(ex_dev), 337 MAJOR(ex_dev), MINOR(ex_dev),
@@ -339,57 +339,64 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, st
339 parent->d_name.name, dentry->d_name.name, 339 parent->d_name.name, dentry->d_name.name,
340 (inode ? inode->i_ino : 0)); 340 (inode ? inode->i_ino : 0));
341 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 */
342 if (ref_fh && ref_fh->fh_export == exp) { 346 if (ref_fh && ref_fh->fh_export == exp) {
343 ref_fh_version = ref_fh->fh_handle.fh_version; 347 version = ref_fh->fh_handle.fh_version;
344 if (ref_fh_version == 0xca) 348 if (version == 0xca)
345 ref_fh_fsid_type = 0; 349 fsid_type = FSID_DEV;
346 else 350 else
347 ref_fh_fsid_type = ref_fh->fh_handle.fh_fsid_type; 351 fsid_type = ref_fh->fh_handle.fh_fsid_type;
348 if (ref_fh_fsid_type > 3) 352 /* We know this version/type works for this export
349 ref_fh_fsid_type = 0; 353 * so there is no need for further checks.
350 354 */
351 /* make sure ref_fh type works for given export */ 355 } else if (exp->ex_uuid) {
352 if (ref_fh_fsid_type == 1 && 356 if (fhp->fh_maxsize >= 64) {
353 !(exp->ex_flags & NFSEXP_FSID)) { 357 if (root_export)
354 /* if we don't have an fsid, we cannot provide one... */ 358 fsid_type = FSID_UUID16;
355 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;
356 } 366 }
357 } else if (exp->ex_flags & NFSEXP_FSID) 367 } else if (exp->ex_flags & NFSEXP_FSID)
358 ref_fh_fsid_type = 1; 368 fsid_type = FSID_NUM;
359 369 else if (!old_valid_dev(ex_dev))
360 if (!old_valid_dev(ex_dev) && ref_fh_fsid_type == 0) {
361 /* for newer device numbers, we must use a newer fsid format */ 370 /* for newer device numbers, we must use a newer fsid format */
362 ref_fh_version = 1; 371 fsid_type = FSID_ENCODE_DEV;
363 ref_fh_fsid_type = 3; 372 else
364 } 373 fsid_type = FSID_DEV;
365 if (old_valid_dev(ex_dev) &&
366 (ref_fh_fsid_type == 2 || ref_fh_fsid_type == 3))
367 /* must use type1 for smaller device numbers */
368 ref_fh_fsid_type = 0;
369 374
370 if (ref_fh == fhp) 375 if (ref_fh == fhp)
371 fh_put(ref_fh); 376 fh_put(ref_fh);
372 377
373 if (fhp->fh_locked || fhp->fh_dentry) { 378 if (fhp->fh_locked || fhp->fh_dentry) {
374 printk(KERN_ERR "fh_compose: fh %s/%s not initialized!\n", 379 printk(KERN_ERR "fh_compose: fh %s/%s not initialized!\n",
375 parent->d_name.name, dentry->d_name.name); 380 parent->d_name.name, dentry->d_name.name);
376 } 381 }
377 if (fhp->fh_maxsize < NFS_FHSIZE) 382 if (fhp->fh_maxsize < NFS_FHSIZE)
378 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",
379 fhp->fh_maxsize, parent->d_name.name, dentry->d_name.name); 384 fhp->fh_maxsize,
385 parent->d_name.name, dentry->d_name.name);
380 386
381 fhp->fh_dentry = dget(dentry); /* our internal copy */ 387 fhp->fh_dentry = dget(dentry); /* our internal copy */
382 fhp->fh_export = exp; 388 fhp->fh_export = exp;
383 cache_get(&exp->h); 389 cache_get(&exp->h);
384 390
385 if (ref_fh_version == 0xca) { 391 if (version == 0xca) {
386 /* old style filehandle please */ 392 /* old style filehandle please */
387 memset(&fhp->fh_handle.fh_base, 0, NFS_FHSIZE); 393 memset(&fhp->fh_handle.fh_base, 0, NFS_FHSIZE);
388 fhp->fh_handle.fh_size = NFS_FHSIZE; 394 fhp->fh_handle.fh_size = NFS_FHSIZE;
389 fhp->fh_handle.ofh_dcookie = 0xfeebbaca; 395 fhp->fh_handle.ofh_dcookie = 0xfeebbaca;
390 fhp->fh_handle.ofh_dev = old_encode_dev(ex_dev); 396 fhp->fh_handle.ofh_dev = old_encode_dev(ex_dev);
391 fhp->fh_handle.ofh_xdev = fhp->fh_handle.ofh_dev; 397 fhp->fh_handle.ofh_xdev = fhp->fh_handle.ofh_dev;
392 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);
393 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));
394 if (inode) 401 if (inode)
395 _fh_update_old(dentry, exp, &fhp->fh_handle); 402 _fh_update_old(dentry, exp, &fhp->fh_handle);
@@ -398,38 +405,12 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, st
398 fhp->fh_handle.fh_version = 1; 405 fhp->fh_handle.fh_version = 1;
399 fhp->fh_handle.fh_auth_type = 0; 406 fhp->fh_handle.fh_auth_type = 0;
400 datap = fhp->fh_handle.fh_auth+0; 407 datap = fhp->fh_handle.fh_auth+0;
401 fhp->fh_handle.fh_fsid_type = ref_fh_fsid_type; 408 fhp->fh_handle.fh_fsid_type = fsid_type;
402 switch (ref_fh_fsid_type) { 409 mk_fsid(fsid_type, datap, ex_dev,
403 case 0: 410 exp->ex_dentry->d_inode->i_ino,
404 /* 411 exp->ex_fsid, exp->ex_uuid);
405 * fsid_type 0: 412
406 * 2byte major, 2byte minor, 4byte inode 413 len = key_len(fsid_type);
407 */
408 mk_fsid_v0(datap, ex_dev,
409 exp->ex_dentry->d_inode->i_ino);
410 break;
411 case 1:
412 /* fsid_type 1 == 4 bytes filesystem id */
413 mk_fsid_v1(datap, exp->ex_fsid);
414 break;
415 case 2:
416 /*
417 * fsid_type 2:
418 * 4byte major, 4byte minor, 4byte inode
419 */
420 mk_fsid_v2(datap, ex_dev,
421 exp->ex_dentry->d_inode->i_ino);
422 break;
423 case 3:
424 /*
425 * fsid_type 3:
426 * 4byte devicenumber, 4byte inode
427 */
428 mk_fsid_v3(datap, ex_dev,
429 exp->ex_dentry->d_inode->i_ino);
430 break;
431 }
432 len = key_len(ref_fh_fsid_type);
433 datap += len/4; 414 datap += len/4;
434 fhp->fh_handle.fh_size = 4 + len; 415 fhp->fh_handle.fh_size = 4 + len;
435 416
@@ -456,7 +437,7 @@ fh_update(struct svc_fh *fhp)
456{ 437{
457 struct dentry *dentry; 438 struct dentry *dentry;
458 __u32 *datap; 439 __u32 *datap;
459 440
460 if (!fhp->fh_dentry) 441 if (!fhp->fh_dentry)
461 goto out_bad; 442 goto out_bad;
462 443
@@ -533,3 +514,22 @@ char * SVCFH_fmt(struct svc_fh *fhp)
533 fh->fh_base.fh_pad[5]); 514 fh->fh_base.fh_pad[5]);
534 return buf; 515 return buf;
535} 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}