fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / fs / nfs / inode.c
index 2d8cf64..9638d44 100644 (file)
@@ -37,7 +37,7 @@
 #include <linux/vfs.h>
 #include <linux/inet.h>
 #include <linux/nfs_xdr.h>
-#include <linux/vserver/xid.h>
+#include <linux/vs_tag.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -56,7 +56,13 @@ static int nfs_update_inode(struct inode *, struct nfs_fattr *);
 
 static void nfs_zap_acl_cache(struct inode *);
 
-static kmem_cache_t * nfs_inode_cachep;
+static struct kmem_cache * nfs_inode_cachep;
+
+static inline unsigned long
+nfs_fattr_to_ino_t(struct nfs_fattr *fattr)
+{
+       return nfs_fileid_to_ino_t(fattr->fileid);
+}
 
 int nfs_write_inode(struct inode *inode, int sync)
 {
@@ -71,21 +77,14 @@ int nfs_write_inode(struct inode *inode, int sync)
 
 void nfs_clear_inode(struct inode *inode)
 {
-       struct nfs_inode *nfsi = NFS_I(inode);
-       struct rpc_cred *cred;
-
        /*
         * The following should never happen...
         */
        BUG_ON(nfs_have_writebacks(inode));
-       BUG_ON (!list_empty(&nfsi->open_files));
+       BUG_ON(!list_empty(&NFS_I(inode)->open_files));
+       BUG_ON(atomic_read(&NFS_I(inode)->data_updates) != 0);
        nfs_zap_acl_cache(inode);
-       cred = nfsi->cache_access.cred;
-       if (cred)
-               put_rpccred(cred);
-
-       nfs_fscache_release_fh_cookie(NFS_SERVER(inode), nfsi);
-       BUG_ON(atomic_read(&nfsi->data_updates) != 0);
+       nfs_access_zap_cache(inode);
 }
 
 /**
@@ -131,8 +130,15 @@ void nfs_zap_caches(struct inode *inode)
        spin_lock(&inode->i_lock);
        nfs_zap_caches_locked(inode);
        spin_unlock(&inode->i_lock);
+}
 
-       nfs_fscache_zap_fh_cookie(NFS_SERVER(inode), NFS_I(inode));
+void nfs_zap_mapping(struct inode *inode, struct address_space *mapping)
+{
+       if (mapping->nrpages != 0) {
+               spin_lock(&inode->i_lock);
+               NFS_I(inode)->cache_validity |= NFS_INO_INVALID_DATA;
+               spin_unlock(&inode->i_lock);
+       }
 }
 
 static void nfs_zap_acl_cache(struct inode *inode)
@@ -211,7 +217,6 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
        };
        struct inode *inode = ERR_PTR(-ENOENT);
        unsigned long hash;
-       int maycache = 1;
 
        if ((fattr->valid & NFS_ATTR_FATTR) == 0)
                goto out_no_inode;
@@ -221,9 +226,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
                goto out_no_inode;
        }
 
-       hash = fattr->fileid;
-       if (sizeof(hash) < sizeof(u64))
-               hash ^= fattr->fileid >> (sizeof(u64) - sizeof(ino_t)) * 8;
+       hash = nfs_fattr_to_ino_t(fattr);
 
        inode = iget5_locked(sb, hash, nfs_find_actor, nfs_init_locked, &desc);
        if (inode == NULL) {
@@ -234,10 +237,9 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
        if (inode->i_state & I_NEW) {
                struct nfs_inode *nfsi = NFS_I(inode);
 
-               /* We set i_ino for the few things that still rely on it, such
-                * as printing messages; stat and filldir use the fileid
-                * directly since i_ino may not be large enough */
-               inode->i_ino = fattr->fileid;
+               /* We set i_ino for the few things that still rely on it,
+                * such as stat(2) */
+               inode->i_ino = hash;
 
                /* We can't support update_atime(), since the server will reset it */
                inode->i_flags |= S_NOATIME|S_NOCMTIME;
@@ -263,7 +265,6 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
                                else
                                        inode->i_op = &nfs_mountpoint_inode_operations;
                                inode->i_fop = NULL;
-                               maycache = 0;
                        }
                } else if (S_ISLNK(inode->i_mode))
                        inode->i_op = &nfs_symlink_inode_operations;
@@ -279,9 +280,9 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
                        nfsi->change_attr = fattr->change_attr;
                inode->i_size = nfs_size_to_loff_t(fattr->size);
                inode->i_nlink = fattr->nlink;
