linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / include / linux / nfs_fs.h
index 6246101..b4dc6e2 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/pagemap.h>
 #include <linux/rwsem.h>
 #include <linux/wait.h>
-#include <linux/uio.h>
 
 #include <linux/nfs_fs_sb.h>
 
@@ -28,7 +27,8 @@
 #include <linux/nfs3.h>
 #include <linux/nfs4.h>
 #include <linux/nfs_xdr.h>
-#include <linux/workqueue.h>
+#include <linux/rwsem.h>
+#include <linux/mempool.h>
 
 /*
  * Enable debugging support for nfs client.
 # define NFS_DEBUG
 #endif
 
-#define NFS_MAX_FILE_IO_BUFFER_SIZE    32768
-#define NFS_DEF_FILE_IO_BUFFER_SIZE    4096
-
-/*
- * The upper limit on timeouts for the exponential backoff algorithm.
- */
-#define NFS_WRITEBACK_DELAY            (5*HZ)
-#define NFS_WRITEBACK_LOCKDELAY                (60*HZ)
-#define NFS_COMMIT_DELAY               (5*HZ)
+/* Default timeout values */
+#define NFS_MAX_UDP_TIMEOUT    (60*HZ)
+#define NFS_MAX_TCP_TIMEOUT    (600*HZ)
 
 /*
  * superblock magic number for NFS
@@ -58,9 +52,6 @@
  */
 #define NFS_RPC_SWAPFLAGS              (RPC_TASK_SWAPPER|RPC_TASK_ROOTCREDS)
 
-#define NFS_RW_SYNC            0x0001  /* O_SYNC handling */
-#define NFS_RW_SWAP            0x0002  /* This is a swap request */
-
 /*
  * When flushing a cluster of dirty pages, there can be different
  * strategies:
 #define FLUSH_STABLE           4       /* commit to stable storage */
 #define FLUSH_LOWPRI           8       /* low priority background flush */
 #define FLUSH_HIGHPRI          16      /* high priority memory reclaim flush */
+#define FLUSH_NOCOMMIT         32      /* Don't send the NFSv3/v4 COMMIT */
 
 #ifdef __KERNEL__
 
 /*
- * NFSv3 Access mode cache
+ * NFSv3/v4 Access mode cache entry
  */
-struct nfs_access_cache {
+struct nfs_access_entry {
        unsigned long           jiffies;
        struct rpc_cred *       cred;
        int                     mask;
-       int                     err;
 };
 
+struct nfs4_state;
+struct nfs_open_context {
+       atomic_t count;
+       struct dentry *dentry;
+       struct rpc_cred *cred;
+       struct nfs4_state *state;
+       fl_owner_t lockowner;
+       int mode;
+       int error;
+
+       struct list_head list;
+
+       __u64 dir_cookie;
+};
+
+/*
+ * NFSv4 delegation
+ */
+struct nfs_delegation;
+
+struct posix_acl;
+
 /*
  * nfs fs inode data in memory
  */
@@ -101,7 +114,8 @@ struct nfs_inode {
        /*
         * Various flags
         */
-       unsigned int            flags;
+       unsigned long           flags;                  /* atomic bit ops */
+       unsigned long           cache_validity;         /* bit mask */
 
        /*
         * read_cache_jiffies is when we started read-caching this inode,
@@ -120,12 +134,12 @@ struct nfs_inode {
         *
         *      mtime != read_cache_mtime
         */
-       unsigned long           readdir_timestamp;
        unsigned long           read_cache_jiffies;
        unsigned long           attrtimeo;
        unsigned long           attrtimeo_timestamp;
        __u64                   change_attr;            /* v4 only */
 
+       unsigned long           last_updated;
        /* "Generation counter" for the attribute cache. This is
         * bumped whenever we update the metadata on the
         * server.
@@ -137,7 +151,11 @@ struct nfs_inode {
         */
        atomic_t                data_updates;
 
-       struct nfs_access_cache cache_access;
+       struct nfs_access_entry cache_access;
+#ifdef CONFIG_NFS_V3_ACL
+       struct posix_acl        *acl_access;
+       struct posix_acl        *acl_default;
+#endif
 
        /*
         * This is the cookie verifier used for NFSv3 readdir
@@ -148,6 +166,7 @@ struct nfs_inode {
        /*
         * This is the list of dirty unwritten pages.
         */
+       spinlock_t              req_lock;
        struct list_head        dirty;
        struct list_head        commit;
        struct radix_tree_root  nfs_page_tree;
@@ -156,28 +175,36 @@ struct nfs_inode {
                                ncommit,
                                npages;
 
-       /* Credentials for shared mmap */
-       struct rpc_cred         *mm_cred;
-
-       wait_queue_head_t       nfs_i_wait;
+       /* Open contexts for shared mmap writes */
+       struct list_head        open_files;
 
 #ifdef CONFIG_NFS_V4
+       struct nfs4_cached_acl  *nfs4_acl;
         /* NFSv4 state */
        struct list_head        open_states;
+       struct nfs_delegation   *delegation;
+       int                      delegation_state;
+       struct rw_semaphore     rwsem;
 #endif /* CONFIG_NFS_V4*/
-
        struct inode            vfs_inode;
 };
 
 /*
- * Legal inode flag values
+ * Cache validity bit flags
+ */
+#define NFS_INO_INVALID_ATTR   0x0001          /* cached attrs are invalid */
+#define NFS_INO_INVALID_DATA   0x0002          /* cached data is invalid */
+#define NFS_INO_INVALID_ATIME  0x0004          /* cached atime is invalid */
+#define NFS_INO_INVALID_ACCESS 0x0008          /* cached access cred invalid */
+#define NFS_INO_INVALID_ACL    0x0010          /* cached acls are invalid */
+#define NFS_INO_REVAL_PAGECACHE        0x0020          /* must revalidate pagecache */
+
+/*
+ * Bit offsets in flags field
  */
-#define NFS_INO_STALE          0x0001          /* possible stale inode */
-#define NFS_INO_ADVISE_RDPLUS   0x0002          /* advise readdirplus */
-#define NFS_INO_REVALIDATING   0x0004          /* revalidating attrs */
-#define NFS_INO_INVALID_ATTR   0x0008          /* cached attrs are invalid */
-#define NFS_INO_INVALID_DATA   0x0010          /* cached data is invalid */
-#define NFS_INO_INVALID_ATIME  0x0020          /* cached atime is invalid */
+#define NFS_INO_REVALIDATING   (0)             /* revalidating attrs */
+#define NFS_INO_ADVISE_RDPLUS  (1)             /* advise readdirplus */
+#define NFS_INO_STALE          (2)             /* possible stale inode */
 
 static inline struct nfs_inode *NFS_I(struct inode *inode)
 {
@@ -203,8 +230,7 @@ static inline struct nfs_inode *NFS_I(struct inode *inode)
 #define NFS_ATTRTIMEO_UPDATE(inode)    (NFS_I(inode)->attrtimeo_timestamp)
 
 #define NFS_FLAGS(inode)               (NFS_I(inode)->flags)
-#define NFS_REVALIDATING(inode)                (NFS_FLAGS(inode) & NFS_INO_REVALIDATING)
-#define NFS_STALE(inode)               (NFS_FLAGS(inode) & NFS_INO_STALE)
+#define NFS_STALE(inode)               (test_bit(NFS_INO_STALE, &NFS_FLAGS(inode)))
 
 #define NFS_FILEID(inode)              (NFS_I(inode)->fileid)
 
@@ -213,10 +239,17 @@ static inline int nfs_caches_unstable(struct inode *inode)
        return atomic_read(&NFS_I(inode)->data_updates) != 0;
 }
 
+static inline void nfs_mark_for_revalidate(struct inode *inode)
+{
+       spin_lock(&inode->i_lock);
+       NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS;
+       spin_unlock(&inode->i_lock);
+}
+
 static inline void NFS_CACHEINV(struct inode *inode)
 {
        if (!nfs_caches_unstable(inode))
-               NFS_FLAGS(inode) |= NFS_INO_INVALID_ATTR;
+               nfs_mark_for_revalidate(inode);
 }
 
 static inline int nfs_server_capable(struct inode *inode, int cap)
@@ -226,13 +259,7 @@ static inline int nfs_server_capable(struct inode *inode, int cap)
 
 static inline int NFS_USE_READDIRPLUS(struct inode *inode)
 {
-       return NFS_FLAGS(inode) & NFS_INO_ADVISE_RDPLUS;
-}
-
-static inline
-loff_t page_offset(struct page *page)
-{
-       return ((loff_t)page->index) << PAGE_CACHE_SHIFT;
+       return test_bit(NFS_INO_ADVISE_RDPLUS, &NFS_FLAGS(inode));
 }
 
 /**
@@ -256,57 +283,93 @@ static inline long nfs_save_change_attribute(struct inode *inode)
 static inline int nfs_verify_change_attribute(struct inode *inode, unsigned long chattr)
 {
        return !nfs_caches_unstable(inode)
-               && chattr == NFS_I(inode)->cache_change_attribute;
+               && time_after_eq(chattr, NFS_I(inode)->cache_change_attribute);
 }
 
 /*
  * linux/fs/nfs/inode.c
  */
+extern int nfs_sync_mapping(struct address_space *mapping);
 extern void nfs_zap_caches(struct inode *);
 extern struct inode *nfs_fhget(struct super_block *, struct nfs_fh *,
                                struct nfs_fattr *);
 extern int nfs_refresh_inode(struct inode *, struct nfs_fattr *);
+extern int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr);
 extern int nfs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
 extern int nfs_permission(struct inode *, int, struct nameidata *);
-extern void nfs_set_mmcred(struct inode *, struct rpc_cred *);
+extern int nfs_access_get_cached(struct inode *, struct rpc_cred *, struct nfs_access_entry *);
+extern void nfs_access_add_cache(struct inode *, struct nfs_access_entry *);
 extern int nfs_open(struct inode *, struct file *);
 extern int nfs_release(struct inode *, struct file *);
+extern int nfs_attribute_timeout(struct inode *inode);
+extern int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode);
 extern int __nfs_revalidate_inode(struct nfs_server *, struct inode *);
