diff options
author | J.Bruce Fields <bfields@fieldses.org> | 2006-10-04 05:16:20 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-04 10:55:23 -0400 |
commit | 42ca09938157105c1f573c831a35e9c3e02eb354 (patch) | |
tree | 61533863e1adb46016015a347c70517ae9b10d3f /fs/nfsd/nfs4xdr.c | |
parent | 81c3f4130202a1dcb2b28ab56684eb5e9d43d8c1 (diff) |
[PATCH] knfsd: nfsd4: actually use all the pieces to implement referrals
Use all the pieces set up so far to implement referral support, allowing
return of NFS4ERR_MOVED and fs_locations attribute.
Signed-off-by: Manoj Naik <manoj@almaden.ibm.com>
Signed-off-by: Fred Isaman <iisaman@citi.umich.edu>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Signed-off-by: Neil Brown <neilb@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/nfsd/nfs4xdr.c')
-rw-r--r-- | fs/nfsd/nfs4xdr.c | 51 |
1 files changed, 45 insertions, 6 deletions
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 0589852007e6..41fc241b729a 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
@@ -60,6 +60,14 @@ | |||
60 | 60 | ||
61 | #define NFSDDBG_FACILITY NFSDDBG_XDR | 61 | #define NFSDDBG_FACILITY NFSDDBG_XDR |
62 | 62 | ||
63 | /* | ||
64 | * As per referral draft, the fsid for a referral MUST be different from the fsid of the containing | ||
65 | * directory in order to indicate to the client that a filesystem boundary is present | ||
66 | * We use a fixed fsid for a referral | ||
67 | */ | ||
68 | #define NFS4_REFERRAL_FSID_MAJOR 0x8000000ULL | ||
69 | #define NFS4_REFERRAL_FSID_MINOR 0x8000000ULL | ||
70 | |||
63 | static int | 71 | static int |
64 | check_filename(char *str, int len, int err) | 72 | check_filename(char *str, int len, int err) |
65 | { | 73 | { |
@@ -1385,6 +1393,25 @@ nfsd4_encode_aclname(struct svc_rqst *rqstp, int whotype, uid_t id, int group, | |||
1385 | return nfsd4_encode_name(rqstp, whotype, id, group, p, buflen); | 1393 | return nfsd4_encode_name(rqstp, whotype, id, group, p, buflen); |
1386 | } | 1394 | } |
1387 | 1395 | ||
1396 | #define WORD0_ABSENT_FS_ATTRS (FATTR4_WORD0_FS_LOCATIONS | FATTR4_WORD0_FSID | \ | ||
1397 | FATTR4_WORD0_RDATTR_ERROR) | ||
1398 | #define WORD1_ABSENT_FS_ATTRS FATTR4_WORD1_MOUNTED_ON_FILEID | ||
1399 | |||
1400 | static int fattr_handle_absent_fs(u32 *bmval0, u32 *bmval1, u32 *rdattr_err) | ||
1401 | { | ||
1402 | /* As per referral draft: */ | ||
1403 | if (*bmval0 & ~WORD0_ABSENT_FS_ATTRS || | ||
1404 | *bmval1 & ~WORD1_ABSENT_FS_ATTRS) { | ||
1405 | if (*bmval0 & FATTR4_WORD0_RDATTR_ERROR || | ||
1406 | *bmval0 & FATTR4_WORD0_FS_LOCATIONS) | ||
1407 | *rdattr_err = NFSERR_MOVED; | ||
1408 | else | ||
1409 | return nfserr_moved; | ||
1410 | } | ||
1411 | *bmval0 &= WORD0_ABSENT_FS_ATTRS; | ||
1412 | *bmval1 &= WORD1_ABSENT_FS_ATTRS; | ||
1413 | return 0; | ||
1414 | } | ||
1388 | 1415 | ||
1389 | /* | 1416 | /* |
1390 | * Note: @fhp can be NULL; in this case, we might have to compose the filehandle | 1417 | * Note: @fhp can be NULL; in this case, we might have to compose the filehandle |
@@ -1407,6 +1434,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, | |||
1407 | u32 *attrlenp; | 1434 | u32 *attrlenp; |
1408 | u32 dummy; | 1435 | u32 dummy; |
1409 | u64 dummy64; | 1436 | u64 dummy64; |
1437 | u32 rdattr_err = 0; | ||
1410 | u32 *p = buffer; | 1438 | u32 *p = buffer; |
1411 | int status; | 1439 | int status; |
1412 | int aclsupport = 0; | 1440 | int aclsupport = 0; |
@@ -1416,6 +1444,12 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, | |||
1416 | BUG_ON(bmval0 & ~NFSD_SUPPORTED_ATTRS_WORD0); | 1444 | BUG_ON(bmval0 & ~NFSD_SUPPORTED_ATTRS_WORD0); |
1417 | BUG_ON(bmval1 & ~NFSD_SUPPORTED_ATTRS_WORD1); | 1445 | BUG_ON(bmval1 & ~NFSD_SUPPORTED_ATTRS_WORD1); |
1418 | 1446 | ||
1447 | if (exp->ex_fslocs.migrated) { | ||
1448 | status = fattr_handle_absent_fs(&bmval0, &bmval1, &rdattr_err); | ||
1449 | if (status) | ||
1450 | goto out; | ||
1451 | } | ||
1452 | |||
1419 | status = vfs_getattr(exp->ex_mnt, dentry, &stat); | 1453 | status = vfs_getattr(exp->ex_mnt, dentry, &stat); |
1420 | if (status) | 1454 | if (status) |
1421 | goto out_nfserr; | 1455 | goto out_nfserr; |
@@ -1461,12 +1495,15 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, | |||
1461 | attrlenp = p++; /* to be backfilled later */ | 1495 | attrlenp = p++; /* to be backfilled later */ |
1462 | 1496 | ||
1463 | if (bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) { | 1497 | if (bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) { |
1498 | u32 word0 = NFSD_SUPPORTED_ATTRS_WORD0; | ||
1464 | if ((buflen -= 12) < 0) | 1499 | if ((buflen -= 12) < 0) |
1465 | goto out_resource; | 1500 | goto out_resource; |
1501 | if (!aclsupport) | ||
1502 | word0 &= ~FATTR4_WORD0_ACL; | ||
1503 | if (!exp->ex_fslocs.locations) | ||
1504 | word0 &= ~FATTR4_WORD0_FS_LOCATIONS; | ||
1466 | WRITE32(2); | 1505 | WRITE32(2); |
1467 | WRITE32(aclsupport ? | 1506 | WRITE32(word0); |
1468 | NFSD_SUPPORTED_ATTRS_WORD0 : | ||
1469 | NFSD_SUPPORTED_ATTRS_WORD0 & ~FATTR4_WORD0_ACL); | ||
1470 | WRITE32(NFSD_SUPPORTED_ATTRS_WORD1); | 1507 | WRITE32(NFSD_SUPPORTED_ATTRS_WORD1); |
1471 | } | 1508 | } |
1472 | if (bmval0 & FATTR4_WORD0_TYPE) { | 1509 | if (bmval0 & FATTR4_WORD0_TYPE) { |
@@ -1520,7 +1557,10 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, | |||
1520 | if (bmval0 & FATTR4_WORD0_FSID) { | 1557 | if (bmval0 & FATTR4_WORD0_FSID) { |
1521 | if ((buflen -= 16) < 0) | 1558 | if ((buflen -= 16) < 0) |
1522 | goto out_resource; | 1559 | goto out_resource; |
1523 | if (is_fsid(fhp, rqstp->rq_reffh)) { | 1560 | if (exp->ex_fslocs.migrated) { |
1561 | WRITE64(NFS4_REFERRAL_FSID_MAJOR); | ||
1562 | WRITE64(NFS4_REFERRAL_FSID_MINOR); | ||
1563 | } else if (is_fsid(fhp, rqstp->rq_reffh)) { | ||
1524 | WRITE64((u64)exp->ex_fsid); | 1564 | WRITE64((u64)exp->ex_fsid); |
1525 | WRITE64((u64)0); | 1565 | WRITE64((u64)0); |
1526 | } else { | 1566 | } else { |
@@ -1543,7 +1583,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, | |||
1543 | if (bmval0 & FATTR4_WORD0_RDATTR_ERROR) { | 1583 | if (bmval0 & FATTR4_WORD0_RDATTR_ERROR) { |
1544 | if ((buflen -= 4) < 0) | 1584 | if ((buflen -= 4) < 0) |
1545 | goto out_resource; | 1585 | goto out_resource; |
1546 | WRITE32(0); | 1586 | WRITE32(rdattr_err); |
1547 | } | 1587 | } |
1548 | if (bmval0 & FATTR4_WORD0_ACL) { | 1588 | if (bmval0 & FATTR4_WORD0_ACL) { |
1549 | struct nfs4_ace *ace; | 1589 | struct nfs4_ace *ace; |
@@ -1970,7 +2010,6 @@ nfsd4_encode_getattr(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_ge | |||
1970 | nfserr = nfsd4_encode_fattr(fhp, fhp->fh_export, fhp->fh_dentry, | 2010 | nfserr = nfsd4_encode_fattr(fhp, fhp->fh_export, fhp->fh_dentry, |
1971 | resp->p, &buflen, getattr->ga_bmval, | 2011 | resp->p, &buflen, getattr->ga_bmval, |
1972 | resp->rqstp); | 2012 | resp->rqstp); |
1973 | |||
1974 | if (!nfserr) | 2013 | if (!nfserr) |
1975 | resp->p += buflen; | 2014 | resp->p += buflen; |
1976 | return nfserr; | 2015 | return nfserr; |