mtd/fs/jffs2 readinode.c,1.58.2.5,1.58.2.6 gc.c,1.52.2.4,1.52.2.5
David Woodhouse
dwmw2 at infradead.org
Thu Oct 10 09:18:41 EDT 2002
- Previous message: mtd/fs/jffs2 erase.c,1.44,1.45
- Next message: mtd/fs/jffs2 Makefile,1.25,1.25.2.1 compr_zlib.c,1.8,1.8.2.1 nodelist.h,1.46.2.2,1.46.2.3 super.c,1.48.2.2,1.48.2.3 zlib.h,1.1,NONE zlib.c,1.1.2.1,NONE
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /home/cvs/mtd/fs/jffs2
In directory phoenix.infradead.org:/tmp/cvs-serv16571
Modified Files:
Tag: jffs2-2_4-branch
readinode.c gc.c
Log Message:
Fix case where clear_inode and read_inode are called simultaneously by the VFS for the same inode
Index: readinode.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/readinode.c,v
retrieving revision 1.58.2.5
retrieving revision 1.58.2.6
diff -u -r1.58.2.5 -r1.58.2.6
--- readinode.c 5 Mar 2002 22:40:03 -0000 1.58.2.5
+++ readinode.c 10 Oct 2002 13:18:38 -0000 1.58.2.6
@@ -468,15 +468,28 @@
struct jffs2_node_frag *frag, *frags;
struct jffs2_full_dirent *fd, *fds;
struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
+ /* I don't think we care about the potential race due to reading this
+ without f->sem. It can never get undeleted. */
+ int deleted = f->inocache && !f->inocache->nlink;
D1(printk(KERN_DEBUG "jffs2_clear_inode(): ino #%lu mode %o\n", inode->i_ino, inode->i_mode));
+ /* If it's a deleted inode, grab the alloc_sem. This prevents
+ jffs2_garbage_collect_pass() from deciding that it wants to
+ garbage collect one of the nodes we're just about to mark
+ obsolete -- by the time we drop alloc_sem and return, all
+ the nodes are marked obsolete, and jffs2_g_c_pass() won't
+ call iget() for the inode in question.
+ */
+ if (deleted)
+ down(&c->alloc_sem);
+
down(&f->sem);
frags = f->fraglist;
fds = f->dents;
if (f->metadata) {
- if (!f->inocache->nlink)
+ if (deleted)
jffs2_mark_node_obsolete(c, f->metadata->raw);
jffs2_free_full_dnode(f->metadata);
}
@@ -488,7 +501,7 @@
if (frag->node && !(--frag->node->frags)) {
/* Not a hole, and it's the final remaining frag of this node. Free the node */
- if (!f->inocache->nlink)
+ if (deleted)
jffs2_mark_node_obsolete(c, frag->node->raw);
jffs2_free_full_dnode(frag->node);
@@ -502,5 +515,8 @@
}
up(&f->sem);
+
+ if(deleted)
+ up(&c->alloc_sem);
};
Index: gc.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/gc.c,v
retrieving revision 1.52.2.4
retrieving revision 1.52.2.5
diff -u -r1.52.2.4 -r1.52.2.5
--- gc.c 15 May 2002 12:51:23 -0000 1.52.2.4
+++ gc.c 10 Oct 2002 13:18:38 -0000 1.52.2.5
@@ -134,8 +134,10 @@
D1(printk(KERN_DEBUG "garbage collect from block at phys 0x%08x\n", jeb->offset));
- if (!jeb->used_size)
+ if (!jeb->used_size) {
+ up(&c->alloc_sem);
goto eraseit;
+ }
raw = jeb->gc_node;
@@ -156,6 +158,7 @@
/* Inode-less node. Clean marker, snapshot or something like that */
spin_unlock_bh(&c->erase_completion_lock);
jffs2_mark_node_obsolete(c, raw);
+ up(&c->alloc_sem);
goto eraseit_lock;
}
@@ -170,8 +173,8 @@
if (is_bad_inode(inode)) {
printk(KERN_NOTICE "Eep. read_inode() failed for ino #%u\n", inum);
/* NB. This will happen again. We need to do something appropriate here. */
- iput(inode);
up(&c->alloc_sem);
+ iput(inode);
return -EIO;
}
@@ -234,6 +237,7 @@
}
upnout:
up(&f->sem);
+ up(&c->alloc_sem);
iput(inode);
eraseit_lock:
@@ -250,7 +254,6 @@
jffs2_erase_pending_trigger(c);
}
spin_unlock_bh(&c->erase_completion_lock);
- up(&c->alloc_sem);
return ret;
}
- Previous message: mtd/fs/jffs2 erase.c,1.44,1.45
- Next message: mtd/fs/jffs2 Makefile,1.25,1.25.2.1 compr_zlib.c,1.8,1.8.2.1 nodelist.h,1.46.2.2,1.46.2.3 super.c,1.48.2.2,1.48.2.3 zlib.h,1.1,NONE zlib.c,1.1.2.1,NONE
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the linux-mtd-cvs
mailing list