+extern void nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping);
 extern int nfs_setattr(struct dentry *, struct iattr *);
+extern void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr);
 extern void nfs_begin_attr_update(struct inode *);
 extern void nfs_end_attr_update(struct inode *);
 extern void nfs_begin_data_update(struct inode *);
 extern void nfs_end_data_update(struct inode *);
-extern void nfs_end_data_update_defer(struct inode *);
+extern struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, struct rpc_cred *cred);
+extern struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx);
+extern void put_nfs_open_context(struct nfs_open_context *ctx);
+extern void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx);
+extern struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_cred *cred, int mode);
+extern void nfs_file_clear_open_context(struct file *filp);
 
 /* linux/net/ipv4/ipconfig.c: trims ip addr off front of name, too. */
 extern u32 root_nfs_parse_addr(char *name); /*__init*/
 
+static inline void nfs_fattr_init(struct nfs_fattr *fattr)
+{
+       fattr->valid = 0;
+       fattr->time_start = jiffies;
+}
+
 /*
  * linux/fs/nfs/file.c
  */
 extern struct inode_operations nfs_file_inode_operations;
+#ifdef CONFIG_NFS_V3
+extern struct inode_operations nfs3_file_inode_operations;
+#endif /* CONFIG_NFS_V3 */
 extern struct file_operations nfs_file_operations;
 extern struct address_space_operations nfs_file_aops;
 
