patch-2.2.0-final linux/fs/inode.c
Next file: linux/fs/namei.c
Previous file: linux/fs/dcache.c
Back to the patch index
Back to the overall index
- Lines: 135
- Date:
Mon Jan 25 14:58:38 1999
- Orig file:
v2.2.0-pre9/linux/fs/inode.c
- Orig date:
Thu Jan 7 15:11:38 1999
diff -u --recursive --new-file v2.2.0-pre9/linux/fs/inode.c linux/fs/inode.c
@@ -354,36 +354,28 @@
return found;
}
+static void shrink_dentry_inodes(int goal)
+{
+ int found;
+
+ spin_unlock(&inode_lock);
+ found = select_dcache(goal, 0);
+ if (found < goal)
+ found = goal;
+ prune_dcache(found);
+ spin_lock(&inode_lock);
+}
+
/*
* Searches the inodes list for freeable inodes,
- * possibly shrinking the dcache before or after.
+ * shrinking the dcache before (and possible after,
+ * if we're low)
*/
static void try_to_free_inodes(int goal)
{
- int retry = 1, found;
-
- /*
- * Check whether to preshrink the dcache ...
- */
- if (inodes_stat.preshrink)
- goto preshrink;
-
- retry = 0;
- do {
- if (free_inodes(goal))
- break;
- /*
- * If we didn't free any inodes, do a limited
- * pruning of the dcache to help the next time.
- */
- preshrink:
- spin_unlock(&inode_lock);
- found = select_dcache(goal, 0);
- if (found < goal)
- found = goal;
- prune_dcache(found);
- spin_lock(&inode_lock);
- } while (retry--);
+ shrink_dentry_inodes(goal);
+ if (!free_inodes(goal))
+ shrink_dentry_inodes(goal);
}
/*
@@ -408,6 +400,21 @@
{
struct inode * inode;
+ /*
+ * Check whether to restock the unused list.
+ */
+ if (inodes_stat.preshrink) {
+ struct list_head *tmp;
+ try_to_free_inodes(8);
+ tmp = inode_unused.next;
+ if (tmp != &inode_unused) {
+ inodes_stat.nr_free_inodes--;
+ list_del(tmp);
+ inode = list_entry(tmp, struct inode, i_list);
+ return inode;
+ }
+ }
+
spin_unlock(&inode_lock);
inode = (struct inode *)__get_free_page(GFP_KERNEL);
if (inode) {
@@ -512,6 +519,12 @@
sb->s_op->read_inode(inode);
}
+/*
+ * This is called by things like the networking layer
+ * etc that want to get an inode without any inode
+ * number, or filesystems that allocate new inodes with
+ * no pre-existing information.
+ */
struct inode * get_empty_inode(void)
{
static unsigned long last_ino = 0;
@@ -519,11 +532,6 @@
struct list_head * tmp;
spin_lock(&inode_lock);
- /*
- * Check whether to restock the unused list.
- */
- if (inodes_stat.nr_free_inodes < 16)
- try_to_free_inodes(8);
tmp = inode_unused.next;
if (tmp != &inode_unused) {
list_del(tmp);
@@ -629,25 +637,18 @@
struct inode * inode;
spin_lock(&inode_lock);
- if (!inodes_stat.nr_free_inodes)
- goto restock;
-search:
inode = find_inode(sb, ino, head);
- if (!inode) {
- return get_new_inode(sb, ino, head);
+ if (inode) {
+ spin_unlock(&inode_lock);
+ wait_on_inode(inode);
+ return inode;
}
- spin_unlock(&inode_lock);
- wait_on_inode(inode);
- return inode;
-
/*
- * We restock the freelist before calling find,
- * in order to avoid repeating the search.
- * (The unused list usually won't be empty.)
+ * get_new_inode() will do the right thing, releasing
+ * the inode lock and re-trying the search in case it
+ * had to block at any point.
*/
-restock:
- try_to_free_inodes(8);
- goto search;
+ return get_new_inode(sb, ino, head);
}
void insert_inode_hash(struct inode *inode)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov