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.c131
1 files changed, 75 insertions, 56 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 3100172822c9..a7b5de899c6d 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -742,69 +742,80 @@ static int encode_link(struct xdr_stream *xdr, const struct qstr *name)
742 return 0; 742 return 0;
743} 743}
744 744
745static inline int nfs4_lock_type(struct file_lock *fl, int block)
746{
747 if ((fl->fl_type & (F_RDLCK|F_WRLCK|F_UNLCK)) == F_RDLCK)
748 return block ? NFS4_READW_LT : NFS4_READ_LT;
749 return block ? NFS4_WRITEW_LT : NFS4_WRITE_LT;
750}
751
752static inline uint64_t nfs4_lock_length(struct file_lock *fl)
753{
754 if (fl->fl_end == OFFSET_MAX)
755 return ~(uint64_t)0;
756 return fl->fl_end - fl->fl_start + 1;
757}
758
745/* 759/*
746 * opcode,type,reclaim,offset,length,new_lock_owner = 32 760 * opcode,type,reclaim,offset,length,new_lock_owner = 32
747 * open_seqid,open_stateid,lock_seqid,lock_owner.clientid, lock_owner.id = 40 761 * open_seqid,open_stateid,lock_seqid,lock_owner.clientid, lock_owner.id = 40
748 */ 762 */
749static int encode_lock(struct xdr_stream *xdr, const struct nfs_lockargs *arg) 763static int encode_lock(struct xdr_stream *xdr, const struct nfs_lock_args *args)
750{ 764{
751 uint32_t *p; 765 uint32_t *p;
752 struct nfs_lock_opargs *opargs = arg->u.lock;
753 766
754 RESERVE_SPACE(32); 767 RESERVE_SPACE(32);
755 WRITE32(OP_LOCK); 768 WRITE32(OP_LOCK);
756 WRITE32(arg->type); 769 WRITE32(nfs4_lock_type(args->fl, args->block));
757 WRITE32(opargs->reclaim); 770 WRITE32(args->reclaim);
758 WRITE64(arg->offset); 771 WRITE64(args->fl->fl_start);
759 WRITE64(arg->length); 772 WRITE64(nfs4_lock_length(args->fl));
760 WRITE32(opargs->new_lock_owner); 773 WRITE32(args->new_lock_owner);
761 if (opargs->new_lock_owner){ 774 if (args->new_lock_owner){
762 RESERVE_SPACE(40); 775 RESERVE_SPACE(40);
763 WRITE32(opargs->open_seqid->sequence->counter); 776 WRITE32(args->open_seqid->sequence->counter);
764 WRITEMEM(opargs->open_stateid->data, sizeof(opargs->open_stateid->data)); 777 WRITEMEM(args->open_stateid->data, sizeof(args->open_stateid->data));
765 WRITE32(opargs->lock_seqid->sequence->counter); 778 WRITE32(args->lock_seqid->sequence->counter);
766 WRITE64(opargs->lock_owner.clientid); 779 WRITE64(args->lock_owner.clientid);
767 WRITE32(4); 780 WRITE32(4);
768 WRITE32(opargs->lock_owner.id); 781 WRITE32(args->lock_owner.id);
769 } 782 }
770 else { 783 else {
771 RESERVE_SPACE(20); 784 RESERVE_SPACE(20);
772 WRITEMEM(opargs->lock_stateid->data, sizeof(opargs->lock_stateid->data)); 785 WRITEMEM(args->lock_stateid->data, sizeof(args->lock_stateid->data));
773 WRITE32(opargs->lock_seqid->sequence->counter); 786 WRITE32(args->lock_seqid->sequence->counter);
774 } 787 }
775 788
776 return 0; 789 return 0;
777} 790}
778 791
779static int encode_lockt(struct xdr_stream *xdr, const struct nfs_lockargs *arg) 792static int encode_lockt(struct xdr_stream *xdr, const struct nfs_lockt_args *args)
780{ 793{
781 uint32_t *p; 794 uint32_t *p;
782 struct nfs_lowner *opargs = arg->u.lockt;
783 795
784 RESERVE_SPACE(40); 796 RESERVE_SPACE(40);
785 WRITE32(OP_LOCKT); 797 WRITE32(OP_LOCKT);
786 WRITE32(arg->type); 798 WRITE32(nfs4_lock_type(args->fl, 0));
787 WRITE64(arg->offset); 799 WRITE64(args->fl->fl_start);
788 WRITE64(arg->length); 800 WRITE64(nfs4_lock_length(args->fl));
789 WRITE64(opargs->clientid); 801 WRITE64(args->lock_owner.clientid);
790 WRITE32(4); 802 WRITE32(4);
791 WRITE32(opargs->id); 803 WRITE32(args->lock_owner.id);
792 804
793 return 0; 805 return 0;
794} 806}
795 807
796static int encode_locku(struct xdr_stream *xdr, const struct nfs_lockargs *arg) 808static int encode_locku(struct xdr_stream *xdr, const struct nfs_locku_args *args)
797{ 809{
798 uint32_t *p; 810 uint32_t *p;
799 struct nfs_locku_opargs *opargs = arg->u.locku;
800 811
801 RESERVE_SPACE(44); 812 RESERVE_SPACE(44);
802 WRITE32(OP_LOCKU); 813 WRITE32(OP_LOCKU);
803 WRITE32(arg->type); 814 WRITE32(nfs4_lock_type(args->fl, 0));
804 WRITE32(opargs->seqid->sequence->counter); 815 WRITE32(args->seqid->sequence->counter);
805 WRITEMEM(opargs->stateid->data, sizeof(opargs->stateid->data)); 816 WRITEMEM(args->stateid->data, sizeof(args->stateid->data));
806 WRITE64(arg->offset); 817 WRITE64(args->fl->fl_start);
807 WRITE64(arg->length); 818 WRITE64(nfs4_lock_length(args->fl));
808 819
809 return 0; 820 return 0;
810} 821}
@@ -1596,21 +1607,20 @@ out:
1596/* 1607/*
1597 * Encode a LOCK request 1608 * Encode a LOCK request
1598 */ 1609 */
1599static int nfs4_xdr_enc_lock(struct rpc_rqst *req, uint32_t *p, struct nfs_lockargs *args) 1610static int nfs4_xdr_enc_lock(struct rpc_rqst *req, uint32_t *p, struct nfs_lock_args *args)
1600{ 1611{
1601 struct xdr_stream xdr; 1612 struct xdr_stream xdr;
1602 struct compound_hdr hdr = { 1613 struct compound_hdr hdr = {
1603 .nops = 2, 1614 .nops = 2,
1604 }; 1615 };
1605 struct nfs_lock_opargs *opargs = args->u.lock;
1606 int status; 1616 int status;
1607 1617
1608 status = nfs_wait_on_sequence(opargs->lock_seqid, req->rq_task); 1618 status = nfs_wait_on_sequence(args->lock_seqid, req->rq_task);
1609 if (status != 0) 1619 if (status != 0)
1610 goto out; 1620 goto out;
1611 /* Do we need to do an open_to_lock_owner? */ 1621 /* Do we need to do an open_to_lock_owner? */
1612 if (opargs->lock_seqid->sequence->flags & NFS_SEQID_CONFIRMED) 1622 if (args->lock_seqid->sequence->flags & NFS_SEQID_CONFIRMED)
1613 opargs->new_lock_owner = 0; 1623 args->new_lock_owner = 0;
1614 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1624 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1615 encode_compound_hdr(&xdr, &hdr); 1625 encode_compound_hdr(&xdr, &hdr);
1616 status = encode_putfh(&xdr, args->fh); 1626 status = encode_putfh(&xdr, args->fh);
@@ -1624,7 +1634,7 @@ out:
1624/* 1634/*
1625 * Encode a LOCKT request 1635 * Encode a LOCKT request
1626 */ 1636 */
1627static int nfs4_xdr_enc_lockt(struct rpc_rqst *req, uint32_t *p, struct nfs_lockargs *args) 1637static int nfs4_xdr_enc_lockt(struct rpc_rqst *req, uint32_t *p, struct nfs_lockt_args *args)
1628{ 1638{
1629 struct xdr_stream xdr; 1639 struct xdr_stream xdr;
1630 struct compound_hdr hdr = { 1640 struct compound_hdr hdr = {
@@ -1645,7 +1655,7 @@ out:
1645/* 1655/*
1646 * Encode a LOCKU request 1656 * Encode a LOCKU request
1647 */ 1657 */
1648static int nfs4_xdr_enc_locku(struct rpc_rqst *req, uint32_t *p, struct nfs_lockargs *args) 1658static int nfs4_xdr_enc_locku(struct rpc_rqst *req, uint32_t *p, struct nfs_locku_args *args)
1649{ 1659{
1650 struct xdr_stream xdr; 1660 struct xdr_stream xdr;
1651 struct compound_hdr hdr = { 1661 struct compound_hdr hdr = {
@@ -2949,55 +2959,64 @@ static int decode_link(struct xdr_stream *xdr, struct nfs4_change_info *cinfo)
2949/* 2959/*
2950 * We create the owner, so we know a proper owner.id length is 4. 2960 * We create the owner, so we know a proper owner.id length is 4.
2951 */ 2961 */
2952static int decode_lock_denied (struct xdr_stream *xdr, struct nfs_lock_denied *denied) 2962static int decode_lock_denied (struct xdr_stream *xdr, struct file_lock *fl)
2953{ 2963{
2964 uint64_t offset, length, clientid;
2954 uint32_t *p; 2965 uint32_t *p;
2955 uint32_t namelen; 2966 uint32_t namelen, type;
2956 2967
2957 READ_BUF(32); 2968 READ_BUF(32);
2958 READ64(denied->offset); 2969 READ64(offset);
2959 READ64(denied->length); 2970 READ64(length);
2960 READ32(denied->type); 2971 READ32(type);
2961 READ64(denied->owner.clientid); 2972 if (fl != NULL) {
2973 fl->fl_start = (loff_t)offset;
2974 fl->fl_end = fl->fl_start + (loff_t)length - 1;
2975 if (length == ~(uint64_t)0)
2976 fl->fl_end = OFFSET_MAX;
2977 fl->fl_type = F_WRLCK;
2978 if (type & 1)
2979 fl->fl_type = F_RDLCK;
2980 fl->fl_pid = 0;
2981 }
2982 READ64(clientid);
2962 READ32(namelen); 2983 READ32(namelen);
2963 READ_BUF(namelen); 2984 READ_BUF(namelen);
2964 if (namelen == 4)
2965 READ32(denied->owner.id);
2966 return -NFS4ERR_DENIED; 2985 return -NFS4ERR_DENIED;
2967} 2986}
2968 2987
2969static int decode_lock(struct xdr_stream *xdr, struct nfs_lockres *res) 2988static int decode_lock(struct xdr_stream *xdr, struct nfs_lock_res *res)
2970{ 2989{
2971 uint32_t *p; 2990 uint32_t *p;
2972 int status; 2991 int status;
2973 2992
2974 status = decode_op_hdr(xdr, OP_LOCK); 2993 status = decode_op_hdr(xdr, OP_LOCK);
2975 if (status == 0) { 2994 if (status == 0) {
2976 READ_BUF(sizeof(res->u.stateid.data)); 2995 READ_BUF(sizeof(res->stateid.data));
2977 COPYMEM(res->u.stateid.data, sizeof(res->u.stateid.data)); 2996 COPYMEM(res->stateid.data, sizeof(res->stateid.data));
2978 } else if (status == -NFS4ERR_DENIED) 2997 } else if (status == -NFS4ERR_DENIED)
2979 return decode_lock_denied(xdr, &res->u.denied); 2998 return decode_lock_denied(xdr, NULL);
2980 return status; 2999 return status;
2981} 3000}
2982 3001
2983static int decode_lockt(struct xdr_stream *xdr, struct nfs_lockres *res) 3002static int decode_lockt(struct xdr_stream *xdr, struct nfs_lockt_res *res)
2984{ 3003{
2985 int status; 3004 int status;
2986 status = decode_op_hdr(xdr, OP_LOCKT); 3005 status = decode_op_hdr(xdr, OP_LOCKT);
2987 if (status == -NFS4ERR_DENIED) 3006 if (status == -NFS4ERR_DENIED)
2988 return decode_lock_denied(xdr, &res->u.denied); 3007 return decode_lock_denied(xdr, res->denied);
2989 return status; 3008 return status;
2990} 3009}
2991 3010
2992static int decode_locku(struct xdr_stream *xdr, struct nfs_lockres *res) 3011static int decode_locku(struct xdr_stream *xdr, struct nfs_locku_res *res)
2993{ 3012{
2994 uint32_t *p; 3013 uint32_t *p;
2995 int status; 3014 int status;
2996 3015
2997 status = decode_op_hdr(xdr, OP_LOCKU); 3016 status = decode_op_hdr(xdr, OP_LOCKU);
2998 if (status == 0) { 3017 if (status == 0) {
2999 READ_BUF(sizeof(res->u.stateid.data)); 3018 READ_BUF(sizeof(res->stateid.data));
3000 COPYMEM(res->u.stateid.data, sizeof(res->u.stateid.data)); 3019 COPYMEM(res->stateid.data, sizeof(res->stateid.data));
3001 } 3020 }
3002 return status; 3021 return status;
3003} 3022}
@@ -3861,7 +3880,7 @@ out:
3861/* 3880/*
3862 * Decode LOCK response 3881 * Decode LOCK response
3863 */ 3882 */
3864static int nfs4_xdr_dec_lock(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_lockres *res) 3883static int nfs4_xdr_dec_lock(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_lock_res *res)
3865{ 3884{
3866 struct xdr_stream xdr; 3885 struct xdr_stream xdr;
3867 struct compound_hdr hdr; 3886 struct compound_hdr hdr;
@@ -3882,7 +3901,7 @@ out:
3882/* 3901/*
3883 * Decode LOCKT response 3902 * Decode LOCKT response
3884 */ 3903 */
3885static int nfs4_xdr_dec_lockt(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_lockres *res) 3904static int nfs4_xdr_dec_lockt(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_lockt_res *res)
3886{ 3905{
3887 struct xdr_stream xdr; 3906 struct xdr_stream xdr;
3888 struct compound_hdr hdr; 3907 struct compound_hdr hdr;
@@ -3903,7 +3922,7 @@ out:
3903/* 3922/*
3904 * Decode LOCKU response 3923 * Decode LOCKU response
3905 */ 3924 */
3906static int nfs4_xdr_dec_locku(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_lockres *res) 3925static int nfs4_xdr_dec_locku(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_locku_res *res)
3907{ 3926{
3908 struct xdr_stream xdr; 3927 struct xdr_stream xdr;
3909 struct compound_hdr hdr; 3928 struct compound_hdr hdr;