-static __inline__ struct rpc_cred *
-nfs_file_cred(struct file *file)
+static inline struct rpc_cred *nfs_file_cred(struct file *file)
 {
-       struct rpc_cred *cred = NULL;
-       if (file)
-               cred = (struct rpc_cred *)file->private_data;
-#ifdef RPC_DEBUG
-       BUG_ON(cred && cred->cr_magic != RPCAUTH_CRED_MAGIC);
-#endif
-       return cred;
+       if (file != NULL) {
+               struct nfs_open_context *ctx;
+
+               ctx = (struct nfs_open_context*)file->private_data;
+               return ctx->cred;
+       }
+       return NULL;
 }
 
+/*
+ * linux/fs/nfs/xattr.c
+ */
+#ifdef CONFIG_NFS_V3_ACL
+extern ssize_t nfs3_listxattr(struct dentry *, char *, size_t);
+extern ssize_t nfs3_getxattr(struct dentry *, const char *, void *, size_t);
+extern int nfs3_setxattr(struct dentry *, const char *,
+                       const void *, size_t, int);
+extern int nfs3_removexattr (struct dentry *, const char *name);
+#else
+# define nfs3_listxattr NULL
+# define nfs3_getxattr NULL
+# define nfs3_setxattr NULL
+# define nfs3_removexattr NULL
+#endif
+
 /*
  * linux/fs/nfs/direct.c
  */
 extern ssize_t nfs_direct_IO(int, struct kiocb *, const struct iovec *, loff_t,
                        unsigned long);
-extern ssize_t nfs_file_direct_read(struct kiocb *iocb, char *buf,
+extern ssize_t nfs_file_direct_read(struct kiocb *iocb, char __user *buf,
                        size_t count, loff_t pos);
 extern ssize_t nfs_file_direct_write(struct kiocb *iocb, const char __user *buf,
                        size_t count, loff_t pos);
@@ -315,18 +378,29 @@ extern ssize_t nfs_file_direct_write(struct kiocb *iocb, const char __user *buf,
  * linux/fs/nfs/dir.c
  */
 extern struct inode_operations nfs_dir_inode_operations;
+#ifdef CONFIG_NFS_V3
+extern struct inode_operations nfs3_dir_inode_operations;
+#endif /* CONFIG_NFS_V3 */
 extern struct file_operations nfs_dir_operations;
 extern struct dentry_operations nfs_dentry_operations;
 
+extern int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fh, struct nfs_fattr *fattr);
+
 /*
  * linux/fs/nfs/symlink.c
  */
 extern struct inode_operations nfs_symlink_inode_operations;
 
 /*
- * linux/fs/nfs/locks.c
+ * linux/fs/nfs/sysctl.c
  */
-extern int nfs_lock(struct file *, int, struct file_lock *);
+#ifdef CONFIG_SYSCTL
+extern int nfs_register_sysctl(void);
+extern void nfs_unregister_sysctl(void);
+#else
+#define nfs_register_sysctl() 0
+#define nfs_unregister_sysctl() do { } while(0)
+#endif
 
 /*
  * linux/fs/nfs/unlink.c
@@ -341,10 +415,12 @@ extern int  nfs_writepage(struct page *page, struct writeback_control *wbc);
 extern int  nfs_writepages(struct address_space *, struct writeback_control *);
 extern int  nfs_flush_incompatible(struct file *file, struct page *page);
 extern int  nfs_updatepage(struct file *, struct page *, unsigned int, unsigned int);
-extern void nfs_writeback_done(struct rpc_task *task);
+extern void nfs_writeback_done(struct rpc_task *task, void *data);
+extern void nfs_writedata_release(void *data);
 
 #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
-extern void nfs_commit_done(struct rpc_task *);
+extern void nfs_commit_done(struct rpc_task *, void *data);
+extern void nfs_commit_release(void *data);
 #endif
 
 /*
@@ -352,14 +428,11 @@ extern void nfs_commit_done(struct rpc_task *);
  * return value!)
  */
 extern int  nfs_sync_inode(struct inode *, unsigned long, unsigned int, int);
-extern int  nfs_flush_inode(struct inode *, unsigned long, unsigned int, int);
-extern int  nfs_flush_list(struct list_head *, int, int);
 #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
-extern int  nfs_commit_inode(struct inode *, unsigned long, unsigned int, int);
-extern int  nfs_commit_list(struct list_head *, int);
+extern int  nfs_commit_inode(struct inode *, int);
 #else
 static inline int
-nfs_commit_inode(struct inode *inode, unsigned long idx_start, unsigned int npages, int how)
+nfs_commit_inode(struct inode *inode, int how)
 {
        return 0;
 }
@@ -393,10 +466,40 @@ static inline int nfs_wb_page(struct inode *inode, struct page* page)
        return nfs_wb_page_priority(inode, page, 0);
 }
 
