diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-03-04 18:13:56 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-03-06 10:32:46 -0500 |
commit | ea9d23f51041036b5d5d062dae2fafe0f670449c (patch) | |
tree | deda0b22af68a64d4817dc4430898605d354d532 /fs | |
parent | cb17e556f6202c200d38a2e0c05a5bd29060389f (diff) |
NFSv4: Add a helper for encoding stateids
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfs/nfs4xdr.c | 113 |
1 files changed, 62 insertions, 51 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index de4cb5cfc318..c03ba77679ad 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -928,6 +928,11 @@ static void encode_nops(struct compound_hdr *hdr) | |||
928 | *hdr->nops_p = htonl(hdr->nops); | 928 | *hdr->nops_p = htonl(hdr->nops); |
929 | } | 929 | } |
930 | 930 | ||
931 | static void encode_nfs4_stateid(struct xdr_stream *xdr, const nfs4_stateid *stateid) | ||
932 | { | ||
933 | encode_opaque_fixed(xdr, stateid->data, NFS4_STATEID_SIZE); | ||
934 | } | ||
935 | |||
931 | static void encode_nfs4_verifier(struct xdr_stream *xdr, const nfs4_verifier *verf) | 936 | static void encode_nfs4_verifier(struct xdr_stream *xdr, const nfs4_verifier *verf) |
932 | { | 937 | { |
933 | encode_opaque_fixed(xdr, verf->data, NFS4_VERIFIER_SIZE); | 938 | encode_opaque_fixed(xdr, verf->data, NFS4_VERIFIER_SIZE); |
@@ -1070,10 +1075,10 @@ static void encode_close(struct xdr_stream *xdr, const struct nfs_closeargs *arg | |||
1070 | { | 1075 | { |
1071 | __be32 *p; | 1076 | __be32 *p; |
1072 | 1077 | ||
1073 | p = reserve_space(xdr, 8+NFS4_STATEID_SIZE); | 1078 | p = reserve_space(xdr, 8); |
1074 | *p++ = cpu_to_be32(OP_CLOSE); | 1079 | *p++ = cpu_to_be32(OP_CLOSE); |
1075 | *p++ = cpu_to_be32(arg->seqid->sequence->counter); | 1080 | *p = cpu_to_be32(arg->seqid->sequence->counter); |
1076 | xdr_encode_opaque_fixed(p, arg->stateid->data, NFS4_STATEID_SIZE); | 1081 | encode_nfs4_stateid(xdr, arg->stateid); |
1077 | hdr->nops++; | 1082 | hdr->nops++; |
1078 | hdr->replen += decode_close_maxsz; | 1083 | hdr->replen += decode_close_maxsz; |
1079 | } | 1084 | } |
@@ -1260,15 +1265,16 @@ static void encode_lock(struct xdr_stream *xdr, const struct nfs_lock_args *args | |||
1260 | p = xdr_encode_hyper(p, nfs4_lock_length(args->fl)); | 1265 | p = xdr_encode_hyper(p, nfs4_lock_length(args->fl)); |
1261 | *p = cpu_to_be32(args->new_lock_owner); | 1266 | *p = cpu_to_be32(args->new_lock_owner); |
1262 | if (args->new_lock_owner){ | 1267 | if (args->new_lock_owner){ |
1263 | p = reserve_space(xdr, 4+NFS4_STATEID_SIZE+4); | 1268 | p = reserve_space(xdr, 4); |
1264 | *p++ = cpu_to_be32(args->open_seqid->sequence->counter); | 1269 | *p = cpu_to_be32(args->open_seqid->sequence->counter); |
1265 | p = xdr_encode_opaque_fixed(p, args->open_stateid->data, NFS4_STATEID_SIZE); | 1270 | encode_nfs4_stateid(xdr, args->open_stateid); |
1266 | *p++ = cpu_to_be32(args->lock_seqid->sequence->counter); | 1271 | p = reserve_space(xdr, 4); |
1272 | *p = cpu_to_be32(args->lock_seqid->sequence->counter); | ||
1267 | encode_lockowner(xdr, &args->lock_owner); | 1273 | encode_lockowner(xdr, &args->lock_owner); |
1268 | } | 1274 | } |
1269 | else { | 1275 | else { |
1270 | p = reserve_space(xdr, NFS4_STATEID_SIZE+4); | 1276 | encode_nfs4_stateid(xdr, args->lock_stateid); |
1271 | p = xdr_encode_opaque_fixed(p, args->lock_stateid->data, NFS4_STATEID_SIZE); | 1277 | p = reserve_space(xdr, 4); |
1272 | *p = cpu_to_be32(args->lock_seqid->sequence->counter); | 1278 | *p = cpu_to_be32(args->lock_seqid->sequence->counter); |
1273 | } | 1279 | } |
1274 | hdr->nops++; | 1280 | hdr->nops++; |
@@ -1293,11 +1299,12 @@ static void encode_locku(struct xdr_stream *xdr, const struct nfs_locku_args *ar | |||
1293 | { | 1299 | { |
1294 | __be32 *p; | 1300 | __be32 *p; |
1295 | 1301 | ||
1296 | p = reserve_space(xdr, 12+NFS4_STATEID_SIZE+16); | 1302 | p = reserve_space(xdr, 12); |
1297 | *p++ = cpu_to_be32(OP_LOCKU); | 1303 | *p++ = cpu_to_be32(OP_LOCKU); |
1298 | *p++ = cpu_to_be32(nfs4_lock_type(args->fl, 0)); | 1304 | *p++ = cpu_to_be32(nfs4_lock_type(args->fl, 0)); |
1299 | *p++ = cpu_to_be32(args->seqid->sequence->counter); | 1305 | *p = cpu_to_be32(args->seqid->sequence->counter); |
1300 | p = xdr_encode_opaque_fixed(p, args->stateid->data, NFS4_STATEID_SIZE); | 1306 | encode_nfs4_stateid(xdr, args->stateid); |
1307 | p = reserve_space(xdr, 16); | ||
1301 | p = xdr_encode_hyper(p, args->fl->fl_start); | 1308 | p = xdr_encode_hyper(p, args->fl->fl_start); |
1302 | xdr_encode_hyper(p, nfs4_lock_length(args->fl)); | 1309 | xdr_encode_hyper(p, nfs4_lock_length(args->fl)); |
1303 | hdr->nops++; | 1310 | hdr->nops++; |
@@ -1457,9 +1464,9 @@ static inline void encode_claim_delegate_cur(struct xdr_stream *xdr, const struc | |||
1457 | { | 1464 | { |
1458 | __be32 *p; | 1465 | __be32 *p; |
1459 | 1466 | ||
1460 | p = reserve_space(xdr, 4+NFS4_STATEID_SIZE); | 1467 | p = reserve_space(xdr, 4); |
1461 | *p++ = cpu_to_be32(NFS4_OPEN_CLAIM_DELEGATE_CUR); | 1468 | *p = cpu_to_be32(NFS4_OPEN_CLAIM_DELEGATE_CUR); |
1462 | xdr_encode_opaque_fixed(p, stateid->data, NFS4_STATEID_SIZE); | 1469 | encode_nfs4_stateid(xdr, stateid); |
1463 | encode_string(xdr, name->len, name->name); | 1470 | encode_string(xdr, name->len, name->name); |
1464 | } | 1471 | } |
1465 | 1472 | ||
@@ -1488,9 +1495,10 @@ static void encode_open_confirm(struct xdr_stream *xdr, const struct nfs_open_co | |||
1488 | { | 1495 | { |
1489 | __be32 *p; | 1496 | __be32 *p; |
1490 | 1497 | ||
1491 | p = reserve_space(xdr, 4+NFS4_STATEID_SIZE+4); | 1498 | p = reserve_space(xdr, 4); |
1492 | *p++ = cpu_to_be32(OP_OPEN_CONFIRM); | 1499 | *p = cpu_to_be32(OP_OPEN_CONFIRM); |
1493 | p = xdr_encode_opaque_fixed(p, arg->stateid->data, NFS4_STATEID_SIZE); | 1500 | encode_nfs4_stateid(xdr, arg->stateid); |
1501 | p = reserve_space(xdr, 4); | ||
1494 | *p = cpu_to_be32(arg->seqid->sequence->counter); | 1502 | *p = cpu_to_be32(arg->seqid->sequence->counter); |
1495 | hdr->nops++; | 1503 | hdr->nops++; |
1496 | hdr->replen += decode_open_confirm_maxsz; | 1504 | hdr->replen += decode_open_confirm_maxsz; |
@@ -1500,9 +1508,10 @@ static void encode_open_downgrade(struct xdr_stream *xdr, const struct nfs_close | |||
1500 | { | 1508 | { |
1501 | __be32 *p; | 1509 | __be32 *p; |
1502 | 1510 | ||
1503 | p = reserve_space(xdr, 4+NFS4_STATEID_SIZE+4); | 1511 | p = reserve_space(xdr, 4); |
1504 | *p++ = cpu_to_be32(OP_OPEN_DOWNGRADE); | 1512 | *p = cpu_to_be32(OP_OPEN_DOWNGRADE); |
1505 | p = xdr_encode_opaque_fixed(p, arg->stateid->data, NFS4_STATEID_SIZE); | 1513 | encode_nfs4_stateid(xdr, arg->stateid); |
1514 | p = reserve_space(xdr, 4); | ||
1506 | *p = cpu_to_be32(arg->seqid->sequence->counter); | 1515 | *p = cpu_to_be32(arg->seqid->sequence->counter); |
1507 | encode_share_access(xdr, arg->fmode); | 1516 | encode_share_access(xdr, arg->fmode); |
1508 | hdr->nops++; | 1517 | hdr->nops++; |
@@ -1535,16 +1544,14 @@ static void encode_putrootfh(struct xdr_stream *xdr, struct compound_hdr *hdr) | |||
1535 | static void encode_open_stateid(struct xdr_stream *xdr, const struct nfs_open_context *ctx, const struct nfs_lock_context *l_ctx, int zero_seqid) | 1544 | static void encode_open_stateid(struct xdr_stream *xdr, const struct nfs_open_context *ctx, const struct nfs_lock_context *l_ctx, int zero_seqid) |
1536 | { | 1545 | { |
1537 | nfs4_stateid stateid; | 1546 | nfs4_stateid stateid; |
1538 | __be32 *p; | ||
1539 | 1547 | ||
1540 | p = reserve_space(xdr, NFS4_STATEID_SIZE); | ||
1541 | if (ctx->state != NULL) { | 1548 | if (ctx->state != NULL) { |
1542 | nfs4_copy_stateid(&stateid, ctx->state, l_ctx->lockowner, l_ctx->pid); | 1549 | nfs4_copy_stateid(&stateid, ctx->state, l_ctx->lockowner, l_ctx->pid); |
1543 | if (zero_seqid) | 1550 | if (zero_seqid) |
1544 | stateid.stateid.seqid = 0; | 1551 | stateid.stateid.seqid = 0; |
1545 | xdr_encode_opaque_fixed(p, stateid.data, NFS4_STATEID_SIZE); | 1552 | encode_nfs4_stateid(xdr, &stateid); |
1546 | } else | 1553 | } else |
1547 | xdr_encode_opaque_fixed(p, zero_stateid.data, NFS4_STATEID_SIZE); | 1554 | encode_nfs4_stateid(xdr, &zero_stateid); |
1548 | } | 1555 | } |
1549 | 1556 | ||
1550 | static void encode_read(struct xdr_stream *xdr, const struct nfs_readargs *args, struct compound_hdr *hdr) | 1557 | static void encode_read(struct xdr_stream *xdr, const struct nfs_readargs *args, struct compound_hdr *hdr) |
@@ -1668,9 +1675,9 @@ encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg, struct compoun | |||
1668 | { | 1675 | { |
1669 | __be32 *p; | 1676 | __be32 *p; |
1670 | 1677 | ||
1671 | p = reserve_space(xdr, 4+NFS4_STATEID_SIZE); | 1678 | p = reserve_space(xdr, 4); |
1672 | *p++ = cpu_to_be32(OP_SETATTR); | 1679 | *p = cpu_to_be32(OP_SETATTR); |
1673 | xdr_encode_opaque_fixed(p, zero_stateid.data, NFS4_STATEID_SIZE); | 1680 | encode_nfs4_stateid(xdr, &zero_stateid); |
1674 | p = reserve_space(xdr, 2*4); | 1681 | p = reserve_space(xdr, 2*4); |
1675 | *p++ = cpu_to_be32(1); | 1682 | *p++ = cpu_to_be32(1); |
1676 | *p = cpu_to_be32(FATTR4_WORD0_ACL); | 1683 | *p = cpu_to_be32(FATTR4_WORD0_ACL); |
@@ -1697,9 +1704,9 @@ static void encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs | |||
1697 | { | 1704 | { |
1698 | __be32 *p; | 1705 | __be32 *p; |
1699 | 1706 | ||
1700 | p = reserve_space(xdr, 4+NFS4_STATEID_SIZE); | 1707 | p = reserve_space(xdr, 4); |
1701 | *p++ = cpu_to_be32(OP_SETATTR); | 1708 | *p = cpu_to_be32(OP_SETATTR); |
1702 | xdr_encode_opaque_fixed(p, arg->stateid.data, NFS4_STATEID_SIZE); | 1709 | encode_nfs4_stateid(xdr, &arg->stateid); |
1703 | hdr->nops++; | 1710 | hdr->nops++; |
1704 | hdr->replen += decode_setattr_maxsz; | 1711 | hdr->replen += decode_setattr_maxsz; |
1705 | encode_attrs(xdr, arg->iap, server); | 1712 | encode_attrs(xdr, arg->iap, server); |
@@ -1760,10 +1767,9 @@ static void encode_delegreturn(struct xdr_stream *xdr, const nfs4_stateid *state | |||
1760 | { | 1767 | { |
1761 | __be32 *p; | 1768 | __be32 *p; |
1762 | 1769 | ||
1763 | p = reserve_space(xdr, 4+NFS4_STATEID_SIZE); | 1770 | p = reserve_space(xdr, 4); |
1764 | 1771 | *p = cpu_to_be32(OP_DELEGRETURN); | |
1765 | *p++ = cpu_to_be32(OP_DELEGRETURN); | 1772 | encode_nfs4_stateid(xdr, stateid); |
1766 | xdr_encode_opaque_fixed(p, stateid->data, NFS4_STATEID_SIZE); | ||
1767 | hdr->nops++; | 1773 | hdr->nops++; |
1768 | hdr->replen += decode_delegreturn_maxsz; | 1774 | hdr->replen += decode_delegreturn_maxsz; |
1769 | } | 1775 | } |
@@ -1999,7 +2005,7 @@ encode_layoutget(struct xdr_stream *xdr, | |||
1999 | { | 2005 | { |
2000 | __be32 *p; | 2006 | __be32 *p; |
2001 | 2007 | ||
2002 | p = reserve_space(xdr, 44 + NFS4_STATEID_SIZE); | 2008 | p = reserve_space(xdr, 40); |
2003 | *p++ = cpu_to_be32(OP_LAYOUTGET); | 2009 | *p++ = cpu_to_be32(OP_LAYOUTGET); |
2004 | *p++ = cpu_to_be32(0); /* Signal layout available */ | 2010 | *p++ = cpu_to_be32(0); /* Signal layout available */ |
2005 | *p++ = cpu_to_be32(args->type); | 2011 | *p++ = cpu_to_be32(args->type); |
@@ -2007,7 +2013,8 @@ encode_layoutget(struct xdr_stream *xdr, | |||
2007 | p = xdr_encode_hyper(p, args->range.offset); | 2013 | p = xdr_encode_hyper(p, args->range.offset); |
2008 | p = xdr_encode_hyper(p, args->range.length); | 2014 | p = xdr_encode_hyper(p, args->range.length); |
2009 | p = xdr_encode_hyper(p, args->minlength); | 2015 | p = xdr_encode_hyper(p, args->minlength); |
2010 | p = xdr_encode_opaque_fixed(p, &args->stateid.data, NFS4_STATEID_SIZE); | 2016 | encode_nfs4_stateid(xdr, &args->stateid); |
2017 | p = reserve_space(xdr, 4); | ||
2011 | *p = cpu_to_be32(args->maxcount); | 2018 | *p = cpu_to_be32(args->maxcount); |
2012 | 2019 | ||
2013 | dprintk("%s: 1st type:0x%x iomode:%d off:%lu len:%lu mc:%d\n", | 2020 | dprintk("%s: 1st type:0x%x iomode:%d off:%lu len:%lu mc:%d\n", |
@@ -2032,13 +2039,14 @@ encode_layoutcommit(struct xdr_stream *xdr, | |||
2032 | dprintk("%s: lbw: %llu type: %d\n", __func__, args->lastbytewritten, | 2039 | dprintk("%s: lbw: %llu type: %d\n", __func__, args->lastbytewritten, |
2033 | NFS_SERVER(args->inode)->pnfs_curr_ld->id); | 2040 | NFS_SERVER(args->inode)->pnfs_curr_ld->id); |
2034 | 2041 | ||
2035 | p = reserve_space(xdr, 44 + NFS4_STATEID_SIZE); | 2042 | p = reserve_space(xdr, 24); |
2036 | *p++ = cpu_to_be32(OP_LAYOUTCOMMIT); | 2043 | *p++ = cpu_to_be32(OP_LAYOUTCOMMIT); |
2037 | /* Only whole file layouts */ | 2044 | /* Only whole file layouts */ |
2038 | p = xdr_encode_hyper(p, 0); /* offset */ | 2045 | p = xdr_encode_hyper(p, 0); /* offset */ |
2039 | p = xdr_encode_hyper(p, args->lastbytewritten + 1); /* length */ | 2046 | p = xdr_encode_hyper(p, args->lastbytewritten + 1); /* length */ |
2040 | *p++ = cpu_to_be32(0); /* reclaim */ | 2047 | *p = cpu_to_be32(0); /* reclaim */ |
2041 | p = xdr_encode_opaque_fixed(p, args->stateid.data, NFS4_STATEID_SIZE); | 2048 | encode_nfs4_stateid(xdr, &args->stateid); |
2049 | p = reserve_space(xdr, 20); | ||
2042 | *p++ = cpu_to_be32(1); /* newoffset = TRUE */ | 2050 | *p++ = cpu_to_be32(1); /* newoffset = TRUE */ |
2043 | p = xdr_encode_hyper(p, args->lastbytewritten); | 2051 | p = xdr_encode_hyper(p, args->lastbytewritten); |
2044 | *p++ = cpu_to_be32(0); /* Never send time_modify_changed */ | 2052 | *p++ = cpu_to_be32(0); /* Never send time_modify_changed */ |
@@ -2070,11 +2078,11 @@ encode_layoutreturn(struct xdr_stream *xdr, | |||
2070 | *p++ = cpu_to_be32(args->layout_type); | 2078 | *p++ = cpu_to_be32(args->layout_type); |
2071 | *p++ = cpu_to_be32(IOMODE_ANY); | 2079 | *p++ = cpu_to_be32(IOMODE_ANY); |
2072 | *p = cpu_to_be32(RETURN_FILE); | 2080 | *p = cpu_to_be32(RETURN_FILE); |
2073 | p = reserve_space(xdr, 16 + NFS4_STATEID_SIZE); | 2081 | p = reserve_space(xdr, 16); |
2074 | p = xdr_encode_hyper(p, 0); | 2082 | p = xdr_encode_hyper(p, 0); |
2075 | p = xdr_encode_hyper(p, NFS4_MAX_UINT64); | 2083 | p = xdr_encode_hyper(p, NFS4_MAX_UINT64); |
2076 | spin_lock(&args->inode->i_lock); | 2084 | spin_lock(&args->inode->i_lock); |
2077 | xdr_encode_opaque_fixed(p, &args->stateid.data, NFS4_STATEID_SIZE); | 2085 | encode_nfs4_stateid(xdr, &args->stateid); |
2078 | spin_unlock(&args->inode->i_lock); | 2086 | spin_unlock(&args->inode->i_lock); |
2079 | if (NFS_SERVER(args->inode)->pnfs_curr_ld->encode_layoutreturn) { | 2087 | if (NFS_SERVER(args->inode)->pnfs_curr_ld->encode_layoutreturn) { |
2080 | NFS_SERVER(args->inode)->pnfs_curr_ld->encode_layoutreturn( | 2088 | NFS_SERVER(args->inode)->pnfs_curr_ld->encode_layoutreturn( |
@@ -2107,10 +2115,10 @@ static void encode_test_stateid(struct xdr_stream *xdr, | |||
2107 | { | 2115 | { |
2108 | __be32 *p; | 2116 | __be32 *p; |
2109 | 2117 | ||
2110 | p = reserve_space(xdr, 8 + NFS4_STATEID_SIZE); | 2118 | p = reserve_space(xdr, 8); |
2111 | *p++ = cpu_to_be32(OP_TEST_STATEID); | 2119 | *p++ = cpu_to_be32(OP_TEST_STATEID); |
2112 | *p++ = cpu_to_be32(1); | 2120 | *p = cpu_to_be32(1); |
2113 | xdr_encode_opaque_fixed(p, args->stateid->data, NFS4_STATEID_SIZE); | 2121 | encode_nfs4_stateid(xdr, args->stateid); |
2114 | hdr->nops++; | 2122 | hdr->nops++; |
2115 | hdr->replen += decode_test_stateid_maxsz; | 2123 | hdr->replen += decode_test_stateid_maxsz; |
2116 | } | 2124 | } |
@@ -2120,9 +2128,9 @@ static void encode_free_stateid(struct xdr_stream *xdr, | |||
2120 | struct compound_hdr *hdr) | 2128 | struct compound_hdr *hdr) |
2121 | { | 2129 | { |
2122 | __be32 *p; | 2130 | __be32 *p; |
2123 | p = reserve_space(xdr, 4 + NFS4_STATEID_SIZE); | 2131 | p = reserve_space(xdr, 4); |
2124 | *p++ = cpu_to_be32(OP_FREE_STATEID); | 2132 | *p = cpu_to_be32(OP_FREE_STATEID); |
2125 | xdr_encode_opaque_fixed(p, args->stateid->data, NFS4_STATEID_SIZE); | 2133 | encode_nfs4_stateid(xdr, args->stateid); |
2126 | hdr->nops++; | 2134 | hdr->nops++; |
2127 | hdr->replen += decode_free_stateid_maxsz; | 2135 | hdr->replen += decode_free_stateid_maxsz; |
2128 | } | 2136 | } |
@@ -5640,11 +5648,14 @@ static int decode_layoutget(struct xdr_stream *xdr, struct rpc_rqst *req, | |||
5640 | status = decode_op_hdr(xdr, OP_LAYOUTGET); | 5648 | status = decode_op_hdr(xdr, OP_LAYOUTGET); |
5641 | if (status) | 5649 | if (status) |
5642 | return status; | 5650 | return status; |
5643 | p = xdr_inline_decode(xdr, 8 + NFS4_STATEID_SIZE); | 5651 | p = xdr_inline_decode(xdr, 4); |
5652 | if (unlikely(!p)) | ||
5653 | goto out_overflow; | ||
5654 | res->return_on_close = be32_to_cpup(p); | ||
5655 | decode_stateid(xdr, &res->stateid); | ||
5656 | p = xdr_inline_decode(xdr, 4); | ||
5644 | if (unlikely(!p)) | 5657 | if (unlikely(!p)) |
5645 | goto out_overflow; | 5658 | goto out_overflow; |
5646 | res->return_on_close = be32_to_cpup(p++); | ||
5647 | p = xdr_decode_opaque_fixed(p, res->stateid.data, NFS4_STATEID_SIZE); | ||
5648 | layout_count = be32_to_cpup(p); | 5659 | layout_count = be32_to_cpup(p); |
5649 | if (!layout_count) { | 5660 | if (!layout_count) { |
5650 | dprintk("%s: server responded with empty layout array\n", | 5661 | dprintk("%s: server responded with empty layout array\n", |