patch-2.0.32 linux/fs/inode.c
Next file: linux/fs/locks.c
Previous file: linux/fs/exec.c
Back to the patch index
Back to the overall index
- Lines: 71
- Date:
Wed Nov 12 20:36:41 1997
- Orig file:
v2.0.31/linux/fs/inode.c
- Orig date:
Wed Oct 15 10:28:42 1997
diff -u --recursive --new-file v2.0.31/linux/fs/inode.c linux/fs/inode.c
@@ -173,7 +173,25 @@
{
struct wait_queue * wait;
+ /*
+ * We can clear inodes either when a last deref to the inode
+ * causes it to be deleted (reference count==1), or when we want to
+ * reuse it (reference count==0). Any other count is an error.
+ */
+ if (inode->i_count > 1)
+ panic ("clear_inode: Inode still has references");
+
+ /*
+ * We are about to zap this inode. This operation may block,
+ * and it's imperative that we don't allow another process to
+ * grab it before it is completely pulled down. The i_count
+ * will prevent reuse of the inode by get_empty_inode(), but the
+ * i_condemned flag will also prevent __iget() from finding the
+ * inode until it is completely dead.
+ */
+ inode->i_condemned = 1;
inode->i_count++;
+
truncate_inode_pages(inode, 0);
wait_on_inode(inode);
if (IS_WRITABLE(inode)) {
@@ -188,6 +206,11 @@
memset(inode,0,sizeof(*inode));
((volatile struct inode *) inode)->i_wait = wait;
insert_inode_free(inode);
+ /*
+ * The inode is now reusable again, and the condemned flag is
+ * clear. Wake up anybody who is waiting on the condemned flag.
+ */
+ wake_up(&inode->i_wait);
}
int fs_may_mount(kdev_t dev)
@@ -428,6 +451,7 @@
}
if (inode->i_pipe)
wake_up_interruptible(&PIPE_WAIT(*inode));
+
repeat:
if (inode->i_count>1) {
inode->i_count--;
@@ -501,7 +525,7 @@
for (i = nr_inodes/2; i > 0; i--,inode = inode->i_next) {
if (!inode->i_count) {
unsigned long i = 999;
- if (!(inode->i_lock | inode->i_dirt))
+ if (!(inode->i_lock || inode->i_dirt))
i = inode->i_nrpages;
if (i < badness) {
best = inode;
@@ -615,6 +639,15 @@
goto return_it;
found_it:
+ /*
+ * The inode may currently be being pulled down by
+ * clear_inode(). Avoid it if so. If we get past this, then
+ * the increment of i_count will prevent the inode's reuse.
+ */
+ if (inode->i_condemned) {
+ sleep_on(&inode->i_wait);
+ goto repeat;
+ }
if (!inode->i_count)
nr_free_inodes--;
inode->i_count++;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov