diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /fs/nfs/nfs3xdr.c | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'fs/nfs/nfs3xdr.c')
-rw-r--r-- | fs/nfs/nfs3xdr.c | 166 |
1 files changed, 59 insertions, 107 deletions
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index bffc32406fb..183c6b123d0 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c | |||
@@ -86,8 +86,6 @@ | |||
86 | XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE)) | 86 | XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE)) |
87 | #define ACL3_setaclres_sz (1+NFS3_post_op_attr_sz) | 87 | #define ACL3_setaclres_sz (1+NFS3_post_op_attr_sz) |
88 | 88 | ||
89 | static int nfs3_stat_to_errno(enum nfs_stat); | ||
90 | |||
91 | /* | 89 | /* |
92 | * Map file type to S_IFMT bits | 90 | * Map file type to S_IFMT bits |
93 | */ | 91 | */ |
@@ -198,7 +196,7 @@ static void encode_filename3(struct xdr_stream *xdr, | |||
198 | { | 196 | { |
199 | __be32 *p; | 197 | __be32 *p; |
200 | 198 | ||
201 | WARN_ON_ONCE(length > NFS3_MAXNAMLEN); | 199 | BUG_ON(length > NFS3_MAXNAMLEN); |
202 | p = xdr_reserve_space(xdr, 4 + length); | 200 | p = xdr_reserve_space(xdr, 4 + length); |
203 | xdr_encode_opaque(p, name, length); | 201 | xdr_encode_opaque(p, name, length); |
204 | } | 202 | } |
@@ -238,6 +236,7 @@ out_overflow: | |||
238 | static void encode_nfspath3(struct xdr_stream *xdr, struct page **pages, | 236 | static void encode_nfspath3(struct xdr_stream *xdr, struct page **pages, |
239 | const u32 length) | 237 | const u32 length) |
240 | { | 238 | { |
239 | BUG_ON(length > NFS3_MAXPATHLEN); | ||
241 | encode_uint32(xdr, length); | 240 | encode_uint32(xdr, length); |
242 | xdr_write_pages(xdr, pages, 0, length); | 241 | xdr_write_pages(xdr, pages, 0, length); |
243 | } | 242 | } |
@@ -245,6 +244,7 @@ static void encode_nfspath3(struct xdr_stream *xdr, struct page **pages, | |||
245 | static int decode_nfspath3(struct xdr_stream *xdr) | 244 | static int decode_nfspath3(struct xdr_stream *xdr) |
246 | { | 245 | { |
247 | u32 recvd, count; | 246 | u32 recvd, count; |
247 | size_t hdrlen; | ||
248 | __be32 *p; | 248 | __be32 *p; |
249 | 249 | ||
250 | p = xdr_inline_decode(xdr, 4); | 250 | p = xdr_inline_decode(xdr, 4); |
@@ -253,9 +253,12 @@ static int decode_nfspath3(struct xdr_stream *xdr) | |||
253 | count = be32_to_cpup(p); | 253 | count = be32_to_cpup(p); |
254 | if (unlikely(count >= xdr->buf->page_len || count > NFS3_MAXPATHLEN)) | 254 | if (unlikely(count >= xdr->buf->page_len || count > NFS3_MAXPATHLEN)) |
255 | goto out_nametoolong; | 255 | goto out_nametoolong; |
256 | recvd = xdr_read_pages(xdr, count); | 256 | hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base; |
257 | recvd = xdr->buf->len - hdrlen; | ||
257 | if (unlikely(count > recvd)) | 258 | if (unlikely(count > recvd)) |
258 | goto out_cheating; | 259 | goto out_cheating; |
260 | |||
261 | xdr_read_pages(xdr, count); | ||
259 | xdr_terminate_string(xdr->buf, count); | 262 | xdr_terminate_string(xdr->buf, count); |
260 | return 0; | 263 | return 0; |
261 | 264 | ||
@@ -324,14 +327,14 @@ static void encode_createverf3(struct xdr_stream *xdr, const __be32 *verifier) | |||
324 | memcpy(p, verifier, NFS3_CREATEVERFSIZE); | 327 | memcpy(p, verifier, NFS3_CREATEVERFSIZE); |
325 | } | 328 | } |
326 | 329 | ||
327 | static int decode_writeverf3(struct xdr_stream *xdr, struct nfs_write_verifier *verifier) | 330 | static int decode_writeverf3(struct xdr_stream *xdr, __be32 *verifier) |
328 | { | 331 | { |
329 | __be32 *p; | 332 | __be32 *p; |
330 | 333 | ||
331 | p = xdr_inline_decode(xdr, NFS3_WRITEVERFSIZE); | 334 | p = xdr_inline_decode(xdr, NFS3_WRITEVERFSIZE); |
332 | if (unlikely(p == NULL)) | 335 | if (unlikely(p == NULL)) |
333 | goto out_overflow; | 336 | goto out_overflow; |
334 | memcpy(verifier->data, p, NFS3_WRITEVERFSIZE); | 337 | memcpy(verifier, p, NFS3_WRITEVERFSIZE); |
335 | return 0; | 338 | return 0; |
336 | out_overflow: | 339 | out_overflow: |
337 | print_overflow_msg(__func__, xdr); | 340 | print_overflow_msg(__func__, xdr); |
@@ -387,6 +390,7 @@ out_overflow: | |||
387 | */ | 390 | */ |
388 | static void encode_ftype3(struct xdr_stream *xdr, const u32 type) | 391 | static void encode_ftype3(struct xdr_stream *xdr, const u32 type) |
389 | { | 392 | { |
393 | BUG_ON(type > NF3FIFO); | ||
390 | encode_uint32(xdr, type); | 394 | encode_uint32(xdr, type); |
391 | } | 395 | } |
392 | 396 | ||
@@ -441,7 +445,7 @@ static void encode_nfs_fh3(struct xdr_stream *xdr, const struct nfs_fh *fh) | |||
441 | { | 445 | { |
442 | __be32 *p; | 446 | __be32 *p; |
443 | 447 | ||
444 | WARN_ON_ONCE(fh->size > NFS3_FHSIZE); | 448 | BUG_ON(fh->size > NFS3_FHSIZE); |
445 | p = xdr_reserve_space(xdr, 4 + fh->size); | 449 | p = xdr_reserve_space(xdr, 4 + fh->size); |
446 | xdr_encode_opaque(p, fh->data, fh->size); | 450 | xdr_encode_opaque(p, fh->data, fh->size); |
447 | } | 451 | } |
@@ -671,7 +675,6 @@ static int decode_fattr3(struct xdr_stream *xdr, struct nfs_fattr *fattr) | |||
671 | p = xdr_decode_nfstime3(p, &fattr->atime); | 675 | p = xdr_decode_nfstime3(p, &fattr->atime); |
672 | p = xdr_decode_nfstime3(p, &fattr->mtime); | 676 | p = xdr_decode_nfstime3(p, &fattr->mtime); |
673 | xdr_decode_nfstime3(p, &fattr->ctime); | 677 | xdr_decode_nfstime3(p, &fattr->ctime); |
674 | fattr->change_attr = nfs_timespec_to_change_attr(&fattr->ctime); | ||
675 | 678 | ||
676 | fattr->valid |= NFS_ATTR_FATTR_V3; | 679 | fattr->valid |= NFS_ATTR_FATTR_V3; |
677 | return 0; | 680 | return 0; |
@@ -722,14 +725,12 @@ static int decode_wcc_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr) | |||
722 | goto out_overflow; | 725 | goto out_overflow; |
723 | 726 | ||
724 | fattr->valid |= NFS_ATTR_FATTR_PRESIZE | 727 | fattr->valid |= NFS_ATTR_FATTR_PRESIZE |
725 | | NFS_ATTR_FATTR_PRECHANGE | ||
726 | | NFS_ATTR_FATTR_PREMTIME | 728 | | NFS_ATTR_FATTR_PREMTIME |
727 | | NFS_ATTR_FATTR_PRECTIME; | 729 | | NFS_ATTR_FATTR_PRECTIME; |
728 | 730 | ||
729 | p = xdr_decode_size3(p, &fattr->pre_size); | 731 | p = xdr_decode_size3(p, &fattr->pre_size); |
730 | p = xdr_decode_nfstime3(p, &fattr->pre_mtime); | 732 | p = xdr_decode_nfstime3(p, &fattr->pre_mtime); |
731 | xdr_decode_nfstime3(p, &fattr->pre_ctime); | 733 | xdr_decode_nfstime3(p, &fattr->pre_ctime); |
732 | fattr->pre_change_attr = nfs_timespec_to_change_attr(&fattr->pre_ctime); | ||
733 | 734 | ||
734 | return 0; | 735 | return 0; |
735 | out_overflow: | 736 | out_overflow: |
@@ -1286,7 +1287,7 @@ static void nfs3_xdr_enc_readdirplus3args(struct rpc_rqst *req, | |||
1286 | * }; | 1287 | * }; |
1287 | */ | 1288 | */ |
1288 | static void encode_commit3args(struct xdr_stream *xdr, | 1289 | static void encode_commit3args(struct xdr_stream *xdr, |
1289 | const struct nfs_commitargs *args) | 1290 | const struct nfs_writeargs *args) |
1290 | { | 1291 | { |
1291 | __be32 *p; | 1292 | __be32 *p; |
1292 | 1293 | ||
@@ -1299,7 +1300,7 @@ static void encode_commit3args(struct xdr_stream *xdr, | |||
1299 | 1300 | ||
1300 | static void nfs3_xdr_enc_commit3args(struct rpc_rqst *req, | 1301 | static void nfs3_xdr_enc_commit3args(struct rpc_rqst *req, |
1301 | struct xdr_stream *xdr, | 1302 | struct xdr_stream *xdr, |
1302 | const struct nfs_commitargs *args) | 1303 | const struct nfs_writeargs *args) |
1303 | { | 1304 | { |
1304 | encode_commit3args(xdr, args); | 1305 | encode_commit3args(xdr, args); |
1305 | } | 1306 | } |
@@ -1337,7 +1338,6 @@ static void nfs3_xdr_enc_setacl3args(struct rpc_rqst *req, | |||
1337 | error = nfsacl_encode(xdr->buf, base, args->inode, | 1338 | error = nfsacl_encode(xdr->buf, base, args->inode, |
1338 | (args->mask & NFS_ACL) ? | 1339 | (args->mask & NFS_ACL) ? |
1339 | args->acl_access : NULL, 1, 0); | 1340 | args->acl_access : NULL, 1, 0); |
1340 | /* FIXME: this is just broken */ | ||
1341 | BUG_ON(error < 0); | 1341 | BUG_ON(error < 0); |
1342 | error = nfsacl_encode(xdr->buf, base + error, args->inode, | 1342 | error = nfsacl_encode(xdr->buf, base + error, args->inode, |
1343 | (args->mask & NFS_DFACL) ? | 1343 | (args->mask & NFS_DFACL) ? |
@@ -1385,7 +1385,7 @@ static int nfs3_xdr_dec_getattr3res(struct rpc_rqst *req, | |||
1385 | out: | 1385 | out: |
1386 | return error; | 1386 | return error; |
1387 | out_default: | 1387 | out_default: |
1388 | return nfs3_stat_to_errno(status); | 1388 | return nfs_stat_to_errno(status); |
1389 | } | 1389 | } |
1390 | 1390 | ||
1391 | /* | 1391 | /* |
@@ -1424,7 +1424,7 @@ static int nfs3_xdr_dec_setattr3res(struct rpc_rqst *req, | |||
1424 | out: | 1424 | out: |
1425 | return error; | 1425 | return error; |
1426 | out_status: | 1426 | out_status: |
1427 | return nfs3_stat_to_errno(status); | 1427 | return nfs_stat_to_errno(status); |
1428 | } | 1428 | } |
1429 | 1429 | ||
1430 | /* | 1430 | /* |
@@ -1472,7 +1472,7 @@ out_default: | |||
1472 | error = decode_post_op_attr(xdr, result->dir_attr); | 1472 | error = decode_post_op_attr(xdr, result->dir_attr); |
1473 | if (unlikely(error)) | 1473 | if (unlikely(error)) |
1474 | goto out; | 1474 | goto out; |
1475 | return nfs3_stat_to_errno(status); | 1475 | return nfs_stat_to_errno(status); |
1476 | } | 1476 | } |
1477 | 1477 | ||
1478 | /* | 1478 | /* |
@@ -1513,7 +1513,7 @@ static int nfs3_xdr_dec_access3res(struct rpc_rqst *req, | |||
1513 | out: | 1513 | out: |
1514 | return error; | 1514 | return error; |
1515 | out_default: | 1515 | out_default: |
1516 | return nfs3_stat_to_errno(status); | 1516 | return nfs_stat_to_errno(status); |
1517 | } | 1517 | } |
1518 | 1518 | ||
1519 | /* | 1519 | /* |
@@ -1554,7 +1554,7 @@ static int nfs3_xdr_dec_readlink3res(struct rpc_rqst *req, | |||
1554 | out: | 1554 | out: |
1555 | return error; | 1555 | return error; |
1556 | out_default: | 1556 | out_default: |
1557 | return nfs3_stat_to_errno(status); | 1557 | return nfs_stat_to_errno(status); |
1558 | } | 1558 | } |
1559 | 1559 | ||
1560 | /* | 1560 | /* |
@@ -1582,6 +1582,7 @@ static int decode_read3resok(struct xdr_stream *xdr, | |||
1582 | struct nfs_readres *result) | 1582 | struct nfs_readres *result) |
1583 | { | 1583 | { |
1584 | u32 eof, count, ocount, recvd; | 1584 | u32 eof, count, ocount, recvd; |
1585 | size_t hdrlen; | ||
1585 | __be32 *p; | 1586 | __be32 *p; |
1586 | 1587 | ||
1587 | p = xdr_inline_decode(xdr, 4 + 4 + 4); | 1588 | p = xdr_inline_decode(xdr, 4 + 4 + 4); |
@@ -1592,10 +1593,13 @@ static int decode_read3resok(struct xdr_stream *xdr, | |||
1592 | ocount = be32_to_cpup(p++); | 1593 | ocount = be32_to_cpup(p++); |
1593 | if (unlikely(ocount != count)) | 1594 | if (unlikely(ocount != count)) |
1594 | goto out_mismatch; | 1595 | goto out_mismatch; |
1595 | recvd = xdr_read_pages(xdr, count); | 1596 | hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base; |
1597 | recvd = xdr->buf->len - hdrlen; | ||
1596 | if (unlikely(count > recvd)) | 1598 | if (unlikely(count > recvd)) |
1597 | goto out_cheating; | 1599 | goto out_cheating; |
1600 | |||
1598 | out: | 1601 | out: |
1602 | xdr_read_pages(xdr, count); | ||
1599 | result->eof = eof; | 1603 | result->eof = eof; |
1600 | result->count = count; | 1604 | result->count = count; |
1601 | return count; | 1605 | return count; |
@@ -1632,7 +1636,7 @@ static int nfs3_xdr_dec_read3res(struct rpc_rqst *req, struct xdr_stream *xdr, | |||
1632 | out: | 1636 | out: |
1633 | return error; | 1637 | return error; |
1634 | out_status: | 1638 | out_status: |
1635 | return nfs3_stat_to_errno(status); | 1639 | return nfs_stat_to_errno(status); |
1636 | } | 1640 | } |
1637 | 1641 | ||
1638 | /* | 1642 | /* |
@@ -1667,22 +1671,20 @@ static int decode_write3resok(struct xdr_stream *xdr, | |||
1667 | { | 1671 | { |
1668 | __be32 *p; | 1672 | __be32 *p; |
1669 | 1673 | ||
1670 | p = xdr_inline_decode(xdr, 4 + 4); | 1674 | p = xdr_inline_decode(xdr, 4 + 4 + NFS3_WRITEVERFSIZE); |
1671 | if (unlikely(p == NULL)) | 1675 | if (unlikely(p == NULL)) |
1672 | goto out_overflow; | 1676 | goto out_overflow; |
1673 | result->count = be32_to_cpup(p++); | 1677 | result->count = be32_to_cpup(p++); |
1674 | result->verf->committed = be32_to_cpup(p++); | 1678 | result->verf->committed = be32_to_cpup(p++); |
1675 | if (unlikely(result->verf->committed > NFS_FILE_SYNC)) | 1679 | if (unlikely(result->verf->committed > NFS_FILE_SYNC)) |
1676 | goto out_badvalue; | 1680 | goto out_badvalue; |
1677 | if (decode_writeverf3(xdr, &result->verf->verifier)) | 1681 | memcpy(result->verf->verifier, p, NFS3_WRITEVERFSIZE); |
1678 | goto out_eio; | ||
1679 | return result->count; | 1682 | return result->count; |
1680 | out_badvalue: | 1683 | out_badvalue: |
1681 | dprintk("NFS: bad stable_how value: %u\n", result->verf->committed); | 1684 | dprintk("NFS: bad stable_how value: %u\n", result->verf->committed); |
1682 | return -EIO; | 1685 | return -EIO; |
1683 | out_overflow: | 1686 | out_overflow: |
1684 | print_overflow_msg(__func__, xdr); | 1687 | print_overflow_msg(__func__, xdr); |
1685 | out_eio: | ||
1686 | return -EIO; | 1688 | return -EIO; |
1687 | } | 1689 | } |
1688 | 1690 | ||
@@ -1704,7 +1706,7 @@ static int nfs3_xdr_dec_write3res(struct rpc_rqst *req, struct xdr_stream *xdr, | |||
1704 | out: | 1706 | out: |
1705 | return error; | 1707 | return error; |
1706 | out_status: | 1708 | out_status: |
1707 | return nfs3_stat_to_errno(status); | 1709 | return nfs_stat_to_errno(status); |
1708 | } | 1710 | } |
1709 | 1711 | ||
1710 | /* | 1712 | /* |
@@ -1768,7 +1770,7 @@ out_default: | |||
1768 | error = decode_wcc_data(xdr, result->dir_attr); | 1770 | error = decode_wcc_data(xdr, result->dir_attr); |
1769 | if (unlikely(error)) | 1771 | if (unlikely(error)) |
1770 | goto out; | 1772 | goto out; |
1771 | return nfs3_stat_to_errno(status); | 1773 | return nfs_stat_to_errno(status); |
1772 | } | 1774 | } |
1773 | 1775 | ||
1774 | /* | 1776 | /* |
@@ -1807,7 +1809,7 @@ static int nfs3_xdr_dec_remove3res(struct rpc_rqst *req, | |||
1807 | out: | 1809 | out: |
1808 | return error; | 1810 | return error; |
1809 | out_status: | 1811 | out_status: |
1810 | return nfs3_stat_to_errno(status); | 1812 | return nfs_stat_to_errno(status); |
1811 | } | 1813 | } |
1812 | 1814 | ||
1813 | /* | 1815 | /* |
@@ -1851,7 +1853,7 @@ static int nfs3_xdr_dec_rename3res(struct rpc_rqst *req, | |||
1851 | out: | 1853 | out: |
1852 | return error; | 1854 | return error; |
1853 | out_status: | 1855 | out_status: |
1854 | return nfs3_stat_to_errno(status); | 1856 | return nfs_stat_to_errno(status); |
1855 | } | 1857 | } |
1856 | 1858 | ||
1857 | /* | 1859 | /* |
@@ -1894,7 +1896,7 @@ static int nfs3_xdr_dec_link3res(struct rpc_rqst *req, struct xdr_stream *xdr, | |||
1894 | out: | 1896 | out: |
1895 | return error; | 1897 | return error; |
1896 | out_status: | 1898 | out_status: |
1897 | return nfs3_stat_to_errno(status); | 1899 | return nfs_stat_to_errno(status); |
1898 | } | 1900 | } |
1899 | 1901 | ||
1900 | /** | 1902 | /** |
@@ -2032,7 +2034,22 @@ out_truncated: | |||
2032 | */ | 2034 | */ |
2033 | static int decode_dirlist3(struct xdr_stream *xdr) | 2035 | static int decode_dirlist3(struct xdr_stream *xdr) |
2034 | { | 2036 | { |
2035 | return xdr_read_pages(xdr, xdr->buf->page_len); | 2037 | u32 recvd, pglen; |
2038 | size_t hdrlen; | ||
2039 | |||
2040 | pglen = xdr->buf->page_len; | ||
2041 | hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base; | ||
2042 | recvd = xdr->buf->len - hdrlen; | ||
2043 | if (unlikely(pglen > recvd)) | ||
2044 | goto out_cheating; | ||
2045 | out: | ||
2046 | xdr_read_pages(xdr, pglen); | ||
2047 | return pglen; | ||
2048 | out_cheating: | ||
2049 | dprintk("NFS: server cheating in readdir result: " | ||
2050 | "pglen %u > recvd %u\n", pglen, recvd); | ||
2051 | pglen = recvd; | ||
2052 | goto out; | ||
2036 | } | 2053 | } |
2037 | 2054 | ||
2038 | static int decode_readdir3resok(struct xdr_stream *xdr, | 2055 | static int decode_readdir3resok(struct xdr_stream *xdr, |
@@ -2071,7 +2088,7 @@ out_default: | |||
2071 | error = decode_post_op_attr(xdr, result->dir_attr); | 2088 | error = decode_post_op_attr(xdr, result->dir_attr); |
2072 | if (unlikely(error)) | 2089 | if (unlikely(error)) |
2073 | goto out; | 2090 | goto out; |
2074 | return nfs3_stat_to_errno(status); | 2091 | return nfs_stat_to_errno(status); |
2075 | } | 2092 | } |
2076 | 2093 | ||
2077 | /* | 2094 | /* |
@@ -2139,7 +2156,7 @@ static int nfs3_xdr_dec_fsstat3res(struct rpc_rqst *req, | |||
2139 | out: | 2156 | out: |
2140 | return error; | 2157 | return error; |
2141 | out_status: | 2158 | out_status: |
2142 | return nfs3_stat_to_errno(status); | 2159 | return nfs_stat_to_errno(status); |
2143 | } | 2160 | } |
2144 | 2161 | ||
2145 | /* | 2162 | /* |
@@ -2215,7 +2232,7 @@ static int nfs3_xdr_dec_fsinfo3res(struct rpc_rqst *req, | |||
2215 | out: | 2232 | out: |
2216 | return error; | 2233 | return error; |
2217 | out_status: | 2234 | out_status: |
2218 | return nfs3_stat_to_errno(status); | 2235 | return nfs_stat_to_errno(status); |
2219 | } | 2236 | } |
2220 | 2237 | ||
2221 | /* | 2238 | /* |
@@ -2278,7 +2295,7 @@ static int nfs3_xdr_dec_pathconf3res(struct rpc_rqst *req, | |||
2278 | out: | 2295 | out: |
2279 | return error; | 2296 | return error; |
2280 | out_status: | 2297 | out_status: |
2281 | return nfs3_stat_to_errno(status); | 2298 | return nfs_stat_to_errno(status); |
2282 | } | 2299 | } |
2283 | 2300 | ||
2284 | /* | 2301 | /* |
@@ -2302,7 +2319,7 @@ out_status: | |||
2302 | */ | 2319 | */ |
2303 | static int nfs3_xdr_dec_commit3res(struct rpc_rqst *req, | 2320 | static int nfs3_xdr_dec_commit3res(struct rpc_rqst *req, |
2304 | struct xdr_stream *xdr, | 2321 | struct xdr_stream *xdr, |
2305 | struct nfs_commitres *result) | 2322 | struct nfs_writeres *result) |
2306 | { | 2323 | { |
2307 | enum nfs_stat status; | 2324 | enum nfs_stat status; |
2308 | int error; | 2325 | int error; |
@@ -2315,11 +2332,11 @@ static int nfs3_xdr_dec_commit3res(struct rpc_rqst *req, | |||
2315 | goto out; | 2332 | goto out; |
2316 | if (status != NFS3_OK) | 2333 | if (status != NFS3_OK) |
2317 | goto out_status; | 2334 | goto out_status; |
2318 | error = decode_writeverf3(xdr, &result->verf->verifier); | 2335 | error = decode_writeverf3(xdr, result->verf->verifier); |
2319 | out: | 2336 | out: |
2320 | return error; | 2337 | return error; |
2321 | out_status: | 2338 | out_status: |
2322 | return nfs3_stat_to_errno(status); | 2339 | return nfs_stat_to_errno(status); |
2323 | } | 2340 | } |
2324 | 2341 | ||
2325 | #ifdef CONFIG_NFS_V3_ACL | 2342 | #ifdef CONFIG_NFS_V3_ACL |
@@ -2342,7 +2359,7 @@ static inline int decode_getacl3resok(struct xdr_stream *xdr, | |||
2342 | if (result->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT)) | 2359 | if (result->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT)) |
2343 | goto out; | 2360 | goto out; |
2344 | 2361 | ||
2345 | hdrlen = xdr_stream_pos(xdr); | 2362 | hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base; |
2346 | 2363 | ||
2347 | acl = NULL; | 2364 | acl = NULL; |
2348 | if (result->mask & NFS_ACL) | 2365 | if (result->mask & NFS_ACL) |
@@ -2384,7 +2401,7 @@ static int nfs3_xdr_dec_getacl3res(struct rpc_rqst *req, | |||
2384 | out: | 2401 | out: |
2385 | return error; | 2402 | return error; |
2386 | out_default: | 2403 | out_default: |
2387 | return nfs3_stat_to_errno(status); | 2404 | return nfs_stat_to_errno(status); |
2388 | } | 2405 | } |
2389 | 2406 | ||
2390 | static int nfs3_xdr_dec_setacl3res(struct rpc_rqst *req, | 2407 | static int nfs3_xdr_dec_setacl3res(struct rpc_rqst *req, |
@@ -2403,76 +2420,11 @@ static int nfs3_xdr_dec_setacl3res(struct rpc_rqst *req, | |||
2403 | out: | 2420 | out: |
2404 | return error; | 2421 | return error; |
2405 | out_default: | 2422 | out_default: |
2406 | return nfs3_stat_to_errno(status); | 2423 | return nfs_stat_to_errno(status); |
2407 | } | 2424 | } |
2408 | 2425 | ||
2409 | #endif /* CONFIG_NFS_V3_ACL */ | 2426 | #endif /* CONFIG_NFS_V3_ACL */ |
2410 | 2427 | ||
2411 | |||
2412 | /* | ||
2413 | * We need to translate between nfs status return values and | ||
2414 | * the local errno values which may not be the same. | ||
2415 | */ | ||
2416 | static const struct { | ||
2417 | int stat; | ||
2418 | int errno; | ||
2419 | } nfs_errtbl[] = { | ||
2420 | { NFS_OK, 0 }, | ||
2421 | { NFSERR_PERM, -EPERM }, | ||
2422 | { NFSERR_NOENT, -ENOENT }, | ||
2423 | { NFSERR_IO, -errno_NFSERR_IO}, | ||
2424 | { NFSERR_NXIO, -ENXIO }, | ||
2425 | /* { NFSERR_EAGAIN, -EAGAIN }, */ | ||
2426 | { NFSERR_ACCES, -EACCES }, | ||
2427 | { NFSERR_EXIST, -EEXIST }, | ||
2428 | { NFSERR_XDEV, -EXDEV }, | ||
2429 | { NFSERR_NODEV, -ENODEV }, | ||
2430 | { NFSERR_NOTDIR, -ENOTDIR }, | ||
2431 | { NFSERR_ISDIR, -EISDIR }, | ||
2432 | { NFSERR_INVAL, -EINVAL }, | ||
2433 | { NFSERR_FBIG, -EFBIG }, | ||
2434 | { NFSERR_NOSPC, -ENOSPC }, | ||
2435 | { NFSERR_ROFS, -EROFS }, | ||
2436 | { NFSERR_MLINK, -EMLINK }, | ||
2437 | { NFSERR_NAMETOOLONG, -ENAMETOOLONG }, | ||
2438 | { NFSERR_NOTEMPTY, -ENOTEMPTY }, | ||
2439 | { NFSERR_DQUOT, -EDQUOT }, | ||
2440 | { NFSERR_STALE, -ESTALE }, | ||
2441 | { NFSERR_REMOTE, -EREMOTE }, | ||
2442 | #ifdef EWFLUSH | ||
2443 | { NFSERR_WFLUSH, -EWFLUSH }, | ||
2444 | #endif | ||
2445 | { NFSERR_BADHANDLE, -EBADHANDLE }, | ||
2446 | { NFSERR_NOT_SYNC, -ENOTSYNC }, | ||
2447 | { NFSERR_BAD_COOKIE, -EBADCOOKIE }, | ||
2448 | { NFSERR_NOTSUPP, -ENOTSUPP }, | ||
2449 | { NFSERR_TOOSMALL, -ETOOSMALL }, | ||
2450 | { NFSERR_SERVERFAULT, -EREMOTEIO }, | ||
2451 | { NFSERR_BADTYPE, -EBADTYPE }, | ||
2452 | { NFSERR_JUKEBOX, -EJUKEBOX }, | ||
2453 | { -1, -EIO } | ||
2454 | }; | ||
2455 | |||
2456 | /** | ||
2457 | * nfs3_stat_to_errno - convert an NFS status code to a local errno | ||
2458 | * @status: NFS status code to convert | ||
2459 | * | ||
2460 | * Returns a local errno value, or -EIO if the NFS status code is | ||
2461 | * not recognized. This function is used jointly by NFSv2 and NFSv3. | ||
2462 | */ | ||
2463 | static int nfs3_stat_to_errno(enum nfs_stat status) | ||
2464 | { | ||
2465 | int i; | ||
2466 | |||
2467 | for (i = 0; nfs_errtbl[i].stat != -1; i++) { | ||
2468 | if (nfs_errtbl[i].stat == (int)status) | ||
2469 | return nfs_errtbl[i].errno; | ||
2470 | } | ||
2471 | dprintk("NFS: Unrecognized nfs status value: %u\n", status); | ||
2472 | return nfs_errtbl[i].errno; | ||
2473 | } | ||
2474 | |||
2475 | |||
2476 | #define PROC(proc, argtype, restype, timer) \ | 2428 | #define PROC(proc, argtype, restype, timer) \ |
2477 | [NFS3PROC_##proc] = { \ | 2429 | [NFS3PROC_##proc] = { \ |
2478 | .p_proc = NFS3PROC_##proc, \ | 2430 | .p_proc = NFS3PROC_##proc, \ |
@@ -2509,7 +2461,7 @@ struct rpc_procinfo nfs3_procedures[] = { | |||
2509 | PROC(COMMIT, commit, commit, 5), | 2461 | PROC(COMMIT, commit, commit, 5), |
2510 | }; | 2462 | }; |
2511 | 2463 | ||
2512 | const struct rpc_version nfs_version3 = { | 2464 | struct rpc_version nfs_version3 = { |
2513 | .number = 3, | 2465 | .number = 3, |
2514 | .nrprocs = ARRAY_SIZE(nfs3_procedures), | 2466 | .nrprocs = ARRAY_SIZE(nfs3_procedures), |
2515 | .procs = nfs3_procedures | 2467 | .procs = nfs3_procedures |
@@ -2537,7 +2489,7 @@ static struct rpc_procinfo nfs3_acl_procedures[] = { | |||
2537 | }, | 2489 | }, |
2538 | }; | 2490 | }; |
2539 | 2491 | ||
2540 | const struct rpc_version nfsacl_version3 = { | 2492 | struct rpc_version nfsacl_version3 = { |
2541 | .number = 3, | 2493 | .number = 3, |
2542 | .nrprocs = sizeof(nfs3_acl_procedures)/ | 2494 | .nrprocs = sizeof(nfs3_acl_procedures)/ |
2543 | sizeof(nfs3_acl_procedures[0]), | 2495 | sizeof(nfs3_acl_procedures[0]), |