-               inode->i_uid = INOXID_UID(XID_TAG(inode), fattr->uid, fattr->gid);
-               inode->i_gid = INOXID_GID(XID_TAG(inode), fattr->uid, fattr->gid);
-               inode->i_xid = INOXID_XID(XID_TAG(inode), fattr->uid, fattr->gid, 0);
+               inode->i_uid = INOTAG_UID(DX_TAG(inode), fattr->uid, fattr->gid);
+               inode->i_gid = INOTAG_GID(DX_TAG(inode), fattr->uid, fattr->gid);
+               inode->i_tag = INOTAG_TAG(DX_TAG(inode), fattr->uid, fattr->gid, 0);
                                         /* maybe fattr->xid someday */
                if (fattr->valid & (NFS_ATTR_FATTR_V3 | NFS_ATTR_FATTR_V4)) {
                        /*
@@ -294,9 +295,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
                nfsi->attrtimeo = NFS_MINATTRTIMEO(inode);
                nfsi->attrtimeo_timestamp = jiffies;
                memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf));
-               nfsi->cache_access.cred = NULL;
-
-               nfs_fscache_get_fh_cookie(sb, nfsi, maycache);
+               nfsi->access_cache = RB_ROOT;
 
                unlock_new_inode(inode);
        } else
@@ -338,8 +337,10 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr)
        lock_kernel();
        nfs_begin_data_update(inode);
        /* Write all dirty data */
-       filemap_write_and_wait(inode->i_mapping);
-       nfs_wb_all(inode);
+       if (S_ISREG(inode->i_mode)) {
+               filemap_write_and_wait(inode->i_mapping);
+               nfs_wb_all(inode);
+       }
        /*
         * Return any delegations if we're going to change ACLs
         */
@@ -373,8 +374,8 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr)
                        inode->i_uid = attr->ia_uid;
                if ((attr->ia_valid & ATTR_GID) != 0)
                        inode->i_gid = attr->ia_gid;
-               if ((attr->ia_valid & ATTR_XID) && IS_TAGXID(inode))
-                       inode->i_xid = attr->ia_xid;
+               if ((attr->ia_valid & ATTR_TAG) && IS_TAGGED(inode))
+                       inode->i_tag = attr->ia_tag;
                spin_lock(&inode->i_lock);
                NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
                spin_unlock(&inode->i_lock);
@@ -382,7 +383,6 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr)
        if ((attr->ia_valid & ATTR_SIZE) != 0) {
                nfs_inc_stats(inode, NFSIOS_SETATTRTRUNC);
                inode->i_size = attr->ia_size;
-               nfs_fscache_set_size(NFS_SERVER(inode), NFS_I(inode), inode->i_size);
                vmtruncate(inode, attr->ia_size);
        }
 }
@@ -429,7 +429,8 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
        int err;
 
        /* Flush out writes to the server in order to update c/mtime */