-/* Hack for future NFS swap support */
-#ifndef IS_SWAPFILE
-# define IS_SWAPFILE(inode)    (0)
-#endif
+/*
+ * Allocate and free nfs_write_data structures
+ */
+extern mempool_t *nfs_wdata_mempool;
+
+static inline struct nfs_write_data *nfs_writedata_alloc(unsigned int pagecount)
+{
+       struct nfs_write_data *p = mempool_alloc(nfs_wdata_mempool, SLAB_NOFS);
+
+       if (p) {
+               memset(p, 0, sizeof(*p));
+               INIT_LIST_HEAD(&p->pages);
+               if (pagecount < NFS_PAGEVEC_SIZE)
+                       p->pagevec = &p->page_array[0];
+               else {
+                       size_t size = ++pagecount * sizeof(struct page *);
+                       p->pagevec = kmalloc(size, GFP_NOFS);
+                       if (p->pagevec) {
+                               memset(p->pagevec, 0, size);
+                       } else {
+                               mempool_free(p, nfs_wdata_mempool);
+                               p = NULL;
+                       }
+               }
+       }
+       return p;
+}
+
+static inline void nfs_writedata_free(struct nfs_write_data *p)
+{
+       if (p && (p->pagevec != &p->page_array[0]))
+               kfree(p->pagevec);
+       mempool_free(p, nfs_wdata_mempool);
+}
 
 /*
  * linux/fs/nfs/read.c
@@ -404,42 +507,79 @@ static inline int nfs_wb_page(struct inode *inode, struct page* page)
 extern int  nfs_readpage(struct file *, struct page *);
 extern int  nfs_readpages(struct file *, struct address_space *,
                struct list_head *, unsigned);
-extern int  nfs_pagein_list(struct list_head *, int);
-extern void nfs_readpage_result(struct rpc_task *);
+extern void nfs_readpage_result(struct rpc_task *, void *);
+extern void  nfs_readdata_release(void *data);
 
-/*
- * linux/fs/mount_clnt.c
- * (Used only by nfsroot module)
- */
-extern int  nfsroot_mount(struct sockaddr_in *, char *, struct nfs_fh *,
-               int, int);
 
 /*
- * inline functions
+ * Allocate and free nfs_read_data structures
  */
+extern mempool_t *nfs_rdata_mempool;
 
-static inline int nfs_attribute_timeout(struct inode *inode)
+static inline struct nfs_read_data *nfs_readdata_alloc(unsigned int pagecount)
 {
-       struct nfs_inode *nfsi = NFS_I(inode);
+       struct nfs_read_data *p = mempool_alloc(nfs_rdata_mempool, SLAB_NOFS);
+
+       if (p) {
+               memset(p, 0, sizeof(*p));
+               INIT_LIST_HEAD(&p->pages);
+               if (pagecount < NFS_PAGEVEC_SIZE)
+                       p->pagevec = &p->page_array[0];
+               else {
+                       size_t size = ++pagecount * sizeof(struct page *);
+                       p->pagevec = kmalloc(size, GFP_NOFS);
+                       if (p->pagevec) {
+                               memset(p->pagevec, 0, size);
+                       } else {
+                               mempool_free(p, nfs_rdata_mempool);
+                               p = NULL;
+                       }
+               }
+       }
+       return p;
+}
 
