diff options
Diffstat (limited to 'fs/nfs/nfs4xdr.c')
-rw-r--r-- | fs/nfs/nfs4xdr.c | 131 |
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 | ||
745 | static 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 | |||
752 | static 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 | */ |
749 | static int encode_lock(struct xdr_stream *xdr, const struct nfs_lockargs *arg) | 763 | static 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 | ||
779 | static int encode_lockt(struct xdr_stream *xdr, const struct nfs_lockargs *arg) | 792 | static 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 | ||
796 | static int encode_locku(struct xdr_stream *xdr, const struct nfs_lockargs *arg) | 808 | static 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 | */ |
1599 | static int nfs4_xdr_enc_lock(struct rpc_rqst *req, uint32_t *p, struct nfs_lockargs *args) | 1610 | static 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 | */ |
1627 | static int nfs4_xdr_enc_lockt(struct rpc_rqst *req, uint32_t *p, struct nfs_lockargs *args) | 1637 | static 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 | */ |
1648 | static int nfs4_xdr_enc_locku(struct rpc_rqst *req, uint32_t *p, struct nfs_lockargs *args) | 1658 | static 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 | */ |
2952 | static int decode_lock_denied (struct xdr_stream *xdr, struct nfs_lock_denied *denied) | 2962 | static 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 | ||
2969 | static int decode_lock(struct xdr_stream *xdr, struct nfs_lockres *res) | 2988 | static 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 | ||
2983 | static int decode_lockt(struct xdr_stream *xdr, struct nfs_lockres *res) | 3002 | static 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 | ||
2992 | static int decode_locku(struct xdr_stream *xdr, struct nfs_lockres *res) | 3011 | static 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 | */ |
3864 | static int nfs4_xdr_dec_lock(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_lockres *res) | 3883 | static 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 | */ |
3885 | static int nfs4_xdr_dec_lockt(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_lockres *res) | 3904 | static 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 | */ |
3906 | static int nfs4_xdr_dec_locku(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_lockres *res) | 3925 | static 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; |