-       nfs_sync_inode_wait(inode, 0, 0, FLUSH_NOCOMMIT);
+       if (S_ISREG(inode->i_mode))
+               nfs_sync_mapping_range(inode->i_mapping, 0, 0, FLUSH_NOCOMMIT);
 
        /*
         * We may force a getattr if the user cares about atime.
@@ -448,10 +449,8 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
                err = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
        else
                err = nfs_revalidate_inode(NFS_SERVER(inode), inode);
-       if (!err) {
+       if (!err)
                generic_fillattr(inode, stat);
-               stat->ino = NFS_FILEID(inode);
-       }
        return err;
 }
 
@@ -459,7 +458,7 @@ static struct nfs_open_context *alloc_nfs_open_context(struct vfsmount *mnt, str
 {
        struct nfs_open_context *ctx;
 
-       ctx = (struct nfs_open_context *)kmalloc(sizeof(*ctx), GFP_KERNEL);
+       ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
        if (ctx != NULL) {
                atomic_set(&ctx->count, 1);
                ctx->dentry = dget(dentry);
@@ -505,7 +504,7 @@ void put_nfs_open_context(struct nfs_open_context *ctx)
  */
 static void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx)
 {
-       struct inode *inode = filp->f_dentry->d_inode;
+       struct inode *inode = filp->f_path.dentry->d_inode;
        struct nfs_inode *nfsi = NFS_I(inode);
 
        filp->private_data = get_nfs_open_context(ctx);
@@ -537,7 +536,7 @@ struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_c
 
 static void nfs_file_clear_open_context(struct file *filp)
 {
-       struct inode *inode = filp->f_dentry->d_inode;
+       struct inode *inode = filp->f_path.dentry->d_inode;
        struct nfs_open_context *ctx = (struct nfs_open_context *)filp->private_data;
 
        if (ctx) {
@@ -560,15 +559,13 @@ int nfs_open(struct inode *inode, struct file *filp)
        cred = rpcauth_lookupcred(NFS_CLIENT(inode)->cl_auth, 0);
        if (IS_ERR(cred))
                return PTR_ERR(cred);
-       ctx = alloc_nfs_open_context(filp->f_vfsmnt, filp->f_dentry, cred);
+       ctx = alloc_nfs_open_context(filp->f_path.mnt, filp->f_path.dentry, cred);
        put_rpccred(cred);
        if (ctx == NULL)
                return -ENOMEM;
        ctx->mode = filp->f_mode;
        nfs_file_set_open_context(filp, ctx);
        put_nfs_open_context(ctx);
-       if ((filp->f_flags & O_ACCMODE) != O_RDONLY)
-               nfs_fscache_disable_fh_cookie(inode);
        return 0;
 }
 
@@ -594,7 +591,7 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
 
        nfs_inc_stats(inode, NFSIOS_INODEREVALIDATE);
        lock_kernel();
-       if (!inode || is_bad_inode(inode))
+       if (is_bad_inode(inode))
                goto out_nowait;
        if (NFS_STALE(inode))
                goto out_nowait;
@@ -676,43 +673,87 @@ int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
        return __nfs_revalidate_inode(server, inode);
 }
 
+static int nfs_invalidate_mapping_nolock(struct inode *inode, struct address_space *mapping)
+{
+       struct nfs_inode *nfsi = NFS_I(inode);
+       
+       if (mapping->nrpages != 0) {
+               int ret = invalidate_inode_pages2(mapping);
+               if (ret < 0)
+                       return ret;
+       }
+       spin_lock(&inode->i_lock);
+       nfsi->cache_validity &= ~NFS_INO_INVALID_DATA;
+       if (S_ISDIR(inode->i_mode)) {
+               memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf));
+               /* This ensures we revalidate child dentries */
+               nfsi->cache_change_attribute = jiffies;
+       }
+       spin_unlock(&inode->i_lock);
+       nfs_inc_stats(inode, NFSIOS_DATAINVALIDATE);
+       dfprintk(PAGECACHE, "NFS: (%s/%Ld) data cache invalidated\n",
+                       inode->i_sb->s_id, (long long)NFS_FILEID(inode));
+       return 0;
+}
+
+static int nfs_invalidate_mapping(struct inode *inode, struct address_space *mapping)
+{
+       int ret = 0;
+
+       mutex_lock(&inode->i_mutex);
+       if (NFS_I(inode)->cache_validity & NFS_INO_INVALID_DATA) {
+               ret = nfs_sync_mapping(mapping);
+               if (ret == 0)
+                       ret = nfs_invalidate_mapping_nolock(inode, mapping);
+       }
+       mutex_unlock(&inode->i_mutex);
+       return ret;
+}
+
 /**
- * nfs_revalidate_mapping - Revalidate the pagecache
+ * nfs_revalidate_mapping_nolock - Revalidate the pagecache
  * @inode - pointer to host inode
  * @mapping - pointer to mapping
  */
-int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping)
+int nfs_revalidate_mapping_nolock(struct inode *inode, struct address_space *mapping)
 {
        struct nfs_inode *nfsi = NFS_I(inode);
        int ret = 0;
 
-       if (NFS_STALE(inode))
-               ret = -ESTALE;
        if ((nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE)
-                       || nfs_attribute_timeout(inode))
+                       || nfs_attribute_timeout(inode) || NFS_STALE(inode)) {
                ret = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
+               if (ret < 0)
+                       goto out;
+       }
+       if (nfsi->cache_validity & NFS_INO_INVALID_DATA)
+               ret = nfs_invalidate_mapping_nolock(inode, mapping);
+out:
+       return ret;
+}
 