-       return time_after(jiffies, nfsi->read_cache_jiffies+nfsi->attrtimeo);
+static inline void nfs_readdata_free(struct nfs_read_data *p)
+{
+       if (p && (p->pagevec != &p->page_array[0]))
+               kfree(p->pagevec);
+       mempool_free(p, nfs_rdata_mempool);
 }
 
-/**
- * nfs_revalidate_inode - Revalidate the inode attributes
- * @server - pointer to nfs_server struct
- * @inode - pointer to inode struct
- *
- * Updates inode attribute information by retrieving the data from the server.
+/*
+ * linux/fs/nfs3proc.c
  */
-static inline int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
+#ifdef CONFIG_NFS_V3_ACL
+extern struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type);
+extern int nfs3_proc_setacl(struct inode *inode, int type,
+                           struct posix_acl *acl);
+extern int nfs3_proc_set_default_acl(struct inode *dir, struct inode *inode,
+               mode_t mode);
+extern void nfs3_forget_cached_acls(struct inode *inode);
+#else
+static inline int nfs3_proc_set_default_acl(struct inode *dir,
+                                           struct inode *inode,
+                                           mode_t mode)
 {
-       if (!(NFS_FLAGS(inode) & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA))
-                       && !nfs_attribute_timeout(inode))
-               return NFS_STALE(inode) ? -ESTALE : 0;
-       return __nfs_revalidate_inode(server, inode);
+       return 0;
 }
 
