aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4xdr.c
diff options
context:
space:
mode:
authorBryan Schumaker <bjschuma@netapp.com>2010-10-21 16:33:17 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2010-10-23 15:27:37 -0400
commitae42c70a60fe330d9c2af7c4b92ce78484308e37 (patch)
treea70a200f3d031240e32e69d87375b021004e9817 /fs/nfs/nfs4xdr.c
parent9942438089d5c0e3adecdcb7bc360b8fe0ce7e62 (diff)
NFS: introduce generic decode_getattr function
Getattr should be able to decode errors and the readdir file handle. decode_getfattr_attrs does the actual attribute decoding, while decode_getfattr_generic will check the opcode before decoding. This will let other functions call decode_getfattr_attrs to decode their attributes. Signed-off-by: Bryan Schumaker <bjschuma@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4xdr.c')
-rw-r--r--fs/nfs/nfs4xdr.c117
1 files changed, 98 insertions, 19 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 8346e977d837..b7eff205d3d8 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -2848,6 +2848,58 @@ out_overflow:
2848 return -EIO; 2848 return -EIO;
2849} 2849}
2850 2850
2851static int decode_attr_error(struct xdr_stream *xdr, uint32_t *bitmap)
2852{
2853 __be32 *p;
2854
2855 if (unlikely(bitmap[0] & (FATTR4_WORD0_RDATTR_ERROR - 1U)))
2856 return -EIO;
2857 if (likely(bitmap[0] & FATTR4_WORD0_RDATTR_ERROR)) {
2858 p = xdr_inline_decode(xdr, 4);
2859 if (unlikely(!p))
2860 goto out_overflow;
2861 bitmap[0] &= ~FATTR4_WORD0_RDATTR_ERROR;
2862 }
2863 return 0;
2864out_overflow:
2865 print_overflow_msg(__func__, xdr);
2866 return -EIO;
2867}
2868
2869static int decode_attr_filehandle(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_fh *fh)
2870{
2871 __be32 *p;
2872 int len;
2873
2874 if (fh == NULL) {
2875 bitmap[0] &= ~FATTR4_WORD0_FILEHANDLE;
2876 return 0;
2877 }
2878
2879 memset(fh, 0, sizeof(*fh));
2880
2881 if (unlikely(bitmap[0] & (FATTR4_WORD0_FILEHANDLE - 1U)))
2882 return -EIO;
2883 if (likely(bitmap[0] & FATTR4_WORD0_FILEHANDLE)) {
2884 p = xdr_inline_decode(xdr, 4);
2885 if (unlikely(!p))
2886 goto out_overflow;
2887 len = be32_to_cpup(p);
2888 if (len > NFS4_FHSIZE)
2889 return -EIO;
2890 fh->size = len;
2891 p = xdr_inline_decode(xdr, len);
2892 if (unlikely(!p))
2893 goto out_overflow;
2894 memcpy(fh->data, p, len);
2895 bitmap[0] &= ~FATTR4_WORD0_FILEHANDLE;
2896 }
2897 return 0;
2898out_overflow:
2899 print_overflow_msg(__func__, xdr);
2900 return -EIO;
2901}
2902
2851static int decode_attr_aclsupport(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) 2903static int decode_attr_aclsupport(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
2852{ 2904{
2853 __be32 *p; 2905 __be32 *p;
@@ -3744,29 +3796,14 @@ xdr_error:
3744 return status; 3796 return status;
3745} 3797}
3746 3798
3747static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, 3799static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
3800 struct nfs_fattr *fattr, struct nfs_fh *fh,
3748 const struct nfs_server *server, int may_sleep) 3801 const struct nfs_server *server, int may_sleep)
3749{ 3802{
3750 __be32 *savep;
3751 uint32_t attrlen,
3752 bitmap[2] = {0},
3753 type;
3754 int status; 3803 int status;
3755 umode_t fmode = 0; 3804 umode_t fmode = 0;
3756 uint64_t fileid; 3805 uint64_t fileid;
3757 3806 uint32_t type;
3758 status = decode_op_hdr(xdr, OP_GETATTR);
3759 if (status < 0)
3760 goto xdr_error;
3761
3762 status = decode_attr_bitmap(xdr, bitmap);
3763 if (status < 0)
3764 goto xdr_error;
3765
3766 status = decode_attr_length(xdr, &attrlen, &savep);
3767 if (status < 0)
3768 goto xdr_error;
3769
3770 3807
3771 status = decode_attr_type(xdr, bitmap, &type); 3808 status = decode_attr_type(xdr, bitmap, &type);
3772 if (status < 0) 3809 if (status < 0)
@@ -3792,6 +3829,14 @@ static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr,
3792 goto xdr_error; 3829 goto xdr_error;
3793 fattr->valid |= status; 3830 fattr->valid |= status;
3794 3831
3832 status = decode_attr_error(xdr, bitmap);
3833 if (status < 0)
3834 goto xdr_error;
3835
3836 status = decode_attr_filehandle(xdr, bitmap, fh);
3837 if (status < 0)
3838 goto xdr_error;
3839
3795 status = decode_attr_fileid(xdr, bitmap, &fattr->fileid); 3840 status = decode_attr_fileid(xdr, bitmap, &fattr->fileid);
3796 if (status < 0) 3841 if (status < 0)
3797 goto xdr_error; 3842 goto xdr_error;
@@ -3857,17 +3902,51 @@ static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr,
3857 status = decode_attr_mounted_on_fileid(xdr, bitmap, &fileid); 3902 status = decode_attr_mounted_on_fileid(xdr, bitmap, &fileid);
3858 if (status < 0) 3903 if (status < 0)
3859 goto xdr_error; 3904 goto xdr_error;
3860 if (status != 0 && !(fattr->valid & status)) { 3905 if (status != 0) {
3861 fattr->fileid = fileid; 3906 fattr->fileid = fileid;
3862 fattr->valid |= status; 3907 fattr->valid |= status;
3863 } 3908 }
3864 3909
3910xdr_error:
3911 dprintk("%s: xdr returned %d\n", __func__, -status);
3912 return status;
3913}
3914
3915static int decode_getfattr_generic(struct xdr_stream *xdr, struct nfs_fattr *fattr,
3916 struct nfs_fh *fh, const struct nfs_server *server, int may_sleep)
3917{
3918 __be32 *savep;
3919 uint32_t attrlen,
3920 bitmap[2] = {0};
3921 int status;
3922
3923 status = decode_op_hdr(xdr, OP_GETATTR);
3924 if (status < 0)
3925 goto xdr_error;
3926
3927 status = decode_attr_bitmap(xdr, bitmap);
3928 if (status < 0)
3929 goto xdr_error;
3930
3931 status = decode_attr_length(xdr, &attrlen, &savep);
3932 if (status < 0)
3933 goto xdr_error;
3934
3935 status = decode_getfattr_attrs(xdr, bitmap, fattr, fh, server, may_sleep);
3936 if (status < 0)
3937 goto xdr_error;
3938
3865 status = verify_attr_len(xdr, savep, attrlen); 3939 status = verify_attr_len(xdr, savep, attrlen);
3866xdr_error: 3940xdr_error:
3867 dprintk("%s: xdr returned %d\n", __func__, -status); 3941 dprintk("%s: xdr returned %d\n", __func__, -status);
3868 return status; 3942 return status;
3869} 3943}
3870 3944
3945static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr,
3946 const struct nfs_server *server, int may_sleep)
3947{
3948 return decode_getfattr_generic(xdr, fattr, NULL, server, may_sleep);
3949}
3871 3950
3872static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo) 3951static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo)
3873{ 3952{