Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  *  Server-side types for NFSv4.
0003  *
0004  *  Copyright (c) 2002 The Regents of the University of Michigan.
0005  *  All rights reserved.
0006  *
0007  *  Kendrick Smith <kmsmith@umich.edu>
0008  *  Andy Adamson   <andros@umich.edu>
0009  *
0010  *  Redistribution and use in source and binary forms, with or without
0011  *  modification, are permitted provided that the following conditions
0012  *  are met:
0013  *
0014  *  1. Redistributions of source code must retain the above copyright
0015  *     notice, this list of conditions and the following disclaimer.
0016  *  2. Redistributions in binary form must reproduce the above copyright
0017  *     notice, this list of conditions and the following disclaimer in the
0018  *     documentation and/or other materials provided with the distribution.
0019  *  3. Neither the name of the University nor the names of its
0020  *     contributors may be used to endorse or promote products derived
0021  *     from this software without specific prior written permission.
0022  *
0023  *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
0024  *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
0025  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
0026  *  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
0027  *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0028  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0029  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
0030  *  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
0031  *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
0032  *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
0033  *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0034  *
0035  */
0036 
0037 #ifndef _LINUX_NFSD_XDR4_H
0038 #define _LINUX_NFSD_XDR4_H
0039 
0040 #include "state.h"
0041 #include "nfsd.h"
0042 
0043 #define NFSD4_MAX_TAGLEN    128
0044 #define XDR_LEN(n)                     (((n) + 3) & ~3)
0045 
0046 #define CURRENT_STATE_ID_FLAG (1<<0)
0047 #define SAVED_STATE_ID_FLAG (1<<1)
0048 
0049 #define SET_CSTATE_FLAG(c, f) ((c)->sid_flags |= (f))
0050 #define HAS_CSTATE_FLAG(c, f) ((c)->sid_flags & (f))
0051 #define CLEAR_CSTATE_FLAG(c, f) ((c)->sid_flags &= ~(f))
0052 
0053 struct nfsd4_compound_state {
0054     struct svc_fh       current_fh;
0055     struct svc_fh       save_fh;
0056     struct nfs4_stateowner  *replay_owner;
0057     struct nfs4_client  *clp;
0058     /* For sessions DRC */
0059     struct nfsd4_session    *session;
0060     struct nfsd4_slot   *slot;
0061     int         data_offset;
0062     bool                    spo_must_allowed;
0063     size_t          iovlen;
0064     u32         minorversion;
0065     __be32          status;
0066     stateid_t   current_stateid;
0067     stateid_t   save_stateid;
0068     /* to indicate current and saved state id presents */
0069     u32     sid_flags;
0070 };
0071 
0072 static inline bool nfsd4_has_session(struct nfsd4_compound_state *cs)
0073 {
0074     return cs->slot != NULL;
0075 }
0076 
0077 struct nfsd4_change_info {
0078     u32     atomic;
0079     u64     before_change;
0080     u64     after_change;
0081 };
0082 
0083 struct nfsd4_access {
0084     u32     ac_req_access;      /* request */
0085     u32     ac_supported;       /* response */
0086     u32     ac_resp_access;     /* response */
0087 };
0088 
0089 struct nfsd4_close {
0090     u32     cl_seqid;           /* request */
0091     stateid_t   cl_stateid;         /* request+response */
0092 };
0093 
0094 struct nfsd4_commit {
0095     u64     co_offset;          /* request */
0096     u32     co_count;           /* request */
0097     nfs4_verifier   co_verf;            /* response */
0098 };
0099 
0100 struct nfsd4_create {
0101     u32     cr_namelen;         /* request */
0102     char *      cr_name;            /* request */
0103     u32     cr_type;            /* request */
0104     union {                             /* request */
0105         struct {
0106             u32 datalen;
0107             char *data;
0108             struct kvec first;
0109         } link;   /* NF4LNK */
0110         struct {
0111             u32 specdata1;
0112             u32 specdata2;
0113         } dev;    /* NF4BLK, NF4CHR */
0114     } u;
0115     u32     cr_bmval[3];        /* request */
0116     struct iattr    cr_iattr;           /* request */
0117     int     cr_umask;           /* request */
0118     struct nfsd4_change_info  cr_cinfo; /* response */
0119     struct nfs4_acl *cr_acl;
0120     struct xdr_netobj cr_label;
0121 };
0122 #define cr_datalen  u.link.datalen
0123 #define cr_data     u.link.data
0124 #define cr_first    u.link.first
0125 #define cr_specdata1    u.dev.specdata1
0126 #define cr_specdata2    u.dev.specdata2
0127 
0128 struct nfsd4_delegreturn {
0129     stateid_t   dr_stateid;
0130 };
0131 
0132 struct nfsd4_getattr {
0133     u32     ga_bmval[3];        /* request */
0134     struct svc_fh   *ga_fhp;            /* response */
0135 };
0136 
0137 struct nfsd4_link {
0138     u32     li_namelen;         /* request */
0139     char *      li_name;            /* request */
0140     struct nfsd4_change_info  li_cinfo; /* response */
0141 };
0142 
0143 struct nfsd4_lock_denied {
0144     clientid_t  ld_clientid;
0145     struct xdr_netobj   ld_owner;
0146     u64             ld_start;
0147     u64             ld_length;
0148     u32             ld_type;
0149 };
0150 
0151 struct nfsd4_lock {
0152     /* request */
0153     u32             lk_type;
0154     u32             lk_reclaim;         /* boolean */
0155     u64             lk_offset;
0156     u64             lk_length;
0157     u32             lk_is_new;
0158     union {
0159         struct {
0160             u32             open_seqid;
0161             stateid_t       open_stateid;
0162             u32             lock_seqid;
0163             clientid_t      clientid;
0164             struct xdr_netobj owner;
0165         } new;
0166         struct {
0167             stateid_t       lock_stateid;
0168             u32             lock_seqid;
0169         } old;
0170     } v;
0171 
0172     /* response */
0173     union {
0174         struct {
0175             stateid_t               stateid;
0176         } ok;
0177         struct nfsd4_lock_denied        denied;
0178     } u;
0179 };
0180 #define lk_new_open_seqid       v.new.open_seqid
0181 #define lk_new_open_stateid     v.new.open_stateid
0182 #define lk_new_lock_seqid       v.new.lock_seqid
0183 #define lk_new_clientid         v.new.clientid
0184 #define lk_new_owner            v.new.owner
0185 #define lk_old_lock_stateid     v.old.lock_stateid
0186 #define lk_old_lock_seqid       v.old.lock_seqid
0187 
0188 #define lk_resp_stateid u.ok.stateid
0189 #define lk_denied       u.denied
0190 
0191 
0192 struct nfsd4_lockt {
0193     u32             lt_type;
0194     clientid_t          lt_clientid;
0195     struct xdr_netobj       lt_owner;
0196     u64             lt_offset;
0197     u64             lt_length;
0198     struct nfsd4_lock_denied    lt_denied;
0199 };
0200 
0201  
0202 struct nfsd4_locku {
0203     u32             lu_type;
0204     u32             lu_seqid;
0205     stateid_t       lu_stateid;
0206     u64             lu_offset;
0207     u64             lu_length;
0208 };
0209 
0210 
0211 struct nfsd4_lookup {
0212     u32     lo_len;             /* request */
0213     char *      lo_name;            /* request */
0214 };
0215 
0216 struct nfsd4_putfh {
0217     u32     pf_fhlen;           /* request */
0218     char        *pf_fhval;          /* request */
0219     bool        no_verify;      /* represents foreigh fh */
0220 };
0221 
0222 struct nfsd4_getxattr {
0223     char        *getxa_name;        /* request */
0224     u32     getxa_len;      /* request */
0225     void        *getxa_buf;
0226 };
0227 
0228 struct nfsd4_setxattr {
0229     u32     setxa_flags;        /* request */
0230     char        *setxa_name;        /* request */
0231     char        *setxa_buf;     /* request */
0232     u32     setxa_len;      /* request */
0233     struct nfsd4_change_info  setxa_cinfo;  /* response */
0234 };
0235 
0236 struct nfsd4_removexattr {
0237     char        *rmxa_name;     /* request */
0238     struct nfsd4_change_info  rmxa_cinfo;   /* response */
0239 };
0240 
0241 struct nfsd4_listxattrs {
0242     u64     lsxa_cookie;        /* request */
0243     u32     lsxa_maxcount;      /* request */
0244     char        *lsxa_buf;      /* unfiltered buffer (reply) */
0245     u32     lsxa_len;       /* unfiltered len (reply) */
0246 };
0247 
0248 struct nfsd4_open {
0249     u32     op_claim_type;      /* request */
0250     u32     op_fnamelen;
0251     char *      op_fname;       /* request - everything but CLAIM_PREV */
0252     u32     op_delegate_type;   /* request - CLAIM_PREV only */
0253     stateid_t       op_delegate_stateid; /* request - response */
0254     u32     op_why_no_deleg;    /* response - DELEG_NONE_EXT only */
0255     u32     op_create;          /* request */
0256     u32     op_createmode;      /* request */
0257     int     op_umask;           /* request */
0258     u32     op_bmval[3];        /* request */
0259     struct iattr    op_iattr;           /* UNCHECKED4, GUARDED4, EXCLUSIVE4_1 */
0260     nfs4_verifier   op_verf __attribute__((aligned(32)));
0261                         /* EXCLUSIVE4 */
0262     clientid_t  op_clientid;        /* request */
0263     struct xdr_netobj op_owner;           /* request */
0264     u32     op_seqid;           /* request */
0265     u32     op_share_access;    /* request */
0266     u32     op_share_deny;      /* request */
0267     u32     op_deleg_want;      /* request */
0268     stateid_t   op_stateid;         /* response */
0269     __be32      op_xdr_error;       /* see nfsd4_open_omfg() */
0270     u32     op_recall;          /* recall */
0271     struct nfsd4_change_info  op_cinfo; /* response */
0272     u32     op_rflags;          /* response */
0273     bool        op_truncate;        /* used during processing */
0274     bool        op_created;         /* used during processing */
0275     struct nfs4_openowner *op_openowner; /* used during processing */
0276     struct file *op_filp;           /* used during processing */
0277     struct nfs4_file *op_file;          /* used during processing */
0278     struct nfs4_ol_stateid *op_stp;     /* used during processing */
0279     struct nfs4_clnt_odstate *op_odstate; /* used during processing */
0280     struct nfs4_acl *op_acl;
0281     struct xdr_netobj op_label;
0282     struct svc_rqst *op_rqstp;
0283 };
0284 
0285 struct nfsd4_open_confirm {
0286     stateid_t   oc_req_stateid      /* request */;
0287     u32     oc_seqid            /* request */;
0288     stateid_t   oc_resp_stateid     /* response */;
0289 };
0290 
0291 struct nfsd4_open_downgrade {
0292     stateid_t       od_stateid;
0293     u32             od_seqid;
0294     u32             od_share_access;    /* request */
0295     u32     od_deleg_want;      /* request */
0296     u32             od_share_deny;      /* request */
0297 };
0298 
0299 
0300 struct nfsd4_read {
0301     stateid_t       rd_stateid;         /* request */
0302     u64         rd_offset;          /* request */
0303     u32         rd_length;          /* request */
0304     int         rd_vlen;
0305     struct nfsd_file    *rd_nf;
0306 
0307     struct svc_rqst     *rd_rqstp;          /* response */
0308     struct svc_fh       *rd_fhp;            /* response */
0309     u32         rd_eof;             /* response */
0310 };
0311 
0312 struct nfsd4_readdir {
0313     u64     rd_cookie;          /* request */
0314     nfs4_verifier   rd_verf;            /* request */
0315     u32     rd_dircount;        /* request */
0316     u32     rd_maxcount;        /* request */
0317     u32     rd_bmval[3];        /* request */
0318     struct svc_rqst *rd_rqstp;          /* response */
0319     struct svc_fh * rd_fhp;             /* response */
0320 
0321     struct readdir_cd   common;
0322     struct xdr_stream   *xdr;
0323     int         cookie_offset;
0324 };
0325 
0326 struct nfsd4_release_lockowner {
0327     clientid_t        rl_clientid;
0328     struct xdr_netobj rl_owner;
0329 };
0330 struct nfsd4_readlink {
0331     struct svc_rqst *rl_rqstp;          /* request */
0332     struct svc_fh * rl_fhp;             /* request */
0333 };
0334 
0335 struct nfsd4_remove {
0336     u32     rm_namelen;         /* request */
0337     char *      rm_name;            /* request */
0338     struct nfsd4_change_info  rm_cinfo; /* response */
0339 };
0340 
0341 struct nfsd4_rename {
0342     u32     rn_snamelen;        /* request */
0343     char *      rn_sname;           /* request */
0344     u32     rn_tnamelen;        /* request */
0345     char *      rn_tname;           /* request */
0346     struct nfsd4_change_info  rn_sinfo; /* response */
0347     struct nfsd4_change_info  rn_tinfo; /* response */
0348 };
0349 
0350 struct nfsd4_secinfo {
0351     u32 si_namelen;                 /* request */
0352     char *si_name;                  /* request */
0353     struct svc_export *si_exp;          /* response */
0354 };
0355 
0356 struct nfsd4_secinfo_no_name {
0357     u32 sin_style;                  /* request */
0358     struct svc_export *sin_exp;         /* response */
0359 };
0360 
0361 struct nfsd4_setattr {
0362     stateid_t   sa_stateid;         /* request */
0363     u32     sa_bmval[3];        /* request */
0364     struct iattr    sa_iattr;           /* request */
0365     struct nfs4_acl *sa_acl;
0366     struct xdr_netobj sa_label;
0367 };
0368 
0369 struct nfsd4_setclientid {
0370     nfs4_verifier   se_verf;            /* request */
0371     struct xdr_netobj se_name;
0372     u32     se_callback_prog;   /* request */
0373     u32     se_callback_netid_len;  /* request */
0374     char *      se_callback_netid_val;  /* request */
0375     u32     se_callback_addr_len;   /* request */
0376     char *      se_callback_addr_val;   /* request */
0377     u32     se_callback_ident;  /* request */
0378     clientid_t  se_clientid;        /* response */
0379     nfs4_verifier   se_confirm;         /* response */
0380 };
0381 
0382 struct nfsd4_setclientid_confirm {
0383     clientid_t  sc_clientid;
0384     nfs4_verifier   sc_confirm;
0385 };
0386 
0387 struct nfsd4_test_stateid_id {
0388     __be32          ts_id_status;
0389     stateid_t       ts_id_stateid;
0390     struct list_head    ts_id_list;
0391 };
0392 
0393 struct nfsd4_test_stateid {
0394     u32     ts_num_ids;
0395     struct list_head ts_stateid_list;
0396 };
0397 
0398 struct nfsd4_free_stateid {
0399     stateid_t   fr_stateid;         /* request */
0400 };
0401 
0402 /* also used for NVERIFY */
0403 struct nfsd4_verify {
0404     u32     ve_bmval[3];        /* request */
0405     u32     ve_attrlen;         /* request */
0406     char *      ve_attrval;         /* request */
0407 };
0408 
0409 struct nfsd4_write {
0410     stateid_t   wr_stateid;         /* request */
0411     u64     wr_offset;          /* request */
0412     u32     wr_stable_how;      /* request */
0413     u32     wr_buflen;          /* request */
0414     struct xdr_buf  wr_payload;         /* request */
0415 
0416     u32     wr_bytes_written;   /* response */
0417     u32     wr_how_written;     /* response */
0418     nfs4_verifier   wr_verifier;        /* response */
0419 };
0420 
0421 struct nfsd4_exchange_id {
0422     nfs4_verifier   verifier;
0423     struct xdr_netobj clname;
0424     u32     flags;
0425     clientid_t  clientid;
0426     u32     seqid;
0427     u32     spa_how;
0428     u32             spo_must_enforce[3];
0429     u32             spo_must_allow[3];
0430     struct xdr_netobj nii_domain;
0431     struct xdr_netobj nii_name;
0432     struct timespec64 nii_time;
0433 };
0434 
0435 struct nfsd4_sequence {
0436     struct nfs4_sessionid   sessionid;      /* request/response */
0437     u32         seqid;          /* request/response */
0438     u32         slotid;         /* request/response */
0439     u32         maxslots;       /* request/response */
0440     u32         cachethis;      /* request */
0441 #if 0
0442     u32         target_maxslots;    /* response */
0443 #endif /* not yet */
0444     u32         status_flags;       /* response */
0445 };
0446 
0447 struct nfsd4_destroy_session {
0448     struct nfs4_sessionid   sessionid;
0449 };
0450 
0451 struct nfsd4_destroy_clientid {
0452     clientid_t clientid;
0453 };
0454 
0455 struct nfsd4_reclaim_complete {
0456     u32 rca_one_fs;
0457 };
0458 
0459 struct nfsd4_deviceid {
0460     u64         fsid_idx;
0461     u32         generation;
0462     u32         pad;
0463 };
0464 
0465 struct nfsd4_layout_seg {
0466     u32         iomode;
0467     u64         offset;
0468     u64         length;
0469 };
0470 
0471 struct nfsd4_getdeviceinfo {
0472     struct nfsd4_deviceid   gd_devid;   /* request */
0473     u32         gd_layout_type; /* request */
0474     u32         gd_maxcount;    /* request */
0475     u32         gd_notify_types;/* request - response */
0476     void            *gd_device; /* response */
0477 };
0478 
0479 struct nfsd4_layoutget {
0480     u64         lg_minlength;   /* request */
0481     u32         lg_signal;  /* request */
0482     u32         lg_layout_type; /* request */
0483     u32         lg_maxcount;    /* request */
0484     stateid_t       lg_sid;     /* request/response */
0485     struct nfsd4_layout_seg lg_seg;     /* request/response */
0486     void            *lg_content;    /* response */
0487 };
0488 
0489 struct nfsd4_layoutcommit {
0490     stateid_t       lc_sid;     /* request */
0491     struct nfsd4_layout_seg lc_seg;     /* request */
0492     u32         lc_reclaim; /* request */
0493     u32         lc_newoffset;   /* request */
0494     u64         lc_last_wr; /* request */
0495     struct timespec64   lc_mtime;   /* request */
0496     u32         lc_layout_type; /* request */
0497     u32         lc_up_len;  /* layout length */
0498     void            *lc_up_layout;  /* decoded by callback */
0499     u32         lc_size_chg;    /* boolean for response */
0500     u64         lc_newsize; /* response */
0501 };
0502 
0503 struct nfsd4_layoutreturn {
0504     u32         lr_return_type; /* request */
0505     u32         lr_layout_type; /* request */
0506     struct nfsd4_layout_seg lr_seg;     /* request */
0507     u32         lr_reclaim; /* request */
0508     u32         lrf_body_len;   /* request */
0509     void            *lrf_body;  /* request */
0510     stateid_t       lr_sid;     /* request/response */
0511     u32         lrs_present;    /* response */
0512 };
0513 
0514 struct nfsd4_fallocate {
0515     /* request */
0516     stateid_t   falloc_stateid;
0517     loff_t      falloc_offset;
0518     u64     falloc_length;
0519 };
0520 
0521 struct nfsd4_clone {
0522     /* request */
0523     stateid_t   cl_src_stateid;
0524     stateid_t   cl_dst_stateid;
0525     u64     cl_src_pos;
0526     u64     cl_dst_pos;
0527     u64     cl_count;
0528 };
0529 
0530 struct nfsd42_write_res {
0531     u64         wr_bytes_written;
0532     u32         wr_stable_how;
0533     nfs4_verifier       wr_verifier;
0534     stateid_t       cb_stateid;
0535 };
0536 
0537 struct nfsd4_cb_offload {
0538     struct nfsd4_callback   co_cb;
0539     struct nfsd42_write_res co_res;
0540     __be32          co_nfserr;
0541     struct knfsd_fh     co_fh;
0542 };
0543 
0544 struct nfsd4_copy {
0545     /* request */
0546     stateid_t       cp_src_stateid;
0547     stateid_t       cp_dst_stateid;
0548     u64         cp_src_pos;
0549     u64         cp_dst_pos;
0550     u64         cp_count;
0551     struct nl4_server   *cp_src;
0552 
0553     unsigned long       cp_flags;
0554 #define NFSD4_COPY_F_STOPPED        (0)
0555 #define NFSD4_COPY_F_INTRA      (1)
0556 #define NFSD4_COPY_F_SYNCHRONOUS    (2)
0557 #define NFSD4_COPY_F_COMMITTED      (3)
0558 
0559     /* response */
0560     struct nfsd42_write_res cp_res;
0561     struct knfsd_fh     fh;
0562 
0563     struct nfs4_client      *cp_clp;
0564 
0565     struct nfsd_file        *nf_src;
0566     struct nfsd_file        *nf_dst;
0567 
0568     copy_stateid_t      cp_stateid;
0569 
0570     struct list_head    copies;
0571     struct task_struct  *copy_task;
0572     refcount_t      refcount;
0573 
0574     struct vfsmount     *ss_mnt;
0575     struct nfs_fh       c_fh;
0576     nfs4_stateid        stateid;
0577 };
0578 
0579 static inline void nfsd4_copy_set_sync(struct nfsd4_copy *copy, bool sync)
0580 {
0581     if (sync)
0582         set_bit(NFSD4_COPY_F_SYNCHRONOUS, &copy->cp_flags);
0583     else
0584         clear_bit(NFSD4_COPY_F_SYNCHRONOUS, &copy->cp_flags);
0585 }
0586 
0587 static inline bool nfsd4_copy_is_sync(const struct nfsd4_copy *copy)
0588 {
0589     return test_bit(NFSD4_COPY_F_SYNCHRONOUS, &copy->cp_flags);
0590 }
0591 
0592 static inline bool nfsd4_copy_is_async(const struct nfsd4_copy *copy)
0593 {
0594     return !test_bit(NFSD4_COPY_F_SYNCHRONOUS, &copy->cp_flags);
0595 }
0596 
0597 static inline bool nfsd4_ssc_is_inter(const struct nfsd4_copy *copy)
0598 {
0599     return !test_bit(NFSD4_COPY_F_INTRA, &copy->cp_flags);
0600 }
0601 
0602 struct nfsd4_seek {
0603     /* request */
0604     stateid_t   seek_stateid;
0605     loff_t      seek_offset;
0606     u32     seek_whence;
0607 
0608     /* response */
0609     u32     seek_eof;
0610     loff_t      seek_pos;
0611 };
0612 
0613 struct nfsd4_offload_status {
0614     /* request */
0615     stateid_t   stateid;
0616 
0617     /* response */
0618     u64     count;
0619     u32     status;
0620 };
0621 
0622 struct nfsd4_copy_notify {
0623     /* request */
0624     stateid_t       cpn_src_stateid;
0625     struct nl4_server   *cpn_dst;
0626 
0627     /* response */
0628     stateid_t       cpn_cnr_stateid;
0629     u64         cpn_sec;
0630     u32         cpn_nsec;
0631     struct nl4_server   *cpn_src;
0632 };
0633 
0634 struct nfsd4_op {
0635     u32                 opnum;
0636     __be32                  status;
0637     const struct nfsd4_operation        *opdesc;
0638     struct nfs4_replay          *replay;
0639     union nfsd4_op_u {
0640         struct nfsd4_access     access;
0641         struct nfsd4_close      close;
0642         struct nfsd4_commit     commit;
0643         struct nfsd4_create     create;
0644         struct nfsd4_delegreturn    delegreturn;
0645         struct nfsd4_getattr        getattr;
0646         struct svc_fh *         getfh;
0647         struct nfsd4_link       link;
0648         struct nfsd4_lock       lock;
0649         struct nfsd4_lockt      lockt;
0650         struct nfsd4_locku      locku;
0651         struct nfsd4_lookup     lookup;
0652         struct nfsd4_verify     nverify;
0653         struct nfsd4_open       open;
0654         struct nfsd4_open_confirm   open_confirm;
0655         struct nfsd4_open_downgrade open_downgrade;
0656         struct nfsd4_putfh      putfh;
0657         struct nfsd4_read       read;
0658         struct nfsd4_readdir        readdir;
0659         struct nfsd4_readlink       readlink;
0660         struct nfsd4_remove     remove;
0661         struct nfsd4_rename     rename;
0662         clientid_t          renew;
0663         struct nfsd4_secinfo        secinfo;
0664         struct nfsd4_setattr        setattr;
0665         struct nfsd4_setclientid    setclientid;
0666         struct nfsd4_setclientid_confirm setclientid_confirm;
0667         struct nfsd4_verify     verify;
0668         struct nfsd4_write      write;
0669         struct nfsd4_release_lockowner  release_lockowner;
0670 
0671         /* NFSv4.1 */
0672         struct nfsd4_exchange_id    exchange_id;
0673         struct nfsd4_backchannel_ctl    backchannel_ctl;
0674         struct nfsd4_bind_conn_to_session bind_conn_to_session;
0675         struct nfsd4_create_session create_session;
0676         struct nfsd4_destroy_session    destroy_session;
0677         struct nfsd4_destroy_clientid   destroy_clientid;
0678         struct nfsd4_sequence       sequence;
0679         struct nfsd4_reclaim_complete   reclaim_complete;
0680         struct nfsd4_test_stateid   test_stateid;
0681         struct nfsd4_free_stateid   free_stateid;
0682         struct nfsd4_getdeviceinfo  getdeviceinfo;
0683         struct nfsd4_layoutget      layoutget;
0684         struct nfsd4_layoutcommit   layoutcommit;
0685         struct nfsd4_layoutreturn   layoutreturn;
0686         struct nfsd4_secinfo_no_name    secinfo_no_name;
0687 
0688         /* NFSv4.2 */
0689         struct nfsd4_fallocate      allocate;
0690         struct nfsd4_fallocate      deallocate;
0691         struct nfsd4_clone      clone;
0692         struct nfsd4_copy       copy;
0693         struct nfsd4_offload_status offload_status;
0694         struct nfsd4_copy_notify    copy_notify;
0695         struct nfsd4_seek       seek;
0696 
0697         struct nfsd4_getxattr       getxattr;
0698         struct nfsd4_setxattr       setxattr;
0699         struct nfsd4_listxattrs     listxattrs;
0700         struct nfsd4_removexattr    removexattr;
0701     } u;
0702 };
0703 
0704 bool nfsd4_cache_this_op(struct nfsd4_op *);
0705 
0706 /*
0707  * Memory needed just for the duration of processing one compound:
0708  */
0709 struct svcxdr_tmpbuf {
0710     struct svcxdr_tmpbuf *next;
0711     char buf[];
0712 };
0713 
0714 struct nfsd4_compoundargs {
0715     /* scratch variables for XDR decode */
0716     struct xdr_stream       *xdr;
0717     struct svcxdr_tmpbuf        *to_free;
0718     struct svc_rqst         *rqstp;
0719 
0720     u32             taglen;
0721     char *              tag;
0722     u32             minorversion;
0723     u32             opcnt;
0724     struct nfsd4_op         *ops;
0725     struct nfsd4_op         iops[8];
0726     int             cachetype;
0727 };
0728 
0729 struct nfsd4_compoundres {
0730     /* scratch variables for XDR encode */
0731     struct xdr_stream       *xdr;
0732     struct svc_rqst *       rqstp;
0733 
0734     __be32              *statusp;
0735     u32             taglen;
0736     char *              tag;
0737     u32             opcnt;
0738 
0739     struct nfsd4_compound_state cstate;
0740 };
0741 
0742 static inline bool nfsd4_is_solo_sequence(struct nfsd4_compoundres *resp)
0743 {
0744     struct nfsd4_compoundargs *args = resp->rqstp->rq_argp;
0745     return resp->opcnt == 1 && args->ops[0].opnum == OP_SEQUENCE;
0746 }
0747 
0748 /*
0749  * The session reply cache only needs to cache replies that the client
0750  * actually asked us to.  But it's almost free for us to cache compounds
0751  * consisting of only a SEQUENCE op, so we may as well cache those too.
0752  * Also, the protocol doesn't give us a convenient response in the case
0753  * of a replay of a solo SEQUENCE op that wasn't cached
0754  * (RETRY_UNCACHED_REP can only be returned in the second op of a
0755  * compound).
0756  */
0757 static inline bool nfsd4_cache_this(struct nfsd4_compoundres *resp)
0758 {
0759     return (resp->cstate.slot->sl_flags & NFSD4_SLOT_CACHETHIS)
0760         || nfsd4_is_solo_sequence(resp);
0761 }
0762 
0763 static inline bool nfsd4_last_compound_op(struct svc_rqst *rqstp)
0764 {
0765     struct nfsd4_compoundres *resp = rqstp->rq_resp;
0766     struct nfsd4_compoundargs *argp = rqstp->rq_argp;
0767 
0768     return argp->opcnt == resp->opcnt;
0769 }
0770 
0771 const struct nfsd4_operation *OPDESC(struct nfsd4_op *op);
0772 int nfsd4_max_reply(struct svc_rqst *rqstp, struct nfsd4_op *op);
0773 void warn_on_nonidempotent_op(struct nfsd4_op *op);
0774 
0775 #define NFS4_SVC_XDRSIZE        sizeof(struct nfsd4_compoundargs)
0776 
0777 static inline void
0778 set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp)
0779 {
0780     BUG_ON(!fhp->fh_pre_saved);
0781     cinfo->atomic = (u32)(fhp->fh_post_saved && !fhp->fh_no_atomic_attr);
0782 
0783     cinfo->before_change = fhp->fh_pre_change;
0784     cinfo->after_change = fhp->fh_post_change;
0785 }
0786 
0787 
0788 bool nfsd4_mach_creds_match(struct nfs4_client *cl, struct svc_rqst *rqstp);
0789 bool nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, struct xdr_stream *xdr);
0790 bool nfs4svc_encode_compoundres(struct svc_rqst *rqstp, struct xdr_stream *xdr);
0791 __be32 nfsd4_check_resp_size(struct nfsd4_compoundres *, u32);
0792 void nfsd4_encode_operation(struct nfsd4_compoundres *, struct nfsd4_op *);
0793 void nfsd4_encode_replay(struct xdr_stream *xdr, struct nfsd4_op *op);
0794 __be32 nfsd4_encode_fattr_to_buf(__be32 **p, int words,
0795         struct svc_fh *fhp, struct svc_export *exp,
0796         struct dentry *dentry,
0797         u32 *bmval, struct svc_rqst *, int ignore_crossmnt);
0798 extern __be32 nfsd4_setclientid(struct svc_rqst *rqstp,
0799         struct nfsd4_compound_state *, union nfsd4_op_u *u);
0800 extern __be32 nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
0801         struct nfsd4_compound_state *, union nfsd4_op_u *u);
0802 extern __be32 nfsd4_exchange_id(struct svc_rqst *rqstp,
0803         struct nfsd4_compound_state *, union nfsd4_op_u *u);
0804 extern __be32 nfsd4_backchannel_ctl(struct svc_rqst *,
0805         struct nfsd4_compound_state *, union nfsd4_op_u *u);
0806 extern __be32 nfsd4_bind_conn_to_session(struct svc_rqst *,
0807         struct nfsd4_compound_state *, union nfsd4_op_u *u);
0808 extern __be32 nfsd4_create_session(struct svc_rqst *,
0809         struct nfsd4_compound_state *, union nfsd4_op_u *u);
0810 extern __be32 nfsd4_sequence(struct svc_rqst *,
0811         struct nfsd4_compound_state *, union nfsd4_op_u *u);
0812 extern void nfsd4_sequence_done(struct nfsd4_compoundres *resp);
0813 extern __be32 nfsd4_destroy_session(struct svc_rqst *,
0814         struct nfsd4_compound_state *, union nfsd4_op_u *u);
0815 extern __be32 nfsd4_destroy_clientid(struct svc_rqst *, struct nfsd4_compound_state *,
0816         union nfsd4_op_u *u);
0817 __be32 nfsd4_reclaim_complete(struct svc_rqst *, struct nfsd4_compound_state *,
0818         union nfsd4_op_u *u);
0819 extern __be32 nfsd4_process_open1(struct nfsd4_compound_state *,
0820         struct nfsd4_open *open, struct nfsd_net *nn);
0821 extern __be32 nfsd4_process_open2(struct svc_rqst *rqstp,
0822         struct svc_fh *current_fh, struct nfsd4_open *open);
0823 extern void nfsd4_cstate_clear_replay(struct nfsd4_compound_state *cstate);
0824 extern void nfsd4_cleanup_open_state(struct nfsd4_compound_state *cstate,
0825         struct nfsd4_open *open);
0826 extern __be32 nfsd4_open_confirm(struct svc_rqst *rqstp,
0827         struct nfsd4_compound_state *, union nfsd4_op_u *u);
0828 extern __be32 nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *,
0829         union nfsd4_op_u *u);
0830 extern __be32 nfsd4_open_downgrade(struct svc_rqst *rqstp,
0831         struct nfsd4_compound_state *, union nfsd4_op_u *u);
0832 extern __be32 nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *,
0833         union nfsd4_op_u *u);
0834 extern __be32 nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *,
0835         union nfsd4_op_u *u);
0836 extern __be32 nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *,
0837         union nfsd4_op_u *u);
0838 extern __be32
0839 nfsd4_release_lockowner(struct svc_rqst *rqstp,
0840         struct nfsd4_compound_state *, union nfsd4_op_u *u);
0841 extern void nfsd4_release_compoundargs(struct svc_rqst *rqstp);
0842 extern __be32 nfsd4_delegreturn(struct svc_rqst *rqstp,
0843         struct nfsd4_compound_state *, union nfsd4_op_u *u);
0844 extern __be32 nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *,
0845         union nfsd4_op_u *u);
0846 extern __be32 nfsd4_test_stateid(struct svc_rqst *rqstp,
0847         struct nfsd4_compound_state *, union nfsd4_op_u *);
0848 extern __be32 nfsd4_free_stateid(struct svc_rqst *rqstp,
0849         struct nfsd4_compound_state *, union nfsd4_op_u *);
0850 extern void nfsd4_bump_seqid(struct nfsd4_compound_state *, __be32 nfserr);
0851 
0852 enum nfsd4_op_flags {
0853     ALLOWED_WITHOUT_FH = 1 << 0,    /* No current filehandle required */
0854     ALLOWED_ON_ABSENT_FS = 1 << 1,  /* ops processed on absent fs */
0855     ALLOWED_AS_FIRST_OP = 1 << 2,   /* ops reqired first in compound */
0856     /* For rfc 5661 section 2.6.3.1.1: */
0857     OP_HANDLES_WRONGSEC = 1 << 3,
0858     OP_IS_PUTFH_LIKE = 1 << 4,
0859     /*
0860      * These are the ops whose result size we estimate before
0861      * encoding, to avoid performing an op then not being able to
0862      * respond or cache a response.  This includes writes and setattrs
0863      * as well as the operations usually called "nonidempotent":
0864      */
0865     OP_MODIFIES_SOMETHING = 1 << 5,
0866     /*
0867      * Cache compounds containing these ops in the xid-based drc:
0868      * We use the DRC for compounds containing non-idempotent
0869      * operations, *except* those that are 4.1-specific (since
0870      * sessions provide their own EOS), and except for stateful
0871      * operations other than setclientid and setclientid_confirm
0872      * (since sequence numbers provide EOS for open, lock, etc in
0873      * the v4.0 case).
0874      */
0875     OP_CACHEME = 1 << 6,
0876     /*
0877      * These are ops which clear current state id.
0878      */
0879     OP_CLEAR_STATEID = 1 << 7,
0880     /* Most ops return only an error on failure; some may do more: */
0881     OP_NONTRIVIAL_ERROR_ENCODE = 1 << 8,
0882 };
0883 
0884 struct nfsd4_operation {
0885     __be32 (*op_func)(struct svc_rqst *, struct nfsd4_compound_state *,
0886             union nfsd4_op_u *);
0887     void (*op_release)(union nfsd4_op_u *);
0888     u32 op_flags;
0889     char *op_name;
0890     /* Try to get response size before operation */
0891     u32 (*op_rsize_bop)(struct svc_rqst *, struct nfsd4_op *);
0892     void (*op_get_currentstateid)(struct nfsd4_compound_state *,
0893             union nfsd4_op_u *);
0894     void (*op_set_currentstateid)(struct nfsd4_compound_state *,
0895             union nfsd4_op_u *);
0896 };
0897 
0898 
0899 #endif