Skip to content
Snippets Groups Projects
nfs4xdr.c 187 KiB
Newer Older
  • Learn to ignore specific revisions
  • 
    	p = reserve_space(xdr, 44 + NFS4_STATEID_SIZE);
    	*p++ = cpu_to_be32(OP_LAYOUTGET);
    	*p++ = cpu_to_be32(0);     /* Signal layout available */
    	*p++ = cpu_to_be32(args->type);
    	*p++ = cpu_to_be32(args->range.iomode);
    	p = xdr_encode_hyper(p, args->range.offset);
    	p = xdr_encode_hyper(p, args->range.length);
    	p = xdr_encode_hyper(p, args->minlength);
    
    	p = xdr_encode_opaque_fixed(p, &args->stateid.data, NFS4_STATEID_SIZE);
    
    	*p = cpu_to_be32(args->maxcount);
    
    	dprintk("%s: 1st type:0x%x iomode:%d off:%lu len:%lu mc:%d\n",
    		__func__,
    		args->type,
    		args->range.iomode,
    		(unsigned long)args->range.offset,
    		(unsigned long)args->range.length,
    		args->maxcount);
    	hdr->nops++;
    	hdr->replen += decode_layoutget_maxsz;
    }
    
    Andy Adamson's avatar
    Andy Adamson committed
    
    static int
    encode_layoutcommit(struct xdr_stream *xdr,
    
    Benny Halevy's avatar
    Benny Halevy committed
    		    struct inode *inode,
    
    Andy Adamson's avatar
    Andy Adamson committed
    		    const struct nfs4_layoutcommit_args *args,
    		    struct compound_hdr *hdr)
    {
    	__be32 *p;
    
    	dprintk("%s: lbw: %llu type: %d\n", __func__, args->lastbytewritten,
    		NFS_SERVER(args->inode)->pnfs_curr_ld->id);
    
    
    Benny Halevy's avatar
    Benny Halevy committed
    	p = reserve_space(xdr, 44 + NFS4_STATEID_SIZE);
    
    Andy Adamson's avatar
    Andy Adamson committed
    	*p++ = cpu_to_be32(OP_LAYOUTCOMMIT);
    	/* Only whole file layouts */
    	p = xdr_encode_hyper(p, 0); /* offset */
    
    	p = xdr_encode_hyper(p, args->lastbytewritten + 1);	/* length */
    
    Andy Adamson's avatar
    Andy Adamson committed
    	*p++ = cpu_to_be32(0); /* reclaim */
    	p = xdr_encode_opaque_fixed(p, args->stateid.data, NFS4_STATEID_SIZE);
    	*p++ = cpu_to_be32(1); /* newoffset = TRUE */
    	p = xdr_encode_hyper(p, args->lastbytewritten);
    	*p++ = cpu_to_be32(0); /* Never send time_modify_changed */
    	*p++ = cpu_to_be32(NFS_SERVER(args->inode)->pnfs_curr_ld->id);/* type */
    
    Benny Halevy's avatar
    Benny Halevy committed
    
    	if (NFS_SERVER(inode)->pnfs_curr_ld->encode_layoutcommit)
    		NFS_SERVER(inode)->pnfs_curr_ld->encode_layoutcommit(
    			NFS_I(inode)->layout, xdr, args);
    	else {
    		p = reserve_space(xdr, 4);
    		*p = cpu_to_be32(0); /* no layout-type payload */
    	}
    
    Andy Adamson's avatar
    Andy Adamson committed
    
    	hdr->nops++;
    	hdr->replen += decode_layoutcommit_maxsz;
    	return 0;
    }
    
    Benny Halevy's avatar
    Benny Halevy committed
    
    static void
    encode_layoutreturn(struct xdr_stream *xdr,
    		    const struct nfs4_layoutreturn_args *args,
    		    struct compound_hdr *hdr)
    {
    	__be32 *p;
    
    	p = reserve_space(xdr, 20);
    	*p++ = cpu_to_be32(OP_LAYOUTRETURN);
    	*p++ = cpu_to_be32(0);		/* reclaim. always 0 for now */
    	*p++ = cpu_to_be32(args->layout_type);
    	*p++ = cpu_to_be32(IOMODE_ANY);
    	*p = cpu_to_be32(RETURN_FILE);
    	p = reserve_space(xdr, 16 + NFS4_STATEID_SIZE);
    	p = xdr_encode_hyper(p, 0);
    	p = xdr_encode_hyper(p, NFS4_MAX_UINT64);
    	spin_lock(&args->inode->i_lock);
    	xdr_encode_opaque_fixed(p, &args->stateid.data, NFS4_STATEID_SIZE);
    	spin_unlock(&args->inode->i_lock);
    
    Andy Adamson's avatar
    Andy Adamson committed
    	if (NFS_SERVER(args->inode)->pnfs_curr_ld->encode_layoutreturn) {
    		NFS_SERVER(args->inode)->pnfs_curr_ld->encode_layoutreturn(
    			NFS_I(args->inode)->layout, xdr, args);
    	} else {
    		p = reserve_space(xdr, 4);
    		*p = cpu_to_be32(0);
    	}
    
    Benny Halevy's avatar
    Benny Halevy committed
    	hdr->nops++;
    	hdr->replen += decode_layoutreturn_maxsz;
    }
    
    
    static int
    encode_secinfo_no_name(struct xdr_stream *xdr,
    		       const struct nfs41_secinfo_no_name_args *args,
    		       struct compound_hdr *hdr)
    {
    	__be32 *p;
    	p = reserve_space(xdr, 8);
    	*p++ = cpu_to_be32(OP_SECINFO_NO_NAME);
    	*p++ = cpu_to_be32(args->style);
    	hdr->nops++;
    	hdr->replen += decode_secinfo_no_name_maxsz;
    	return 0;
    }
    
    
    static void encode_test_stateid(struct xdr_stream *xdr,
    				struct nfs41_test_stateid_args *args,
    				struct compound_hdr *hdr)
    {
    	__be32 *p;
    
    	p = reserve_space(xdr, 8 + NFS4_STATEID_SIZE);
    	*p++ = cpu_to_be32(OP_TEST_STATEID);
    	*p++ = cpu_to_be32(1);
    	xdr_encode_opaque_fixed(p, args->stateid->data, NFS4_STATEID_SIZE);
    	hdr->nops++;
    	hdr->replen += decode_test_stateid_maxsz;
    }
    
    
    static void encode_free_stateid(struct xdr_stream *xdr,
    				struct nfs41_free_stateid_args *args,
    				struct compound_hdr *hdr)
    {
    	__be32 *p;
    	p = reserve_space(xdr, 4 + NFS4_STATEID_SIZE);
    	*p++ = cpu_to_be32(OP_FREE_STATEID);
    	xdr_encode_opaque_fixed(p, args->stateid->data, NFS4_STATEID_SIZE);
    	hdr->nops++;
    	hdr->replen += decode_free_stateid_maxsz;
    }
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    /*
     * END OF "GENERIC" ENCODE ROUTINES.
     */
    
    
    static u32 nfs4_xdr_minorversion(const struct nfs4_sequence_args *args)
    {
    #if defined(CONFIG_NFS_V4_1)
    	if (args->sa_session)
    
    		return args->sa_session->clp->cl_mvops->minor_version;
    
    #endif /* CONFIG_NFS_V4_1 */
    	return 0;
    }
    
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    /*
     * Encode an ACCESS request
     */
    
    static void nfs4_xdr_enc_access(struct rpc_rqst *req, struct xdr_stream *xdr,
    				const struct nfs4_accessargs *args)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct compound_hdr hdr = {
    
    		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_sequence(xdr, &args->seq_args, &hdr);
    	encode_putfh(xdr, args->fh, &hdr);
    	encode_access(xdr, args->access, &hdr);
    	encode_getfattr(xdr, args->bitmask, &hdr);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    }
    
    /*
     * Encode LOOKUP request
     */
    
    static void nfs4_xdr_enc_lookup(struct rpc_rqst *req, struct xdr_stream *xdr,
    				const struct nfs4_lookup_arg *args)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct compound_hdr hdr = {
    
    		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_sequence(xdr, &args->seq_args, &hdr);
    	encode_putfh(xdr, args->dir_fh, &hdr);
    	encode_lookup(xdr, args->name, &hdr);
    	encode_getfh(xdr, &hdr);
    	encode_getfattr(xdr, args->bitmask, &hdr);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    }
    
    /*
     * Encode LOOKUP_ROOT request
     */
    
    static void nfs4_xdr_enc_lookup_root(struct rpc_rqst *req,
    				     struct xdr_stream *xdr,
    				     const struct nfs4_lookup_root_arg *args)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct compound_hdr hdr = {
    
    		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_sequence(xdr, &args->seq_args, &hdr);
    	encode_putrootfh(xdr, &hdr);
    	encode_getfh(xdr, &hdr);
    	encode_getfattr(xdr, args->bitmask, &hdr);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    }
    
    /*
     * Encode REMOVE request
     */
    
    static void nfs4_xdr_enc_remove(struct rpc_rqst *req, struct xdr_stream *xdr,
    				const struct nfs_removeargs *args)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct compound_hdr hdr = {
    
    		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_sequence(xdr, &args->seq_args, &hdr);
    	encode_putfh(xdr, args->fh, &hdr);
    	encode_remove(xdr, &args->name, &hdr);
    	encode_getfattr(xdr, args->bitmask, &hdr);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    }
    
    /*
     * Encode RENAME request
     */
    
    static void nfs4_xdr_enc_rename(struct rpc_rqst *req, struct xdr_stream *xdr,
    				const struct nfs_renameargs *args)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct compound_hdr hdr = {
    
    		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_sequence(xdr, &args->seq_args, &hdr);
    	encode_putfh(xdr, args->old_dir, &hdr);
    	encode_savefh(xdr, &hdr);
    	encode_putfh(xdr, args->new_dir, &hdr);
    	encode_rename(xdr, args->old_name, args->new_name, &hdr);
    	encode_getfattr(xdr, args->bitmask, &hdr);
    	encode_restorefh(xdr, &hdr);
    	encode_getfattr(xdr, args->bitmask, &hdr);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    }
    
    /*
     * Encode LINK request
     */
    
    static void nfs4_xdr_enc_link(struct rpc_rqst *req, struct xdr_stream *xdr,
    			     const struct nfs4_link_arg *args)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct compound_hdr hdr = {
    
    		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_sequence(xdr, &args->seq_args, &hdr);
    	encode_putfh(xdr, args->fh, &hdr);
    	encode_savefh(xdr, &hdr);
    	encode_putfh(xdr, args->dir_fh, &hdr);
    	encode_link(xdr, args->name, &hdr);
    	encode_getfattr(xdr, args->bitmask, &hdr);
    	encode_restorefh(xdr, &hdr);
    	encode_getfattr(xdr, args->bitmask, &hdr);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    }
    
    /*
     * Encode CREATE request
     */
    
    static void nfs4_xdr_enc_create(struct rpc_rqst *req, struct xdr_stream *xdr,
    				const struct nfs4_create_arg *args)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct compound_hdr hdr = {
    
    		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_sequence(xdr, &args->seq_args, &hdr);
    	encode_putfh(xdr, args->dir_fh, &hdr);
    	encode_savefh(xdr, &hdr);
    	encode_create(xdr, args, &hdr);
    	encode_getfh(xdr, &hdr);
    	encode_getfattr(xdr, args->bitmask, &hdr);
    	encode_restorefh(xdr, &hdr);
    	encode_getfattr(xdr, args->bitmask, &hdr);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    }
    
    /*
     * Encode SYMLINK request
     */
    
    static void nfs4_xdr_enc_symlink(struct rpc_rqst *req, struct xdr_stream *xdr,
    				 const struct nfs4_create_arg *args)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    
    	nfs4_xdr_enc_create(req, xdr, args);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    }
    
    /*
     * Encode GETATTR request
     */
    
    static void nfs4_xdr_enc_getattr(struct rpc_rqst *req, struct xdr_stream *xdr,
    				 const struct nfs4_getattr_arg *args)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct compound_hdr hdr = {
    
    		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_sequence(xdr, &args->seq_args, &hdr);
    	encode_putfh(xdr, args->fh, &hdr);
    	encode_getfattr(xdr, args->bitmask, &hdr);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    }
    
    /*
     * Encode a CLOSE request
     */
    
    static void nfs4_xdr_enc_close(struct rpc_rqst *req, struct xdr_stream *xdr,
    			       struct nfs_closeargs *args)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    
    Andy Adamson's avatar
    Andy Adamson committed
    	struct compound_hdr hdr = {
    
    		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_sequence(xdr, &args->seq_args, &hdr);
    	encode_putfh(xdr, args->fh, &hdr);
    	encode_close(xdr, args, &hdr);
    	encode_getfattr(xdr, args->bitmask, &hdr);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    }
    
    /*
     * Encode an OPEN request
     */
    
    static void nfs4_xdr_enc_open(struct rpc_rqst *req, struct xdr_stream *xdr,
    			      struct nfs_openargs *args)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct compound_hdr hdr = {
    
    		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_sequence(xdr, &args->seq_args, &hdr);
    	encode_putfh(xdr, args->fh, &hdr);
    	encode_savefh(xdr, &hdr);
    	encode_open(xdr, args, &hdr);
    	encode_getfh(xdr, &hdr);
    	encode_getfattr(xdr, args->bitmask, &hdr);
    	encode_restorefh(xdr, &hdr);
    
    	encode_getfattr(xdr, args->dir_bitmask, &hdr);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    }
    
    /*
     * Encode an OPEN_CONFIRM request
     */
    
    static void nfs4_xdr_enc_open_confirm(struct rpc_rqst *req,
    				      struct xdr_stream *xdr,
    				      struct nfs_open_confirmargs *args)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct compound_hdr hdr = {
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_putfh(xdr, args->fh, &hdr);
    	encode_open_confirm(xdr, args, &hdr);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    }
    
    /*
     * Encode an OPEN request with no attributes.
     */
    
    static void nfs4_xdr_enc_open_noattr(struct rpc_rqst *req,
    				     struct xdr_stream *xdr,
    				     struct nfs_openargs *args)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct compound_hdr hdr = {
    
    		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_sequence(xdr, &args->seq_args, &hdr);
    	encode_putfh(xdr, args->fh, &hdr);
    	encode_open(xdr, args, &hdr);
    	encode_getfattr(xdr, args->bitmask, &hdr);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    }
    
    /*
     * Encode an OPEN_DOWNGRADE request
     */
    
    static void nfs4_xdr_enc_open_downgrade(struct rpc_rqst *req,
    					struct xdr_stream *xdr,
    					struct nfs_closeargs *args)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct compound_hdr hdr = {
    
    		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_sequence(xdr, &args->seq_args, &hdr);
    	encode_putfh(xdr, args->fh, &hdr);
    	encode_open_downgrade(xdr, args, &hdr);
    	encode_getfattr(xdr, args->bitmask, &hdr);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    }
    
    /*
     * Encode a LOCK request
     */
    
    static void nfs4_xdr_enc_lock(struct rpc_rqst *req, struct xdr_stream *xdr,
    			      struct nfs_lock_args *args)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct compound_hdr hdr = {
    
    		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_sequence(xdr, &args->seq_args, &hdr);
    	encode_putfh(xdr, args->fh, &hdr);
    	encode_lock(xdr, args, &hdr);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    }
    
    /*
     * Encode a LOCKT request
     */
    
    static void nfs4_xdr_enc_lockt(struct rpc_rqst *req, struct xdr_stream *xdr,
    			       struct nfs_lockt_args *args)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct compound_hdr hdr = {
    
    		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_sequence(xdr, &args->seq_args, &hdr);
    	encode_putfh(xdr, args->fh, &hdr);
    	encode_lockt(xdr, args, &hdr);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    }
    
    /*
     * Encode a LOCKU request
     */
    
    static void nfs4_xdr_enc_locku(struct rpc_rqst *req, struct xdr_stream *xdr,
    			       struct nfs_locku_args *args)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct compound_hdr hdr = {
    
    		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_sequence(xdr, &args->seq_args, &hdr);
    	encode_putfh(xdr, args->fh, &hdr);
    	encode_locku(xdr, args, &hdr);
    
    static void nfs4_xdr_enc_release_lockowner(struct rpc_rqst *req,
    					   struct xdr_stream *xdr,
    					struct nfs_release_lockowner_args *args)
    
    {
    	struct compound_hdr hdr = {
    		.minorversion = 0,
    	};
    
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_release_lockowner(xdr, &args->lock_owner, &hdr);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    /*
     * Encode a READLINK request
     */
    
    static void nfs4_xdr_enc_readlink(struct rpc_rqst *req, struct xdr_stream *xdr,
    				  const struct nfs4_readlink *args)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct compound_hdr hdr = {
    
    		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_sequence(xdr, &args->seq_args, &hdr);
    	encode_putfh(xdr, args->fh, &hdr);
    	encode_readlink(xdr, args, req, &hdr);
    
    	xdr_inline_pages(&req->rq_rcv_buf, hdr.replen << 2, args->pages,
    
    			args->pgbase, args->pglen);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    }
    
    /*
     * Encode a READDIR request
     */
    
    static void nfs4_xdr_enc_readdir(struct rpc_rqst *req, struct xdr_stream *xdr,
    				 const struct nfs4_readdir_arg *args)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct compound_hdr hdr = {
    
    		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_sequence(xdr, &args->seq_args, &hdr);
    	encode_putfh(xdr, args->fh, &hdr);
    	encode_readdir(xdr, args, req, &hdr);
    
    	xdr_inline_pages(&req->rq_rcv_buf, hdr.replen << 2, args->pages,
    
    			 args->pgbase, args->count);
    	dprintk("%s: inlined page args = (%u, %p, %u, %u)\n",
    
    			__func__, hdr.replen << 2, args->pages,
    
    			args->pgbase, args->count);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    }
    
    /*
     * Encode a READ request
     */
    
    static void nfs4_xdr_enc_read(struct rpc_rqst *req, struct xdr_stream *xdr,
    			      struct nfs_readargs *args)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct compound_hdr hdr = {
    
    		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_sequence(xdr, &args->seq_args, &hdr);
    	encode_putfh(xdr, args->fh, &hdr);
    	encode_read(xdr, args, &hdr);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    
    
    	xdr_inline_pages(&req->rq_rcv_buf, hdr.replen << 2,
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    			 args->pages, args->pgbase, args->count);
    
    	req->rq_rcv_buf.flags |= XDRBUF_READ;
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    }
    
    /*
     * Encode an SETATTR request
     */
    
    static void nfs4_xdr_enc_setattr(struct rpc_rqst *req, struct xdr_stream *xdr,
    				 struct nfs_setattrargs *args)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    
    Andy Adamson's avatar
    Andy Adamson committed
    	struct compound_hdr hdr = {
    
    		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_sequence(xdr, &args->seq_args, &hdr);
    	encode_putfh(xdr, args->fh, &hdr);
    	encode_setattr(xdr, args, args->server, &hdr);
    	encode_getfattr(xdr, args->bitmask, &hdr);
    
    static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr,
    				struct nfs_getaclargs *args)
    
    {
    	struct compound_hdr hdr = {
    
    		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_sequence(xdr, &args->seq_args, &hdr);
    	encode_putfh(xdr, args->fh, &hdr);
    
    	replen = hdr.replen + op_decode_hdr_maxsz + 1;
    
    	encode_getattr_two(xdr, FATTR4_WORD0_ACL, 0, &hdr);
    
    	xdr_inline_pages(&req->rq_rcv_buf, replen << 2,
    
    		args->acl_pages, args->acl_pgbase, args->acl_len);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    /*
     * Encode a WRITE request
     */
    
    static void nfs4_xdr_enc_write(struct rpc_rqst *req, struct xdr_stream *xdr,
    			       struct nfs_writeargs *args)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct compound_hdr hdr = {
    
    		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_sequence(xdr, &args->seq_args, &hdr);
    	encode_putfh(xdr, args->fh, &hdr);
    	encode_write(xdr, args, &hdr);
    
    	req->rq_snd_buf.flags |= XDRBUF_WRITE;
    
    	if (args->bitmask)
    		encode_getfattr(xdr, args->bitmask, &hdr);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    }
    
    /*
     *  a COMMIT request
     */
    
    static void nfs4_xdr_enc_commit(struct rpc_rqst *req, struct xdr_stream *xdr,
    				struct nfs_writeargs *args)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct compound_hdr hdr = {
    
    		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_sequence(xdr, &args->seq_args, &hdr);
    	encode_putfh(xdr, args->fh, &hdr);
    	encode_commit(xdr, args, &hdr);
    
    	if (args->bitmask)
    		encode_getfattr(xdr, args->bitmask, &hdr);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    }
    
    /*
     * FSINFO request
     */
    
    static void nfs4_xdr_enc_fsinfo(struct rpc_rqst *req, struct xdr_stream *xdr,
    				struct nfs4_fsinfo_arg *args)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct compound_hdr hdr = {
    
    		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_sequence(xdr, &args->seq_args, &hdr);
    	encode_putfh(xdr, args->fh, &hdr);
    	encode_fsinfo(xdr, args->bitmask, &hdr);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    }
    
    /*
     * a PATHCONF request
     */
    
    static void nfs4_xdr_enc_pathconf(struct rpc_rqst *req, struct xdr_stream *xdr,
    				  const struct nfs4_pathconf_arg *args)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct compound_hdr hdr = {
    
    		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_sequence(xdr, &args->seq_args, &hdr);
    	encode_putfh(xdr, args->fh, &hdr);
    	encode_getattr_one(xdr, args->bitmask[0] & nfs4_pathconf_bitmap[0],
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    }
    
    /*
     * a STATFS request
     */
    
    static void nfs4_xdr_enc_statfs(struct rpc_rqst *req, struct xdr_stream *xdr,
    				const struct nfs4_statfs_arg *args)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct compound_hdr hdr = {
    
    		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_sequence(xdr, &args->seq_args, &hdr);
    	encode_putfh(xdr, args->fh, &hdr);
    	encode_getattr_two(xdr, args->bitmask[0] & nfs4_statfs_bitmap[0],
    
    			   args->bitmask[1] & nfs4_statfs_bitmap[1], &hdr);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    }
    
    /*
     * GETATTR_BITMAP request
     */
    
    static void nfs4_xdr_enc_server_caps(struct rpc_rqst *req,
    				     struct xdr_stream *xdr,
    				     struct nfs4_server_caps_arg *args)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct compound_hdr hdr = {
    
    		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_sequence(xdr, &args->seq_args, &hdr);
    	encode_putfh(xdr, args->fhandle, &hdr);
    	encode_getattr_one(xdr, FATTR4_WORD0_SUPPORTED_ATTRS|
    
    			   FATTR4_WORD0_LINK_SUPPORT|
    			   FATTR4_WORD0_SYMLINK_SUPPORT|
    			   FATTR4_WORD0_ACLSUPPORT, &hdr);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    }
    
    /*
     * a RENEW request
     */
    
    static void nfs4_xdr_enc_renew(struct rpc_rqst *req, struct xdr_stream *xdr,
    			       struct nfs_client *clp)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct compound_hdr hdr = {
    
    	encode_compound_hdr(xdr, req, &hdr);
    
    	encode_renew(xdr, clp->cl_clientid, &hdr);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    }
    
    /*
     * a SETCLIENTID request
     */
    
    static void nfs4_xdr_enc_setclientid(struct rpc_rqst *req,
    				     struct xdr_stream *xdr,
    				     struct nfs4_setclientid *sc)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct compound_hdr hdr = {
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_setclientid(xdr, sc, &hdr);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    }
    
    /*
     * a SETCLIENTID_CONFIRM request
     */
    
    static void nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req,
    					     struct xdr_stream *xdr,
    					     struct nfs4_setclientid_res *arg)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct compound_hdr hdr = {
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    	};
    
    	const u32 lease_bitmap[3] = { FATTR4_WORD0_LEASE_TIME };
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_setclientid_confirm(xdr, arg, &hdr);
    	encode_putrootfh(xdr, &hdr);
    	encode_fsinfo(xdr, lease_bitmap, &hdr);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    }
    
    /*
     * DELEGRETURN request
     */
    
    static void nfs4_xdr_enc_delegreturn(struct rpc_rqst *req,
    				     struct xdr_stream *xdr,
    				     const struct nfs4_delegreturnargs *args)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct compound_hdr hdr = {
    
    		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_sequence(xdr, &args->seq_args, &hdr);
    	encode_putfh(xdr, args->fhandle, &hdr);
    	encode_delegreturn(xdr, args->stateid, &hdr);
    	encode_getfattr(xdr, args->bitmask, &hdr);
    
    /*
     * Encode FS_LOCATIONS request
     */
    
    static void nfs4_xdr_enc_fs_locations(struct rpc_rqst *req,
    				      struct xdr_stream *xdr,
    				      struct nfs4_fs_locations_arg *args)
    
    {
    	struct compound_hdr hdr = {
    
    		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_sequence(xdr, &args->seq_args, &hdr);
    	encode_putfh(xdr, args->dir_fh, &hdr);
    	encode_lookup(xdr, args->name, &hdr);
    
    	replen = hdr.replen;	/* get the attribute into args->page */
    
    	encode_fs_locations(xdr, args->bitmask, &hdr);
    
    	xdr_inline_pages(&req->rq_rcv_buf, replen << 2, &args->page,
    
    /*
     * Encode SECINFO request
     */
    static void nfs4_xdr_enc_secinfo(struct rpc_rqst *req,
    				struct xdr_stream *xdr,
    				struct nfs4_secinfo_arg *args)
    {
    	struct compound_hdr hdr = {
    		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    	};
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_sequence(xdr, &args->seq_args, &hdr);
    	encode_putfh(xdr, args->dir_fh, &hdr);
    	encode_secinfo(xdr, args->name, &hdr);
    	encode_nops(&hdr);
    }
    
    
    #if defined(CONFIG_NFS_V4_1)
    /*
     * EXCHANGE_ID request
     */
    
    static void nfs4_xdr_enc_exchange_id(struct rpc_rqst *req,
    				     struct xdr_stream *xdr,
    				     struct nfs41_exchange_id_args *args)
    
    {
    	struct compound_hdr hdr = {
    
    		.minorversion = args->client->cl_mvops->minor_version,
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_exchange_id(xdr, args, &hdr);
    
    	encode_nops(&hdr);
    }
    
    /*
     * a CREATE_SESSION request
     */
    
    static void nfs4_xdr_enc_create_session(struct rpc_rqst *req,
    					struct xdr_stream *xdr,
    					struct nfs41_create_session_args *args)
    
    {
    	struct compound_hdr hdr = {
    
    		.minorversion = args->client->cl_mvops->minor_version,
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_create_session(xdr, args, &hdr);
    
    	encode_nops(&hdr);
    }
    
    
    /*
     * a DESTROY_SESSION request
     */
    
    static void nfs4_xdr_enc_destroy_session(struct rpc_rqst *req,
    					 struct xdr_stream *xdr,
    					 struct nfs4_session *session)
    
    {
    	struct compound_hdr hdr = {
    
    		.minorversion = session->clp->cl_mvops->minor_version,
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_destroy_session(xdr, session, &hdr);
    
    	encode_nops(&hdr);
    }
    
    
    Andy Adamson's avatar
    Andy Adamson committed
    /*
     * a SEQUENCE request
     */
    
    static void nfs4_xdr_enc_sequence(struct rpc_rqst *req, struct xdr_stream *xdr,
    				  struct nfs4_sequence_args *args)
    
    Andy Adamson's avatar
    Andy Adamson committed
    {
    	struct compound_hdr hdr = {
    		.minorversion = nfs4_xdr_minorversion(args),
    	};
    
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_sequence(xdr, args, &hdr);
    
    Andy Adamson's avatar
    Andy Adamson committed
    	encode_nops(&hdr);
    }
    
    
    Andy Adamson's avatar
    Andy Adamson committed
    /*
     * a GET_LEASE_TIME request
     */
    
    static void nfs4_xdr_enc_get_lease_time(struct rpc_rqst *req,
    					struct xdr_stream *xdr,
    					struct nfs4_get_lease_time_args *args)
    
    Andy Adamson's avatar
    Andy Adamson committed
    {
    	struct compound_hdr hdr = {
    		.minorversion = nfs4_xdr_minorversion(&args->la_seq_args),
    	};
    
    	const u32 lease_bitmap[3] = { FATTR4_WORD0_LEASE_TIME };
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_sequence(xdr, &args->la_seq_args, &hdr);
    	encode_putrootfh(xdr, &hdr);
    	encode_fsinfo(xdr, lease_bitmap, &hdr);
    
    Andy Adamson's avatar
    Andy Adamson committed
    	encode_nops(&hdr);
    }
    
    
    /*
     * a RECLAIM_COMPLETE request
     */
    
    static void nfs4_xdr_enc_reclaim_complete(struct rpc_rqst *req,
    					  struct xdr_stream *xdr,
    				struct nfs41_reclaim_complete_args *args)
    
    {
    	struct compound_hdr hdr = {
    		.minorversion = nfs4_xdr_minorversion(&args->seq_args)
    	};
    
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_sequence(xdr, &args->seq_args, &hdr);
    	encode_reclaim_complete(xdr, args, &hdr);
    
    Andy Adamson's avatar
    Andy Adamson committed
    /*
     * Encode GETDEVICELIST request
     */
    static void nfs4_xdr_enc_getdevicelist(struct rpc_rqst *req,
    				       struct xdr_stream *xdr,
    				       struct nfs4_getdevicelist_args *args)
    {
    	struct compound_hdr hdr = {
    		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    	};
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_sequence(xdr, &args->seq_args, &hdr);
    	encode_putfh(xdr, args->fh, &hdr);
    	encode_getdevicelist(xdr, args, &hdr);
    	encode_nops(&hdr);
    }
    
    
    static void nfs4_xdr_enc_getdeviceinfo(struct rpc_rqst *req,
    				       struct xdr_stream *xdr,
    				       struct nfs4_getdeviceinfo_args *args)
    
    {
    	struct compound_hdr hdr = {
    		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    	};
    
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_sequence(xdr, &args->seq_args, &hdr);
    	encode_getdeviceinfo(xdr, args, &hdr);
    
    
    	/* set up reply kvec. Subtract notification bitmap max size (2)
    	 * so that notification bitmap is put in xdr_buf tail */
    	xdr_inline_pages(&req->rq_rcv_buf, (hdr.replen - 2) << 2,
    			 args->pdev->pages, args->pdev->pgbase,
    			 args->pdev->pglen);
    
    	encode_nops(&hdr);
    }
    
    /*
     *  Encode LAYOUTGET request
     */
    
    static void nfs4_xdr_enc_layoutget(struct rpc_rqst *req,
    				   struct xdr_stream *xdr,
    				   struct nfs4_layoutget_args *args)
    
    {
    	struct compound_hdr hdr = {
    		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    	};
    
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_sequence(xdr, &args->seq_args, &hdr);
    	encode_putfh(xdr, NFS_FH(args->inode), &hdr);
    	encode_layoutget(xdr, args, &hdr);
    
    
    	xdr_inline_pages(&req->rq_rcv_buf, hdr.replen << 2,
    	    args->layout.pages, 0, args->layout.pglen);
    
    
    Andy Adamson's avatar
    Andy Adamson committed
    
    /*
     *  Encode LAYOUTCOMMIT request
     */
    
    Benny Halevy's avatar
    Benny Halevy committed
    static void nfs4_xdr_enc_layoutcommit(struct rpc_rqst *req,
    				      struct xdr_stream *xdr,
    				      struct nfs4_layoutcommit_args *args)
    
    Andy Adamson's avatar
    Andy Adamson committed
    {
    
    Benny Halevy's avatar
    Benny Halevy committed
    	struct nfs4_layoutcommit_data *data =
    		container_of(args, struct nfs4_layoutcommit_data, args);
    
    Andy Adamson's avatar
    Andy Adamson committed
    	struct compound_hdr hdr = {
    		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    	};
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_sequence(xdr, &args->seq_args, &hdr);
    	encode_putfh(xdr, NFS_FH(args->inode), &hdr);
    
    Benny Halevy's avatar
    Benny Halevy committed
    	encode_layoutcommit(xdr, data->args.inode, args, &hdr);
    
    Andy Adamson's avatar
    Andy Adamson committed
    	encode_getfattr(xdr, args->bitmask, &hdr);
    
    Benny Halevy's avatar
    Benny Halevy committed
    }
    
    /*
     * Encode LAYOUTRETURN request
     */
    static void nfs4_xdr_enc_layoutreturn(struct rpc_rqst *req,
    				      struct xdr_stream *xdr,
    				      struct nfs4_layoutreturn_args *args)
    {
    	struct compound_hdr hdr = {
    		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    	};
    
    	encode_compound_hdr(xdr, req, &hdr);
    	encode_sequence(xdr, &args->seq_args, &hdr);
    	encode_putfh(xdr, NFS_FH(args->inode), &hdr);
    	encode_layoutreturn(xdr, args, &hdr);
    	encode_nops(&hdr);