nfsd: fix bad offset use
[linux-3.10.git] / fs / nfsd / xdr4.h
index 83202a1..546f898 100644 (file)
@@ -1,6 +1,4 @@
 /*
- *  include/linux/nfsd/xdr4.h
- *
  *  Server-side types for NFSv4.
  *
  *  Copyright (c) 2002 The Regents of the University of Michigan.
 #define NFSD4_MAX_TAGLEN       128
 #define XDR_LEN(n)                     (((n) + 3) & ~3)
 
+#define CURRENT_STATE_ID_FLAG (1<<0)
+#define SAVED_STATE_ID_FLAG (1<<1)
+
+#define SET_STATE_ID(c, f) ((c)->sid_flags |= (f))
+#define HAS_STATE_ID(c, f) ((c)->sid_flags & (f))
+#define CLEAR_STATE_ID(c, f) ((c)->sid_flags &= ~(f))
+
 struct nfsd4_compound_state {
        struct svc_fh           current_fh;
        struct svc_fh           save_fh;
@@ -55,7 +60,11 @@ struct nfsd4_compound_state {
        __be32                  *datap;
        size_t                  iovlen;
        u32                     minorversion;
-       u32                     status;
+       __be32                  status;
+       stateid_t       current_stateid;
+       stateid_t       save_stateid;
+       /* to indicate current and saved state id presents */
+       u32             sid_flags;
 };
 
 static inline bool nfsd4_has_session(struct nfsd4_compound_state *cs)
