Newer
Older
|| S_ISLNK(inode->i_mode)))
invalid &= ~NFS_INO_INVALID_DATA;
if (data_stable)
invalid &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME|NFS_INO_REVAL_PAGECACHE);
nfsi->cache_validity |= invalid;
return 0;
out_changed:
/*
* Big trouble! The inode has become a different object.
*/
#ifdef NFS_PARANOIA
printk(KERN_DEBUG "%s: inode %ld mode changed, %07o to %07o\n",
__FUNCTION__, inode->i_ino, inode->i_mode, fattr->mode);
#endif
/*
* No need to worry about unhashing the dentry, as the
* lookup validation will know that the inode is bad.
* (But we fall through to invalidate the caches.)
*/
nfs_invalidate_inode(inode);
return -ESTALE;
out_fileid:
printk(KERN_ERR "NFS: server %s error: fileid changed\n"
"fsid %s: expected fileid 0x%Lx, got 0x%Lx\n",
NFS_SERVER(inode)->hostname, inode->i_sb->s_id,
(long long)nfsi->fileid, (long long)fattr->fileid);
goto out_err;
#ifdef CONFIG_NFS_V4
/*
* Clean out any remaining NFSv4 state that might be left over due
* to open() calls that passed nfs_atomic_lookup, but failed to call
* nfs_open().
*/
{
struct nfs_inode *nfsi = NFS_I(inode);
/* If we are holding a delegation, return it! */
nfs_inode_return_delegation(inode);
/* First call standard NFS clear_inode() code */
nfs_clear_inode(inode);
/* Now clear out any remaining state */
while (!list_empty(&nfsi->open_states)) {
struct nfs4_state *state;
state = list_entry(nfsi->open_states.next,
struct nfs4_state,
inode_states);
dprintk("%s(%s/%Ld): found unclaimed NFSv4 state %p\n",
__FUNCTION__,
inode->i_sb->s_id,
(long long)NFS_FILEID(inode),
state);
BUG_ON(atomic_read(&state->count) != 1);
nfs4_close_state(state, state->state);
}
}
#endif
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);
if (!nfsi)
return NULL;
nfsi->flags = 0UL;
nfsi->cache_validity = 0UL;
nfsi->cache_change_attribute = jiffies;
#ifdef CONFIG_NFS_V3_ACL
nfsi->acl_access = ERR_PTR(-EAGAIN);
nfsi->acl_default = ERR_PTR(-EAGAIN);
#endif
#ifdef CONFIG_NFS_V4
nfsi->nfs4_acl = NULL;
#endif /* CONFIG_NFS_V4 */
{
kmem_cache_free(nfs_inode_cachep, NFS_I(inode));
}
static inline void nfs4_init_once(struct nfs_inode *nfsi)
{
#ifdef CONFIG_NFS_V4
INIT_LIST_HEAD(&nfsi->open_states);
nfsi->delegation = NULL;
nfsi->delegation_state = 0;
init_rwsem(&nfsi->rwsem);
#endif
}
static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
{
struct nfs_inode *nfsi = (struct nfs_inode *) foo;
if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
SLAB_CTOR_CONSTRUCTOR) {
inode_init_once(&nfsi->vfs_inode);
spin_lock_init(&nfsi->req_lock);
INIT_LIST_HEAD(&nfsi->dirty);
INIT_LIST_HEAD(&nfsi->commit);
INIT_LIST_HEAD(&nfsi->open_files);
INIT_RADIX_TREE(&nfsi->nfs_page_tree, GFP_ATOMIC);
atomic_set(&nfsi->data_updates, 0);
nfsi->ndirty = 0;
nfsi->ncommit = 0;
nfsi->npages = 0;
nfs4_init_once(nfsi);
}
}
{
nfs_inode_cachep = kmem_cache_create("nfs_inode_cache",
sizeof(struct nfs_inode),
0, (SLAB_RECLAIM_ACCOUNT|
SLAB_MEM_SPREAD),
init_once, NULL);
if (nfs_inode_cachep == NULL)
return -ENOMEM;
return 0;
}
static void __exit nfs_destroy_inodecache(void)
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
{
if (kmem_cache_destroy(nfs_inode_cachep))
printk(KERN_INFO "nfs_inode_cache: not all structures were freed\n");
}
/*
* Initialize NFS
*/
static int __init init_nfs_fs(void)
{
int err;
err = nfs_init_nfspagecache();
if (err)
goto out4;
err = nfs_init_inodecache();
if (err)
goto out3;
err = nfs_init_readpagecache();
if (err)
goto out2;
err = nfs_init_writepagecache();
if (err)
goto out1;
err = nfs_init_directcache();
if (err)
goto out0;
#ifdef CONFIG_PROC_FS
rpc_proc_register(&nfs_rpcstat);
#endif
goto out;
return 0;
out:
#ifdef CONFIG_PROC_FS
rpc_proc_unregister("nfs");
#endif
nfs_destroy_directcache();
out0:
nfs_destroy_writepagecache();
out1:
nfs_destroy_readpagecache();
out2:
nfs_destroy_inodecache();
out3:
nfs_destroy_nfspagecache();
out4:
return err;
}
static void __exit exit_nfs_fs(void)
{
nfs_destroy_directcache();
nfs_destroy_writepagecache();
nfs_destroy_readpagecache();
nfs_destroy_inodecache();
nfs_destroy_nfspagecache();
#ifdef CONFIG_PROC_FS
rpc_proc_unregister("nfs");
#endif
}
/* Not quite true; I just maintain it */
MODULE_AUTHOR("Olaf Kirch <okir@monad.swb.de>");
MODULE_LICENSE("GPL");
module_init(init_nfs_fs)
module_exit(exit_nfs_fs)