aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4xdr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4xdr.c')
-rw-r--r--fs/nfs/nfs4xdr.c187
1 files changed, 104 insertions, 83 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index fbbace8a30c4..4bbf5ef57785 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -392,9 +392,11 @@ static int nfs_stat_to_errno(int);
392 decode_getattr_maxsz) 392 decode_getattr_maxsz)
393#define NFS4_enc_delegreturn_sz (compound_encode_hdr_maxsz + \ 393#define NFS4_enc_delegreturn_sz (compound_encode_hdr_maxsz + \
394 encode_putfh_maxsz + \ 394 encode_putfh_maxsz + \
395 encode_delegreturn_maxsz) 395 encode_delegreturn_maxsz + \
396 encode_getattr_maxsz)
396#define NFS4_dec_delegreturn_sz (compound_decode_hdr_maxsz + \ 397#define NFS4_dec_delegreturn_sz (compound_decode_hdr_maxsz + \
397 decode_delegreturn_maxsz) 398 decode_delegreturn_maxsz + \
399 decode_getattr_maxsz)
398#define NFS4_enc_getacl_sz (compound_encode_hdr_maxsz + \ 400#define NFS4_enc_getacl_sz (compound_encode_hdr_maxsz + \
399 encode_putfh_maxsz + \ 401 encode_putfh_maxsz + \
400 encode_getattr_maxsz) 402 encode_getattr_maxsz)
@@ -564,7 +566,7 @@ static int encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const s
564 } 566 }
565 if (iap->ia_valid & ATTR_MODE) { 567 if (iap->ia_valid & ATTR_MODE) {
566 bmval1 |= FATTR4_WORD1_MODE; 568 bmval1 |= FATTR4_WORD1_MODE;
567 WRITE32(iap->ia_mode); 569 WRITE32(iap->ia_mode & S_IALLUGO);
568 } 570 }
569 if (iap->ia_valid & ATTR_UID) { 571 if (iap->ia_valid & ATTR_UID) {
570 bmval1 |= FATTR4_WORD1_OWNER; 572 bmval1 |= FATTR4_WORD1_OWNER;
@@ -742,69 +744,80 @@ static int encode_link(struct xdr_stream *xdr, const struct qstr *name)
742 return 0; 744 return 0;
743} 745}
744 746
747static inline int nfs4_lock_type(struct file_lock *fl, int block)
748{
749 if ((fl->fl_type & (F_RDLCK|F_WRLCK|F_UNLCK)) == F_RDLCK)
750 return block ? NFS4_READW_LT : NFS4_READ_LT;
751 return block ? NFS4_WRITEW_LT : NFS4_WRITE_LT;
752}
753
754static inline uint64_t nfs4_lock_length(struct file_lock *fl)
755{
756 if (fl->fl_end == OFFSET_MAX)
757 return ~(uint64_t)0;
758 return fl->fl_end - fl->fl_start + 1;
759}
760
745/* 761/*
746 * opcode,type,reclaim,offset,length,new_lock_owner = 32 762 * opcode,type,reclaim,offset,length,new_lock_owner = 32
747 * open_seqid,open_stateid,lock_seqid,lock_owner.clientid, lock_owner.id = 40 763 * open_seqid,open_stateid,lock_seqid,lock_owner.clientid, lock_owner.id = 40
748 */ 764 */
749static int encode_lock(struct xdr_stream *xdr, const struct nfs_lockargs *arg) 765static int encode_lock(struct xdr_stream *xdr, const struct nfs_lock_args *args)
750{ 766{
751 uint32_t *p; 767 uint32_t *p;
752 struct nfs_lock_opargs *opargs = arg->u.lock;
753 768
754 RESERVE_SPACE(32); 769 RESERVE_SPACE(32);
755 WRITE32(OP_LOCK); 770 WRITE32(OP_LOCK);
756 WRITE32(arg->type); 771 WRITE32(nfs4_lock_type(args->fl, args->block));
757 WRITE32(opargs->reclaim); 772 WRITE32(args->reclaim);
758 WRITE64(arg->offset); 773 WRITE64(args->fl->fl_start);
759 WRITE64(arg->length); 774 WRITE64(nfs4_lock_length(args->fl));
760 WRITE32(opargs->new_lock_owner); 775 WRITE32(args->new_lock_owner);
761 if (opargs->new_lock_owner){ 776 if (args->new_lock_owner){
762 RESERVE_SPACE(40); 777 RESERVE_SPACE(40);
763 WRITE32(opargs->open_seqid->sequence->counter); 778 WRITE32(args->open_seqid->sequence->counter);
764 WRITEMEM(opargs->open_stateid->data, sizeof(opargs->open_stateid->data)); 779 WRITEMEM(args->open_stateid->data, sizeof(args->open_stateid->data));
765 WRITE32(opargs->lock_seqid->sequence->counter); 780 WRITE32(args->lock_seqid->sequence->counter);
766 WRITE64(opargs->lock_owner.clientid); 781 WRITE64(args->lock_owner.clientid);
767 WRITE32(4); 782 WRITE32(4);
768 WRITE32(opargs->lock_owner.id); 783 WRITE32(args->lock_owner.id);
769 } 784 }
770 else { 785 else {
771 RESERVE_SPACE(20); 786 RESERVE_SPACE(20);
772 WRITEMEM(opargs->lock_stateid->data, sizeof(opargs->lock_stateid->data)); 787 WRITEMEM(args->lock_stateid->data, sizeof(args->lock_stateid->data));
773 WRITE32(opargs->lock_seqid->sequence->counter); 788 WRITE32(args->lock_seqid->sequence->counter);
774 } 789 }
775 790
776 return 0; 791 return 0;
777} 792}
778 793
779static int encode_lockt(struct xdr_stream *xdr, const struct nfs_lockargs *arg) 794static int encode_lockt(struct xdr_stream *xdr, const struct nfs_lockt_args *args)
780{ 795{
781 uint32_t *p; 796 uint32_t *p;
782 struct nfs_lowner *opargs = arg->u.lockt;
783 797
784 RESERVE_SPACE(40); 798 RESERVE_SPACE(40);
785 WRITE32(OP_LOCKT); 799 WRITE32(OP_LOCKT);
786 WRITE32(arg->type); 800 WRITE32(nfs4_lock_type(args->fl, 0));
787 WRITE64(arg->offset); 801 WRITE64(args->fl->fl_start);
788 WRITE64(arg->length); 802 WRITE64(nfs4_lock_length(args->fl));
789 WRITE64(opargs->clientid); 803 WRITE64(args->lock_owner.clientid);
790 WRITE32(4); 804 WRITE32(4);
791 WRITE32(opargs->id); 805 WRITE32(args->lock_owner.id);
792 806
793 return 0; 807 return 0;
794} 808}
795 809
796static int encode_locku(struct xdr_stream *xdr, const struct nfs_lockargs *arg) 810static int encode_locku(struct xdr_stream *xdr, const struct nfs_locku_args *args)
797{ 811{
798 uint32_t *p; 812 uint32_t *p;
799 struct nfs_locku_opargs *opargs = arg->u.locku;
800 813
801 RESERVE_SPACE(44); 814 RESERVE_SPACE(44);
802 WRITE32(OP_LOCKU); 815 WRITE32(OP_LOCKU);
803 WRITE32(arg->type); 816 WRITE32(nfs4_lock_type(args->fl, 0));
804 WRITE32(opargs->seqid->sequence->counter); 817 WRITE32(args->seqid->sequence->counter);
805 WRITEMEM(opargs->stateid->data, sizeof(opargs->stateid->data)); 818 WRITEMEM(args->stateid->data, sizeof(args->stateid->data));
806 WRITE64(arg->offset); 819 WRITE64(args->fl->fl_start);
807 WRITE64(arg->length); 820 WRITE64(nfs4_lock_length(args->fl));
808 821
809 return 0; 822 return 0;
810} 823}
@@ -964,9 +977,9 @@ static int encode_open_confirm(struct xdr_stream *xdr, const struct nfs_open_con
964{ 977{
965 uint32_t *p; 978 uint32_t *p;
966 979
967 RESERVE_SPACE(8+sizeof(arg->stateid.data)); 980 RESERVE_SPACE(8+sizeof(arg->stateid->data));
968 WRITE32(OP_OPEN_CONFIRM); 981 WRITE32(OP_OPEN_CONFIRM);
969 WRITEMEM(arg->stateid.data, sizeof(arg->stateid.data)); 982 WRITEMEM(arg->stateid->data, sizeof(arg->stateid->data));
970 WRITE32(arg->seqid->sequence->counter); 983 WRITE32(arg->seqid->sequence->counter);
971 984
972 return 0; 985 return 0;
@@ -1499,9 +1512,6 @@ static int nfs4_xdr_enc_open(struct rpc_rqst *req, uint32_t *p, struct nfs_opena
1499 }; 1512 };
1500 int status; 1513 int status;
1501 1514
1502 status = nfs_wait_on_sequence(args->seqid, req->rq_task);
1503 if (status != 0)
1504 goto out;
1505 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1515 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1506 encode_compound_hdr(&xdr, &hdr); 1516 encode_compound_hdr(&xdr, &hdr);
1507 status = encode_putfh(&xdr, args->fh); 1517 status = encode_putfh(&xdr, args->fh);
@@ -1538,9 +1548,6 @@ static int nfs4_xdr_enc_open_confirm(struct rpc_rqst *req, uint32_t *p, struct n
1538 }; 1548 };
1539 int status; 1549 int status;
1540 1550
1541 status = nfs_wait_on_sequence(args->seqid, req->rq_task);
1542 if (status != 0)
1543 goto out;
1544 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1551 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1545 encode_compound_hdr(&xdr, &hdr); 1552 encode_compound_hdr(&xdr, &hdr);
1546 status = encode_putfh(&xdr, args->fh); 1553 status = encode_putfh(&xdr, args->fh);
@@ -1558,19 +1565,19 @@ static int nfs4_xdr_enc_open_noattr(struct rpc_rqst *req, uint32_t *p, struct nf
1558{ 1565{
1559 struct xdr_stream xdr; 1566 struct xdr_stream xdr;
1560 struct compound_hdr hdr = { 1567 struct compound_hdr hdr = {
1561 .nops = 2, 1568 .nops = 3,
1562 }; 1569 };
1563 int status; 1570 int status;
1564 1571
1565 status = nfs_wait_on_sequence(args->seqid, req->rq_task);
1566 if (status != 0)
1567 goto out;
1568 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1572 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1569 encode_compound_hdr(&xdr, &hdr); 1573 encode_compound_hdr(&xdr, &hdr);
1570 status = encode_putfh(&xdr, args->fh); 1574 status = encode_putfh(&xdr, args->fh);
1571 if (status) 1575 if (status)
1572 goto out; 1576 goto out;
1573 status = encode_open(&xdr, args); 1577 status = encode_open(&xdr, args);
1578 if (status)
1579 goto out;
1580 status = encode_getfattr(&xdr, args->bitmask);
1574out: 1581out:
1575 return status; 1582 return status;
1576} 1583}
@@ -1602,21 +1609,14 @@ out:
1602/* 1609/*
1603 * Encode a LOCK request 1610 * Encode a LOCK request
1604 */ 1611 */
1605static int nfs4_xdr_enc_lock(struct rpc_rqst *req, uint32_t *p, struct nfs_lockargs *args) 1612static int nfs4_xdr_enc_lock(struct rpc_rqst *req, uint32_t *p, struct nfs_lock_args *args)
1606{ 1613{
1607 struct xdr_stream xdr; 1614 struct xdr_stream xdr;
1608 struct compound_hdr hdr = { 1615 struct compound_hdr hdr = {
1609 .nops = 2, 1616 .nops = 2,
1610 }; 1617 };
1611 struct nfs_lock_opargs *opargs = args->u.lock;
1612 int status; 1618 int status;
1613 1619
1614 status = nfs_wait_on_sequence(opargs->lock_seqid, req->rq_task);
1615 if (status != 0)
1616 goto out;
1617 /* Do we need to do an open_to_lock_owner? */
1618 if (opargs->lock_seqid->sequence->flags & NFS_SEQID_CONFIRMED)
1619 opargs->new_lock_owner = 0;
1620 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1620 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1621 encode_compound_hdr(&xdr, &hdr); 1621 encode_compound_hdr(&xdr, &hdr);
1622 status = encode_putfh(&xdr, args->fh); 1622 status = encode_putfh(&xdr, args->fh);
@@ -1630,7 +1630,7 @@ out:
1630/* 1630/*
1631 * Encode a LOCKT request 1631 * Encode a LOCKT request
1632 */ 1632 */
1633static int nfs4_xdr_enc_lockt(struct rpc_rqst *req, uint32_t *p, struct nfs_lockargs *args) 1633static int nfs4_xdr_enc_lockt(struct rpc_rqst *req, uint32_t *p, struct nfs_lockt_args *args)
1634{ 1634{
1635 struct xdr_stream xdr; 1635 struct xdr_stream xdr;
1636 struct compound_hdr hdr = { 1636 struct compound_hdr hdr = {
@@ -1651,7 +1651,7 @@ out:
1651/* 1651/*
1652 * Encode a LOCKU request 1652 * Encode a LOCKU request
1653 */ 1653 */
1654static int nfs4_xdr_enc_locku(struct rpc_rqst *req, uint32_t *p, struct nfs_lockargs *args) 1654static int nfs4_xdr_enc_locku(struct rpc_rqst *req, uint32_t *p, struct nfs_locku_args *args)
1655{ 1655{
1656 struct xdr_stream xdr; 1656 struct xdr_stream xdr;
1657 struct compound_hdr hdr = { 1657 struct compound_hdr hdr = {
@@ -1985,14 +1985,20 @@ static int nfs4_xdr_enc_delegreturn(struct rpc_rqst *req, uint32_t *p, const str
1985{ 1985{
1986 struct xdr_stream xdr; 1986 struct xdr_stream xdr;
1987 struct compound_hdr hdr = { 1987 struct compound_hdr hdr = {
1988 .nops = 2, 1988 .nops = 3,
1989 }; 1989 };
1990 int status; 1990 int status;
1991 1991
1992 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1992 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1993 encode_compound_hdr(&xdr, &hdr); 1993 encode_compound_hdr(&xdr, &hdr);
1994 if ((status = encode_putfh(&xdr, args->fhandle)) == 0) 1994 status = encode_putfh(&xdr, args->fhandle);
1995 status = encode_delegreturn(&xdr, args->stateid); 1995 if (status != 0)
1996 goto out;
1997 status = encode_delegreturn(&xdr, args->stateid);
1998 if (status != 0)
1999 goto out;
2000 status = encode_getfattr(&xdr, args->bitmask);
2001out:
1996 return status; 2002 return status;
1997} 2003}
1998 2004
@@ -2955,55 +2961,64 @@ static int decode_link(struct xdr_stream *xdr, struct nfs4_change_info *cinfo)
2955/* 2961/*
2956 * We create the owner, so we know a proper owner.id length is 4. 2962 * We create the owner, so we know a proper owner.id length is 4.
2957 */ 2963 */
2958static int decode_lock_denied (struct xdr_stream *xdr, struct nfs_lock_denied *denied) 2964static int decode_lock_denied (struct xdr_stream *xdr, struct file_lock *fl)
2959{ 2965{
2966 uint64_t offset, length, clientid;
2960 uint32_t *p; 2967 uint32_t *p;
2961 uint32_t namelen; 2968 uint32_t namelen, type;
2962 2969
2963 READ_BUF(32); 2970 READ_BUF(32);
2964 READ64(denied->offset); 2971 READ64(offset);
2965 READ64(denied->length); 2972 READ64(length);
2966 READ32(denied->type); 2973 READ32(type);
2967 READ64(denied->owner.clientid); 2974 if (fl != NULL) {
2975 fl->fl_start = (loff_t)offset;
2976 fl->fl_end = fl->fl_start + (loff_t)length - 1;
2977 if (length == ~(uint64_t)0)
2978 fl->fl_end = OFFSET_MAX;
2979 fl->fl_type = F_WRLCK;
2980 if (type & 1)
2981 fl->fl_type = F_RDLCK;
2982 fl->fl_pid = 0;
2983 }
2984 READ64(clientid);
2968 READ32(namelen); 2985 READ32(namelen);
2969 READ_BUF(namelen); 2986 READ_BUF(namelen);
2970 if (namelen == 4)
2971 READ32(denied->owner.id);
2972 return -NFS4ERR_DENIED; 2987 return -NFS4ERR_DENIED;
2973} 2988}
2974 2989
2975static int decode_lock(struct xdr_stream *xdr, struct nfs_lockres *res) 2990static int decode_lock(struct xdr_stream *xdr, struct nfs_lock_res *res)
2976{ 2991{
2977 uint32_t *p; 2992 uint32_t *p;
2978 int status; 2993 int status;
2979 2994
2980 status = decode_op_hdr(xdr, OP_LOCK); 2995 status = decode_op_hdr(xdr, OP_LOCK);
2981 if (status == 0) { 2996 if (status == 0) {
2982 READ_BUF(sizeof(res->u.stateid.data)); 2997 READ_BUF(sizeof(res->stateid.data));
2983 COPYMEM(res->u.stateid.data, sizeof(res->u.stateid.data)); 2998 COPYMEM(res->stateid.data, sizeof(res->stateid.data));
2984 } else if (status == -NFS4ERR_DENIED) 2999 } else if (status == -NFS4ERR_DENIED)
2985 return decode_lock_denied(xdr, &res->u.denied); 3000 return decode_lock_denied(xdr, NULL);
2986 return status; 3001 return status;
2987} 3002}
2988 3003
2989static int decode_lockt(struct xdr_stream *xdr, struct nfs_lockres *res) 3004static int decode_lockt(struct xdr_stream *xdr, struct nfs_lockt_res *res)
2990{ 3005{
2991 int status; 3006 int status;
2992 status = decode_op_hdr(xdr, OP_LOCKT); 3007 status = decode_op_hdr(xdr, OP_LOCKT);
2993 if (status == -NFS4ERR_DENIED) 3008 if (status == -NFS4ERR_DENIED)
2994 return decode_lock_denied(xdr, &res->u.denied); 3009 return decode_lock_denied(xdr, res->denied);
2995 return status; 3010 return status;
2996} 3011}
2997 3012
2998static int decode_locku(struct xdr_stream *xdr, struct nfs_lockres *res) 3013static int decode_locku(struct xdr_stream *xdr, struct nfs_locku_res *res)
2999{ 3014{
3000 uint32_t *p; 3015 uint32_t *p;
3001 int status; 3016 int status;
3002 3017
3003 status = decode_op_hdr(xdr, OP_LOCKU); 3018 status = decode_op_hdr(xdr, OP_LOCKU);
3004 if (status == 0) { 3019 if (status == 0) {
3005 READ_BUF(sizeof(res->u.stateid.data)); 3020 READ_BUF(sizeof(res->stateid.data));
3006 COPYMEM(res->u.stateid.data, sizeof(res->u.stateid.data)); 3021 COPYMEM(res->stateid.data, sizeof(res->stateid.data));
3007 } 3022 }
3008 return status; 3023 return status;
3009} 3024}
@@ -3831,6 +3846,9 @@ static int nfs4_xdr_dec_open_noattr(struct rpc_rqst *rqstp, uint32_t *p, struct
3831 if (status) 3846 if (status)
3832 goto out; 3847 goto out;
3833 status = decode_open(&xdr, res); 3848 status = decode_open(&xdr, res);
3849 if (status)
3850 goto out;
3851 decode_getfattr(&xdr, res->f_attr, res->server);
3834out: 3852out:
3835 return status; 3853 return status;
3836} 3854}
@@ -3864,7 +3882,7 @@ out:
3864/* 3882/*
3865 * Decode LOCK response 3883 * Decode LOCK response
3866 */ 3884 */
3867static int nfs4_xdr_dec_lock(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_lockres *res) 3885static int nfs4_xdr_dec_lock(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_lock_res *res)
3868{ 3886{
3869 struct xdr_stream xdr; 3887 struct xdr_stream xdr;
3870 struct compound_hdr hdr; 3888 struct compound_hdr hdr;
@@ -3885,7 +3903,7 @@ out:
3885/* 3903/*
3886 * Decode LOCKT response 3904 * Decode LOCKT response
3887 */ 3905 */
3888static int nfs4_xdr_dec_lockt(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_lockres *res) 3906static int nfs4_xdr_dec_lockt(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_lockt_res *res)
3889{ 3907{
3890 struct xdr_stream xdr; 3908 struct xdr_stream xdr;
3891 struct compound_hdr hdr; 3909 struct compound_hdr hdr;
@@ -3906,7 +3924,7 @@ out:
3906/* 3924/*
3907 * Decode LOCKU response 3925 * Decode LOCKU response
3908 */ 3926 */
3909static int nfs4_xdr_dec_locku(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_lockres *res) 3927static int nfs4_xdr_dec_locku(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_locku_res *res)
3910{ 3928{
3911 struct xdr_stream xdr; 3929 struct xdr_stream xdr;
3912 struct compound_hdr hdr; 3930 struct compound_hdr hdr;
@@ -4174,7 +4192,7 @@ static int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req, uint32_t *p, s
4174/* 4192/*
4175 * DELEGRETURN request 4193 * DELEGRETURN request
4176 */ 4194 */
4177static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, uint32_t *p, void *dummy) 4195static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_delegreturnres *res)
4178{ 4196{
4179 struct xdr_stream xdr; 4197 struct xdr_stream xdr;
4180 struct compound_hdr hdr; 4198 struct compound_hdr hdr;
@@ -4182,11 +4200,14 @@ static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, uint32_t *p, void *d
4182 4200
4183 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); 4201 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
4184 status = decode_compound_hdr(&xdr, &hdr); 4202 status = decode_compound_hdr(&xdr, &hdr);
4185 if (status == 0) { 4203 if (status != 0)
4186 status = decode_putfh(&xdr); 4204 goto out;
4187 if (status == 0) 4205 status = decode_putfh(&xdr);
4188 status = decode_delegreturn(&xdr); 4206 if (status != 0)
4189 } 4207 goto out;
4208 status = decode_delegreturn(&xdr);
4209 decode_getfattr(&xdr, res->fattr, res->server);
4210out:
4190 return status; 4211 return status;
4191} 4212}
4192 4213