-       if (nfsi->cache_validity & NFS_INO_INVALID_DATA) {
-               nfs_inc_stats(inode, NFSIOS_DATAINVALIDATE);
-               if (S_ISREG(inode->i_mode))
-                       nfs_sync_mapping(mapping);
-               invalidate_inode_pages2(mapping);
-
-               spin_lock(&inode->i_lock);
-               nfsi->cache_validity &= ~NFS_INO_INVALID_DATA;
-               if (S_ISDIR(inode->i_mode)) {
-                       memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf));
-                       /* This ensures we revalidate child dentries */
-                       nfsi->cache_change_attribute = jiffies;
-               }
-               spin_unlock(&inode->i_lock);
-
-               nfs_fscache_renew_fh_cookie(NFS_SERVER(inode), nfsi);
+/**
+ * nfs_revalidate_mapping - Revalidate the pagecache
+ * @inode - pointer to host inode
+ * @mapping - pointer to mapping
+ *
+ * This version of the function will take the inode->i_mutex and attempt to
+ * flush out all dirty data if it needs to invalidate the page cache.
+ */
+int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping)
+{
+       struct nfs_inode *nfsi = NFS_I(inode);
+       int ret = 0;
 
-               dfprintk(PAGECACHE, "NFS: (%s/%Ld) data cache invalidated\n",
-                               inode->i_sb->s_id,
-                               (long long)NFS_FILEID(inode));
+       if ((nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE)
+                       || nfs_attribute_timeout(inode) || NFS_STALE(inode)) {
+               ret = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
+               if (ret < 0)
+                       goto out;
        }
+       if (nfsi->cache_validity & NFS_INO_INVALID_DATA)
+               ret = nfs_invalidate_mapping(inode, mapping);
+out:
        return ret;
 }
 
@@ -737,13 +778,11 @@ void nfs_end_data_update(struct inode *inode)
 {
        struct nfs_inode *nfsi = NFS_I(inode);
 
-       if (!nfs_have_delegation(inode, FMODE_READ)) {
-               /* Directories and symlinks: invalidate page cache */
-               if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) {
-                       spin_lock(&inode->i_lock);
-                       nfsi->cache_validity |= NFS_INO_INVALID_DATA;
-                       spin_unlock(&inode->i_lock);
-               }
+       /* Directories: invalidate page cache */
+       if (S_ISDIR(inode->i_mode)) {
+               spin_lock(&inode->i_lock);
+               nfsi->cache_validity |= NFS_INO_INVALID_DATA;
+               spin_unlock(&inode->i_lock);
        }
        nfsi->cache_change_attribute = jiffies;
        atomic_dec(&nfsi->data_updates);
@@ -786,7 +825,7 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
        int data_unstable;
        uid_t uid;
        gid_t gid;
-       xid_t xid;
+       tag_t tag;
 
 
        /* Has the inode gone and changed behind our back? */
@@ -814,15 +853,15 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
        if (cur_size != new_isize && nfsi->npages == 0)
                nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE;
 
-       uid = INOXID_UID(XID_TAG(inode), fattr->uid, fattr->gid);
-       gid = INOXID_GID(XID_TAG(inode), fattr->uid, fattr->gid);
-       xid = INOXID_XID(XID_TAG(inode), fattr->uid, fattr->gid, 0);
+       uid = INOTAG_UID(DX_TAG(inode), fattr->uid, fattr->gid);
+       gid = INOTAG_GID(DX_TAG(inode), fattr->uid, fattr->gid);
+       tag = INOTAG_TAG(DX_TAG(inode), fattr->uid, fattr->gid, 0);
 
        /* Have any file permissions changed? */
        if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO)
                        || inode->i_uid != uid
                        || inode->i_gid != gid
-                       || inode->i_xid != xid)
+                       || inode->i_tag != tag)
                nfsi->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
 
        /* Has the link count changed? */
@@ -870,6 +909,12 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
  *
  * After an operation that has changed the inode metadata, mark the
  * attribute cache as being invalid, then try to update it.
+ *
+ * NB: if the server didn't return any post op attributes, this
+ * function will force the retrieval of attributes before the next
+ * NFS request.  Thus it should be used only for operations that
+ * are expected to change one or more attributes, to avoid
+ * unnecessary NFS requests and trips through nfs_update_inode().
  */
 int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr)
 {
@@ -908,7 +953,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
        int data_stable;
        uid_t uid;
        gid_t gid;
-       xid_t xid;
+       tag_t tag;
 
        dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n",
                        __FUNCTION__, inode->i_sb->s_id, inode->i_ino,
@@ -953,13 +998,11 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
                        if (data_stable) {
                                inode->i_size = new_isize;
                                invalid |= NFS_INO_INVALID_DATA;
-                               nfs_fscache_set_size(NFS_SERVER(inode), nfsi, inode->i_size);
                        }
                        invalid |= NFS_INO_INVALID_ATTR;
                } else if (new_isize > cur_isize) {
                        inode->i_size = new_isize;
                        invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA;
-                       nfs_fscache_set_size(NFS_SERVER(inode), nfsi, inode->i_size);
                }
                nfsi->cache_change_attribute = jiffies;
                dprintk("NFS: isize change on server for file %s/%ld\n",
@@ -983,21 +1026,21 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
        }
        memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime));
 
-       uid = INOXID_UID(XID_TAG(inode), fattr->uid, fattr->gid);
-       gid = INOXID_GID(XID_TAG(inode), fattr->uid, fattr->gid);
-       xid = INOXID_XID(XID_TAG(inode), fattr->uid, fattr->gid, 0);
+       uid = INOTAG_UID(DX_TAG(inode), fattr->uid, fattr->gid);
+       gid = INOTAG_GID(DX_TAG(inode), fattr->uid, fattr->gid);
+       tag = INOTAG_TAG(DX_TAG(inode), fattr->uid, fattr->gid, 0);
 
        if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) ||
            inode->i_uid != uid ||
            inode->i_gid != gid ||
-           inode->i_xid != xid)
+           inode->i_tag != tag)
                invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
 
        inode->i_mode = fattr->mode;
        inode->i_nlink = fattr->nlink;
        inode->i_uid = uid;
        inode->i_gid = gid;
-       inode->i_xid = xid;
+       inode->i_tag = tag;
 
        if (fattr->valid & (NFS_ATTR_FATTR_V3 | NFS_ATTR_FATTR_V4)) {
                /*
@@ -1099,7 +1142,7 @@ void nfs4_clear_inode(struct inode *inode)
 struct inode *nfs_alloc_inode(struct super_block *sb)
 {
        struct nfs_inode *nfsi;
-       nfsi = (struct nfs_inode *)kmem_cache_alloc(nfs_inode_cachep, SLAB_KERNEL);
+       nfsi = (struct nfs_inode *)kmem_cache_alloc(nfs_inode_cachep, GFP_KERNEL);
        if (!nfsi)
                return NULL;
        nfsi->flags = 0UL;
@@ -1130,7 +1173,7 @@ static inline void nfs4_init_once(struct nfs_inode *nfsi)
 #endif
 }
 
-static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
+static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)
 {
        struct nfs_inode *nfsi = (struct nfs_inode *) foo;
 
@@ -1141,6 +1184,8 @@ static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
                INIT_LIST_HEAD(&nfsi->dirty);
                INIT_LIST_HEAD(&nfsi->commit);
                INIT_LIST_HEAD(&nfsi->open_files);
+               INIT_LIST_HEAD(&nfsi->access_cache_entry_lru);
+               INIT_LIST_HEAD(&nfsi->access_cache_inode_lru);
                INIT_RADIX_TREE(&nfsi->nfs_page_tree, GFP_ATOMIC);
                atomic_set(&nfsi->data_updates, 0);
                nfsi->ndirty = 0;
@@ -1165,8 +1210,7 @@ static int __init nfs_init_inodecache(void)
 
 static void nfs_destroy_inodecache(void)
 {
-       if (kmem_cache_destroy(nfs_inode_cachep))
-               printk(KERN_INFO "nfs_inode_cache: not all structures were freed\n");
+       kmem_cache_destroy(nfs_inode_cachep);
 }
 
 /*
@@ -1176,10 +1220,6 @@ static int __init init_nfs_fs(void)
 {
        int err;
 
-       err = nfs_fscache_register();
-       if (err < 0)
-               goto out6;
-
        err = nfs_fs_proc_init();
        if (err)
                goto out5;
@@ -1226,8 +1266,6 @@ out3:
 out4:
        nfs_fs_proc_exit();
 out5:
-       nfs_fscache_unregister();
-out6:
        return err;
 }
 
@@ -1238,7 +1276,6 @@ static void __exit exit_nfs_fs(void)
        nfs_destroy_readpagecache();
        nfs_destroy_inodecache();
        nfs_destroy_nfspagecache();
-       nfs_fscache_unregister();
 #ifdef CONFIG_PROC_FS
        rpc_proc_unregister("nfs");
 #endif