+static inline void nfs3_forget_cached_acls(struct inode *inode)
+{
+}
+#endif /* CONFIG_NFS_V3_ACL */
+
+/*
+ * linux/fs/mount_clnt.c
+ * (Used only by nfsroot module)
+ */
+extern int  nfsroot_mount(struct sockaddr_in *, char *, struct nfs_fh *,
+               int, int);
+
+/*
+ * inline functions
+ */
+
 static inline loff_t
 nfs_size_to_loff_t(__u64 size)
 {
@@ -477,213 +617,6 @@ extern void * nfs_root_data(void);
 
 #define NFS_JUKEBOX_RETRY_TIME (5 * HZ)
 
-#ifdef CONFIG_NFS_V4
-
-struct idmap;
-
-/*
- * In a seqid-mutating op, this macro controls which error return
- * values trigger incrementation of the seqid.
- *
- * from rfc 3010:
- * The client MUST monotonically increment the sequence number for the
- * CLOSE, LOCK, LOCKU, OPEN, OPEN_CONFIRM, and OPEN_DOWNGRADE
- * operations.  This is true even in the event that the previous
- * operation that used the sequence number received an error.  The only
- * exception to this rule is if the previous operation received one of
- * the following errors: NFSERR_STALE_CLIENTID, NFSERR_STALE_STATEID,
- * NFSERR_BAD_STATEID, NFSERR_BAD_SEQID, NFSERR_BADXDR,
- * NFSERR_RESOURCE, NFSERR_NOFILEHANDLE.
- *
- */
-#define seqid_mutating_err(err)       \
-(((err) != NFSERR_STALE_CLIENTID) &&  \
- ((err) != NFSERR_STALE_STATEID)  &&  \
- ((err) != NFSERR_BAD_STATEID)    &&  \
- ((err) != NFSERR_BAD_SEQID)      &&  \
- ((err) != NFSERR_BAD_XDR)        &&  \
- ((err) != NFSERR_RESOURCE)       &&  \
- ((err) != NFSERR_NOFILEHANDLE))
-
-enum nfs4_client_state {
-       NFS4CLNT_OK  = 0,
-       NFS4CLNT_NEW,
-       NFS4CLNT_SETUP_STATE,
-};
-
-/*
- * The nfs4_client identifies our client state to the server.
- */
-struct nfs4_client {
-       struct list_head        cl_servers;     /* Global list of servers */
-       struct in_addr          cl_addr;        /* Server identifier */
-       u64                     cl_clientid;    /* constant */
-       nfs4_verifier           cl_confirm;
-       unsigned long           cl_state;
-       long                    cl_generation;
-
-       u32                     cl_lockowner_id;
-
-       /*
-        * The following rwsem ensures exclusive access to the server
-        * while we recover the state following a lease expiration.
-        */
-       struct rw_semaphore     cl_sem;
-
-       struct list_head        cl_state_owners;
-       struct list_head        cl_unused;
-       int                     cl_nunused;
-       spinlock_t              cl_lock;
-       atomic_t                cl_count;
-
-       struct rpc_clnt *       cl_rpcclient;
-       struct rpc_cred *       cl_cred;
-
-       struct list_head        cl_superblocks; /* List of nfs_server structs */
-
-       unsigned long           cl_lease_time;
-       unsigned long           cl_last_renewal;
-       struct work_struct      cl_renewd;
-       struct work_struct      cl_recoverd;
-
-       wait_queue_head_t       cl_waitq;
-       struct rpc_wait_queue   cl_rpcwaitq;
-
-       /* idmapper */
-       struct idmap *          cl_idmap;
-
-       /* Our own IP address, as a null-terminated string.
-        * This is used to generate the clientid, and the callback address.
-        */
-       char                    cl_ipaddr[16];
-};
-
-/*
- * NFS4 state_owners and lock_owners are simply labels for ordered
- * sequences of RPC calls. Their sole purpose is to provide once-only
- * semantics by allowing the server to identify replayed requests.
- *
- * The ->so_sema is held during all state_owner seqid-mutating operations:
- * OPEN, OPEN_DOWNGRADE, and CLOSE. Its purpose is to properly serialize
- * so_seqid.
- */
-struct nfs4_state_owner {
-       struct list_head     so_list;    /* per-clientid list of state_owners */
-       struct nfs4_client   *so_client;
-       u32                  so_id;      /* 32-bit identifier, unique */
-       struct semaphore     so_sema;
-       u32                  so_seqid;   /* protected by so_sema */
-       unsigned int         so_flags;   /* protected by so_sema */
-       atomic_t             so_count;
-       long                 so_generation;
-
-       struct rpc_cred      *so_cred;   /* Associated cred */
-       struct list_head     so_states;
-};
-
-/*
- * struct nfs4_state maintains the client-side state for a given
- * (state_owner,inode) tuple (OPEN) or state_owner (LOCK).
- *
- * OPEN:
- * In order to know when to OPEN_DOWNGRADE or CLOSE the state on the server,
- * we need to know how many files are open for reading or writing on a
- * given inode. This information too is stored here.
- *
- * LOCK: one nfs4_state (LOCK) to hold the lock stateid nfs4_state(OPEN)
- */
-
-struct nfs4_lock_state {
-       struct list_head        ls_locks;       /* Other lock stateids */
-       fl_owner_t              ls_owner;       /* POSIX lock owner */
-       struct nfs4_state *     ls_parent;      /* Parent nfs4_state */
-       u32                     ls_seqid;
-       u32                     ls_id;
-       nfs4_stateid            ls_stateid;
-       atomic_t                ls_count;
-};
-
-/* bits for nfs4_state->flags */
-enum {
-       LK_STATE_IN_USE,
-};
-
-struct nfs4_state {
-       struct list_head open_states;   /* List of states for the same state_owner */
-       struct list_head inode_states;  /* List of states for the same inode */
-       struct list_head lock_states;   /* List of subservient lock stateids */
-
-       struct nfs4_state_owner *owner; /* Pointer to the open owner */
-       struct inode *inode;            /* Pointer to the inode */
-
-       unsigned long flags;            /* Do we hold any locks? */
-       struct semaphore lock_sema;     /* Serializes file locking operations */
-       rwlock_t state_lock;            /* Protects the lock_states list */
-
-       nfs4_stateid stateid;
-
-       unsigned int nreaders;
-       unsigned int nwriters;
-       int state;                      /* State on the server (R,W, or RW) */
-       atomic_t count;
-};
-
-
-extern struct dentry_operations nfs4_dentry_operations;
-extern struct inode_operations nfs4_dir_inode_operations;
-
-/* nfs4proc.c */
-extern int nfs4_proc_setclientid(struct nfs4_client *, u32, unsigned short);
-extern int nfs4_proc_setclientid_confirm(struct nfs4_client *);
-extern int nfs4_open_reclaim(struct nfs4_state_owner *, struct nfs4_state *);
-extern int nfs4_proc_async_renew(struct nfs4_client *);
-extern int nfs4_proc_renew(struct nfs4_client *);
-extern int nfs4_do_close(struct inode *, struct nfs4_state *);
-int nfs4_do_downgrade(struct inode *inode, struct nfs4_state *state, mode_t mode);
-extern int nfs4_wait_clnt_recover(struct rpc_clnt *, struct nfs4_client *);
-extern struct inode *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *);
-extern int nfs4_open_revalidate(struct inode *, struct dentry *, int);
-
-/* nfs4renewd.c */
-extern void nfs4_schedule_state_renewal(struct nfs4_client *);
-extern void nfs4_renewd_prepare_shutdown(struct nfs_server *);
-extern void nfs4_kill_renewd(struct nfs4_client *);
-
-/* nfs4state.c */
-extern void init_nfsv4_state(struct nfs_server *);
-extern void destroy_nfsv4_state(struct nfs_server *);
-extern struct nfs4_client *nfs4_get_client(struct in_addr *);
-extern void nfs4_put_client(struct nfs4_client *clp);
-extern u32 nfs4_alloc_lockowner_id(struct nfs4_client *);
-
-extern struct nfs4_state_owner * nfs4_get_state_owner(struct nfs_server *, struct rpc_cred *);
-extern void nfs4_put_state_owner(struct nfs4_state_owner *);
-extern struct nfs4_state * nfs4_get_open_state(struct inode *, struct nfs4_state_owner *);
-extern void nfs4_put_open_state(struct nfs4_state *);
-extern void nfs4_close_state(struct nfs4_state *, mode_t);
-extern struct nfs4_state *nfs4_find_state(struct inode *, struct rpc_cred *, mode_t mode);
-extern void nfs4_increment_seqid(int status, struct nfs4_state_owner *sp);
-extern int nfs4_handle_error(struct nfs_server *, int);
-extern void nfs4_schedule_state_recovery(struct nfs4_client *);
-extern struct nfs4_lock_state *nfs4_find_lock_state(struct nfs4_state *state, fl_owner_t);
-extern struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, fl_owner_t);
-extern void nfs4_put_lock_state(struct nfs4_lock_state *state);
-extern void nfs4_increment_lock_seqid(int status, struct nfs4_lock_state *ls);
-extern void nfs4_notify_setlk(struct inode *, struct file_lock *, struct nfs4_lock_state *);
-extern void nfs4_notify_unlck(struct inode *, struct file_lock *, struct nfs4_lock_state *);
-extern void nfs4_copy_stateid(nfs4_stateid *, struct nfs4_state *, fl_owner_t);
-
-
-
-struct nfs4_mount_data;
-#else
-#define init_nfsv4_state(server)  do { } while (0)
-#define destroy_nfsv4_state(server)       do { } while (0)
-#define nfs4_put_state_owner(inode, owner) do { } while (0)
-#define nfs4_put_open_state(state) do { } while (0)
-#define nfs4_renewd_prepare_shutdown(server) do { } while (0)
-#endif
-
 #endif /* __KERNEL__ */
 
 /*
@@ -697,6 +630,7 @@ struct nfs4_mount_data;
 #define NFSDBG_XDR             0x0020
 #define NFSDBG_FILE            0x0040
 #define NFSDBG_ROOT            0x0080
+#define NFSDBG_CALLBACK                0x0100
 #define NFSDBG_ALL             0xFFFF
 
 #ifdef __KERNEL__