@@ -83,7 +92,6 @@ struct nfsd4_access {
 struct nfsd4_close {
        u32             cl_seqid;           /* request */
        stateid_t       cl_stateid;         /* request+response */
-       struct nfs4_stateowner * cl_stateowner; /* response */
 };
 
 struct nfsd4_commit {
@@ -133,7 +141,7 @@ struct nfsd4_link {
 
 struct nfsd4_lock_denied {
        clientid_t      ld_clientid;
-       struct nfs4_stateowner   *ld_sop;
+       struct xdr_netobj       ld_owner;
        u64             ld_start;
        u64             ld_length;
        u32             ld_type;
@@ -167,9 +175,6 @@ struct nfsd4_lock {
                } ok;
                struct nfsd4_lock_denied        denied;
        } u;
-       /* The lk_replay_owner is the open owner in the open_to_lock_owner
-        * case and the lock owner otherwise: */
-       struct nfs4_stateowner *lk_replay_owner;
 };
 #define lk_new_open_seqid       v.new.open_seqid
 #define lk_new_open_stateid     v.new.open_stateid
@@ -190,7 +195,6 @@ struct nfsd4_lockt {
        struct xdr_netobj               lt_owner;
        u64                             lt_offset;
        u64                             lt_length;
-       struct nfs4_stateowner *        lt_stateowner;
        struct nfsd4_lock_denied        lt_denied;
 };
 
@@ -201,7 +205,6 @@ struct nfsd4_locku {
        stateid_t       lu_stateid;
        u64             lu_offset;
        u64             lu_length;
-       struct nfs4_stateowner  *lu_stateowner;
 };
 
 
@@ -220,40 +223,44 @@ struct nfsd4_open {
        struct xdr_netobj op_fname;         /* request - everything but CLAIM_PREV */
        u32             op_delegate_type;   /* request - CLAIM_PREV only */
        stateid_t       op_delegate_stateid; /* request - response */
+       u32             op_why_no_deleg;    /* response - DELEG_NONE_EXT only */
        u32             op_create;          /* request */
        u32             op_createmode;      /* request */
        u32             op_bmval[3];        /* request */
        struct iattr    iattr;              /* UNCHECKED4, GUARDED4, EXCLUSIVE4_1 */
-       nfs4_verifier   verf;               /* EXCLUSIVE4 */
+       nfs4_verifier   op_verf __attribute__((aligned(32)));
+                                           /* EXCLUSIVE4 */
        clientid_t      op_clientid;        /* request */
        struct xdr_netobj op_owner;           /* request */
        u32             op_seqid;           /* request */
        u32             op_share_access;    /* request */
        u32             op_share_deny;      /* request */
+       u32             op_deleg_want;      /* request */
        stateid_t       op_stateid;         /* response */
        u32             op_recall;          /* recall */
        struct nfsd4_change_info  op_cinfo; /* response */
        u32             op_rflags;          /* response */
-       int             op_truncate;        /* used during processing */
-       struct nfs4_stateowner *op_stateowner; /* used during processing */
+       bool            op_truncate;        /* used during processing */
+       bool            op_created;         /* used during processing */
+       struct nfs4_openowner *op_openowner; /* used during processing */
+       struct nfs4_file *op_file;          /* used during processing */
+       struct nfs4_ol_stateid *op_stp;     /* used during processing */
        struct nfs4_acl *op_acl;
 };
 #define op_iattr       iattr
-#define op_verf                verf
 
 struct nfsd4_open_confirm {
        stateid_t       oc_req_stateid          /* request */;
        u32             oc_seqid                /* request */;
        stateid_t       oc_resp_stateid         /* response */;
-       struct nfs4_stateowner * oc_stateowner; /* response */
 };
 
 struct nfsd4_open_downgrade {
        stateid_t       od_stateid;
        u32             od_seqid;
-       u32             od_share_access;
-       u32             od_share_deny;
-       struct nfs4_stateowner *od_stateowner;
+       u32             od_share_access;        /* request */
+       u32             od_deleg_want;          /* request */
+       u32             od_share_deny;          /* request */
 };
 
 
@@ -313,6 +320,11 @@ struct nfsd4_secinfo {
        struct svc_export *si_exp;                      /* response */
 };
 
+struct nfsd4_secinfo_no_name {
+       u32 sin_style;                                  /* request */
+       struct svc_export *sin_exp;                     /* response */
+};
+
 struct nfsd4_setattr {
        stateid_t       sa_stateid;         /* request */
        u32             sa_bmval[3];        /* request */
@@ -322,8 +334,7 @@ struct nfsd4_setattr {
 
 struct nfsd4_setclientid {
        nfs4_verifier   se_verf;            /* request */
-       u32             se_namelen;         /* request */
-       char *          se_name;            /* request */
+       struct xdr_netobj se_name;
        u32             se_callback_prog;   /* request */
        u32             se_callback_netid_len;  /* request */
        char *          se_callback_netid_val;  /* request */
@@ -339,6 +350,29 @@ struct nfsd4_setclientid_confirm {
        nfs4_verifier   sc_confirm;
 };
 
+struct nfsd4_saved_compoundargs {
+       __be32 *p;
+       __be32 *end;
+       int pagelen;
+       struct page **pagelist;
+};
+
+struct nfsd4_test_stateid_id {
+       __be32                  ts_id_status;
+       stateid_t               ts_id_stateid;
+       struct list_head        ts_id_list;
+};
+
+struct nfsd4_test_stateid {
+       u32             ts_num_ids;
+       struct list_head ts_stateid_list;
+};
+
+struct nfsd4_free_stateid {
+       stateid_t       fr_stateid;         /* request */
+       __be32          fr_status;          /* response */
+};
+
 /* also used for NVERIFY */
 struct nfsd4_verify {
        u32             ve_bmval[3];        /* request */
@@ -351,7 +385,8 @@ struct nfsd4_write {
        u64             wr_offset;          /* request */
        u32             wr_stable_how;      /* request */
        u32             wr_buflen;          /* request */
-       int             wr_vlen;
+       struct kvec     wr_head;
+       struct page **  wr_pagelist;        /* request */
 
        u32             wr_bytes_written;   /* response */
        u32             wr_how_written;     /* response */
@@ -375,14 +410,22 @@ struct nfsd4_sequence {
        u32                     cachethis;              /* request */
 #if 0
        u32                     target_maxslots;        /* response */
-       u32                     status_flags;           /* response */
 #endif /* not yet */
+       u32                     status_flags;           /* response */
 };
 
 struct nfsd4_destroy_session {
        struct nfs4_sessionid   sessionid;
 };
 
+struct nfsd4_destroy_clientid {
+       clientid_t clientid;
+};
+
+struct nfsd4_reclaim_complete {
+       u32 rca_one_fs;
+};
+
 struct nfsd4_op {
        int                                     opnum;
        __be32                                  status;
@@ -420,13 +463,20 @@ struct nfsd4_op {
 
                /* NFSv4.1 */
                struct nfsd4_exchange_id        exchange_id;
+               struct nfsd4_backchannel_ctl    backchannel_ctl;
+               struct nfsd4_bind_conn_to_session bind_conn_to_session;
                struct nfsd4_create_session     create_session;
                struct nfsd4_destroy_session    destroy_session;
                struct nfsd4_sequence           sequence;
+               struct nfsd4_reclaim_complete   reclaim_complete;
+               struct nfsd4_test_stateid       test_stateid;
+               struct nfsd4_free_stateid       free_stateid;
        } u;
        struct nfs4_replay *                    replay;
 };
 
+bool nfsd4_cache_this_op(struct nfsd4_op *);
+
 struct nfsd4_compoundargs {
        /* scratch variables for XDR decode */
        __be32 *                        p;
@@ -449,6 +499,7 @@ struct nfsd4_compoundargs {
        u32                             opcnt;
        struct nfsd4_op                 *ops;
        struct nfsd4_op                 iops[8];
+       int                             cachetype;
 };
 
 struct nfsd4_compoundres {
@@ -473,7 +524,16 @@ static inline bool nfsd4_is_solo_sequence(struct nfsd4_compoundres *resp)
 
 static inline bool nfsd4_not_cached(struct nfsd4_compoundres *resp)
 {
-       return !resp->cstate.slot->sl_cachethis || nfsd4_is_solo_sequence(resp);
+       return !(resp->cstate.slot->sl_flags & NFSD4_SLOT_CACHETHIS)
+               || nfsd4_is_solo_sequence(resp);
+}
+
+static inline bool nfsd4_last_compound_op(struct svc_rqst *rqstp)
+{
+       struct nfsd4_compoundres *resp = rqstp->rq_resp;
+       struct nfsd4_compoundargs *argp = rqstp->rq_argp;
+
+       return argp->opcnt == resp->opcnt;
 }
 
 #define NFS4_SVC_XDRSIZE               sizeof(struct nfsd4_compoundargs)
@@ -481,18 +541,17 @@ static inline bool nfsd4_not_cached(struct nfsd4_compoundres *resp)
 static inline void
 set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp)
 {
-       BUG_ON(!fhp->fh_pre_saved || !fhp->fh_post_saved);
-       cinfo->atomic = 1;
+       BUG_ON(!fhp->fh_pre_saved);
+       cinfo->atomic = fhp->fh_post_saved;
        cinfo->change_supported = IS_I_VERSION(fhp->fh_dentry->d_inode);
-       if (cinfo->change_supported) {
-               cinfo->before_change = fhp->fh_pre_change;
-               cinfo->after_change = fhp->fh_post_change;
-       } else {
-               cinfo->before_ctime_sec = fhp->fh_pre_ctime.tv_sec;
-               cinfo->before_ctime_nsec = fhp->fh_pre_ctime.tv_nsec;
-               cinfo->after_ctime_sec = fhp->fh_post_attr.ctime.tv_sec;
-               cinfo->after_ctime_nsec = fhp->fh_post_attr.ctime.tv_nsec;
-       }
+
+       cinfo->before_change = fhp->fh_pre_change;
+       cinfo->after_change = fhp->fh_post_change;
+       cinfo->before_ctime_sec = fhp->fh_pre_ctime.tv_sec;
+       cinfo->before_ctime_nsec = fhp->fh_pre_ctime.tv_nsec;
+       cinfo->after_ctime_sec = fhp->fh_post_attr.ctime.tv_sec;
+       cinfo->after_ctime_nsec = fhp->fh_post_attr.ctime.tv_nsec;
+
 }
 
 int nfs4svc_encode_voidres(struct svc_rqst *, __be32 *, void *);
@@ -500,10 +559,11 @@ int nfs4svc_decode_compoundargs(struct svc_rqst *, __be32 *,
                struct nfsd4_compoundargs *);
 int nfs4svc_encode_compoundres(struct svc_rqst *, __be32 *,
                struct nfsd4_compoundres *);
+__be32 nfsd4_check_resp_size(struct nfsd4_compoundres *, u32);
 void nfsd4_encode_operation(struct nfsd4_compoundres *, struct nfsd4_op *);
 void nfsd4_encode_replay(struct nfsd4_compoundres *resp, struct nfsd4_op *op);
 __be32 nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
-                      struct dentry *dentry, __be32 *buffer, int *countp,
+                      struct dentry *dentry, __be32 **buffer, int countp,
                       u32 *bmval, struct svc_rqst *, int ignore_crossmnt);
 extern __be32 nfsd4_setclientid(struct svc_rqst *rqstp,
                struct nfsd4_compound_state *,
@@ -515,9 +575,10 @@ extern void nfsd4_store_cache_entry(struct nfsd4_compoundres *resp);
 extern __be32 nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
                struct nfsd4_sequence *seq);
 extern __be32 nfsd4_exchange_id(struct svc_rqst *rqstp,
-               struct nfsd4_compound_state *,
-struct nfsd4_exchange_id *);
-               extern __be32 nfsd4_create_session(struct svc_rqst *,
+               struct nfsd4_compound_state *, struct nfsd4_exchange_id *);
+extern __be32 nfsd4_backchannel_ctl(struct svc_rqst *, struct nfsd4_compound_state *, struct nfsd4_backchannel_ctl *);
+extern __be32 nfsd4_bind_conn_to_session(struct svc_rqst *, struct nfsd4_compound_state *, struct nfsd4_bind_conn_to_session *);
+extern __be32 nfsd4_create_session(struct svc_rqst *,
                struct nfsd4_compound_state *,
                struct nfsd4_create_session *);
 extern __be32 nfsd4_sequence(struct svc_rqst *,
@@ -526,10 +587,13 @@ extern __be32 nfsd4_sequence(struct svc_rqst *,
 extern __be32 nfsd4_destroy_session(struct svc_rqst *,
                struct nfsd4_compound_state *,
                struct nfsd4_destroy_session *);
+extern __be32 nfsd4_destroy_clientid(struct svc_rqst *, struct nfsd4_compound_state *, struct nfsd4_destroy_clientid *);
+__be32 nfsd4_reclaim_complete(struct svc_rqst *, struct nfsd4_compound_state *, struct nfsd4_reclaim_complete *);
 extern __be32 nfsd4_process_open1(struct nfsd4_compound_state *,
-               struct nfsd4_open *open);
+               struct nfsd4_open *open, struct nfsd_net *nn);
 extern __be32 nfsd4_process_open2(struct svc_rqst *rqstp,
                struct svc_fh *current_fh, struct nfsd4_open *open);
+extern void nfsd4_cleanup_open_state(struct nfsd4_open *open, __be32 status);
 extern __be32 nfsd4_open_confirm(struct svc_rqst *rqstp,
                struct nfsd4_compound_state *, struct nfsd4_open_confirm *oc);
 extern __be32 nfsd4_close(struct svc_rqst *rqstp,
@@ -550,11 +614,15 @@ extern __be32
 nfsd4_release_lockowner(struct svc_rqst *rqstp,
                struct nfsd4_compound_state *,
                struct nfsd4_release_lockowner *rlockowner);
-extern void nfsd4_release_compoundargs(struct nfsd4_compoundargs *);
+extern int nfsd4_release_compoundargs(void *rq, __be32 *p, void *resp);
 extern __be32 nfsd4_delegreturn(struct svc_rqst *rqstp,
                struct nfsd4_compound_state *, struct nfsd4_delegreturn *dr);
 extern __be32 nfsd4_renew(struct svc_rqst *rqstp,
                          struct nfsd4_compound_state *, clientid_t *clid);
+extern __be32 nfsd4_test_stateid(struct svc_rqst *rqstp,
+               struct nfsd4_compound_state *, struct nfsd4_test_stateid *test_stateid);
+extern __be32 nfsd4_free_stateid(struct svc_rqst *rqstp,
+               struct nfsd4_compound_state *, struct nfsd4_free_stateid *free_stateid);
 #endif
 
 /*