#include <linux/security.h>
#include <linux/pagemap.h>
#include <linux/cdev.h>
+#include <linux/bootmem.h>
#include <linux/vs_base.h>
/*
* from its final dispose_list, the struct super_block they refer to
* (for inode->i_sb->s_op) may already have been freed and reused.
*/
-static DECLARE_MUTEX(iprune_sem);
+DECLARE_MUTEX(iprune_sem);
/*
* Statistics gathering..
struct address_space * const mapping = &inode->i_data;
inode->i_sb = sb;
- if (sb->s_flags & MS_TAGXID)
- inode->i_xid = current->xid;
- else
- inode->i_xid = 0; /* maybe xid -1 would be better? */
// inode->i_dqh = dqhget(sb->s_dqh);
+
+ /* important because of inode slab reuse */
+ inode->i_xid = 0;
inode->i_blkbits = sb->s_blocksize_bits;
inode->i_flags = 0;
atomic_set(&inode->i_count, 1);
inode->i_bdev = NULL;
inode->i_cdev = NULL;
inode->i_rdev = 0;
- // inode->i_xid = 0; /* maybe not too wise ... */
inode->i_security = NULL;
inode->dirtied_when = 0;
if (security_inode_alloc(inode)) {
*/
void clear_inode(struct inode *inode)
{
+ might_sleep();
invalidate_inode_buffers(inode);
if (inode->i_data.nrpages)
* and we don't want to recurse into the FS that called us
* in clear_inode() and friends..
*/
- if (gfp_mask & __GFP_FS)
- prune_icache(nr);
+ if (!(gfp_mask & __GFP_FS))
+ return -1;
+ prune_icache(nr);
}
- return inodes_stat.nr_unused;
+ return (inodes_stat.nr_unused / 100) * sysctl_vfs_cache_pressure;
}
static void __wait_on_freeing_inode(struct inode *inode);
list_add(&inode->i_list, &inode_in_use);
inode->i_ino = ++last_ino;
inode->i_state = 0;
- inode->i_xid = vx_current_xid();
spin_unlock(&inode_lock);
}
return inode;
if (!sb->dq_op)
return; /* nothing to do */
spin_lock(&inode_lock); /* This lock is for inodes code */
- /* We don't have to lock against quota code - test IS_QUOTAINIT is just for speedup... */
-
+
+ /* We hold dqptr_sem so we are safe against the quota code */
list_for_each(act_head, &inode_in_use) {
inode = list_entry(act_head, struct inode, i_list);
- if (inode->i_sb == sb && IS_QUOTAINIT(inode))
+ if (inode->i_sb == sb && !IS_NOQUOTA(inode))
remove_inode_dquot_ref(inode, type, tofree_head);
}
list_for_each(act_head, &inode_unused) {
inode = list_entry(act_head, struct inode, i_list);
- if (inode->i_sb == sb && IS_QUOTAINIT(inode))
+ if (inode->i_sb == sb && !IS_NOQUOTA(inode))
remove_inode_dquot_ref(inode, type, tofree_head);
}
list_for_each(act_head, &sb->s_dirty) {
inode = list_entry(act_head, struct inode, i_list);
- if (IS_QUOTAINIT(inode))
+ if (!IS_NOQUOTA(inode))
remove_inode_dquot_ref(inode, type, tofree_head);
}
list_for_each(act_head, &sb->s_io) {
inode = list_entry(act_head, struct inode, i_list);
- if (IS_QUOTAINIT(inode))
+ if (!IS_NOQUOTA(inode))
remove_inode_dquot_ref(inode, type, tofree_head);
}
spin_unlock(&inode_lock);
/*
* Initialize the waitqueues and inode hash table.
*/
+void __init inode_init_early(void)
+{
+ int loop;
+
+ inode_hashtable =
+ alloc_large_system_hash("Inode-cache",
+ sizeof(struct hlist_head),
+ ihash_entries,
+ 14,
+ 0,
+ &i_hash_shift,
+ &i_hash_mask);
+
+ for (loop = 0; loop < (1 << i_hash_shift); loop++)
+ INIT_HLIST_HEAD(&inode_hashtable[loop]);
+}
+
void __init inode_init(unsigned long mempages)
{
- struct hlist_head *head;
- unsigned long order;
- unsigned int nr_hash;
int i;
for (i = 0; i < ARRAY_SIZE(i_wait_queue_heads); i++)
init_waitqueue_head(&i_wait_queue_heads[i].wqh);
- if (!ihash_entries)
- ihash_entries = PAGE_SHIFT < 14 ?
- mempages >> (14 - PAGE_SHIFT) :
- mempages << (PAGE_SHIFT - 14);
-
- ihash_entries *= sizeof(struct hlist_head);
- for (order = 0; ((1UL << order) << PAGE_SHIFT) < ihash_entries; order++)
- ;
-
- do {
- unsigned long tmp;
-
- nr_hash = (1UL << order) * PAGE_SIZE /
- sizeof(struct hlist_head);
- i_hash_mask = (nr_hash - 1);
-
- tmp = nr_hash;
- i_hash_shift = 0;
- while ((tmp >>= 1UL) != 0UL)
- i_hash_shift++;
-
- inode_hashtable = (struct hlist_head *)
- __get_free_pages(GFP_ATOMIC, order);
- } while (inode_hashtable == NULL && --order >= 0);
-
- printk("Inode-cache hash table entries: %d (order: %ld, %ld bytes)\n",
- nr_hash, order, (PAGE_SIZE << order));
-
- if (!inode_hashtable)
- panic("Failed to allocate inode hash table\n");
-
- head = inode_hashtable;
- i = nr_hash;
- do {
- INIT_HLIST_HEAD(head);
- head++;
- i--;
- } while (i);
-
/* inode slab cache */
inode_cachep = kmem_cache_create("inode_cache", sizeof(struct inode),
- 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, init_once,
- NULL);
+ 0, SLAB_PANIC, init_once, NULL);
set_shrinker(DEFAULT_SEEKS, shrink_icache_memory);
}