[Ocfs2-commits] mfasheh commits r2377 - trunk/fs/ocfs2
svn-commits at oss.oracle.com
svn-commits at oss.oracle.com
Tue Jun 7 19:51:12 CDT 2005
Author: mfasheh
Signed-off-by: jlbec
Date: 2005-06-07 19:51:11 -0500 (Tue, 07 Jun 2005)
New Revision: 2377
Modified:
trunk/fs/ocfs2/inode.c
Log:
* don't wait on freeing inodes during ilookup which comes from the vote
thread. this fixes a deadlock where ocfs2 gets a vote for the inode while
another process on the system is in delete_inode waiting on the lock.
Signed-off-by: jlbec
Modified: trunk/fs/ocfs2/inode.c
===================================================================
--- trunk/fs/ocfs2/inode.c 2005-06-08 00:25:15 UTC (rev 2376)
+++ trunk/fs/ocfs2/inode.c 2005-06-08 00:51:11 UTC (rev 2377)
@@ -54,11 +54,12 @@
extern struct address_space_operations ocfs2_aops;
+#define OCFS2_FI_FLAG_NOWAIT 0x1
struct ocfs2_find_inode_args
{
- u64 blkno;
- unsigned long ino;
- u32 flags;
+ u64 fi_blkno;
+ unsigned long fi_ino;
+ unsigned int fi_flags;
};
static int ocfs2_read_locked_inode(struct inode *inode,
@@ -73,10 +74,15 @@
{
struct ocfs2_find_inode_args args;
- args.blkno = blkno;
- args.flags = 0;
- args.ino = ino_from_blkno(osb->sb, blkno);
- return ilookup5(osb->sb, args.ino, ocfs2_find_actor, &args);
+ /* ocfs2_ilookup should *only* be called from the vote thread,
+ * unless modified to conditionally set
+ * OCFS2_FI_FLAG_NOWAIT */
+ BUG_ON(current != osb->vote_task);
+
+ args.fi_blkno = blkno;
+ args.fi_flags = OCFS2_FI_FLAG_NOWAIT;
+ args.fi_ino = ino_from_blkno(osb->sb, blkno);
+ return ilookup5(osb->sb, args.fi_ino, ocfs2_find_actor, &args);
}
struct inode *ocfs2_iget(ocfs2_super *osb, u64 blkno)
@@ -84,7 +90,6 @@
struct inode *inode = NULL;
struct super_block *sb = osb->sb;
struct ocfs2_find_inode_args args;
- u32 flags = 0;
mlog_entry("(blkno = %"MLFu64")\n", blkno);
@@ -96,11 +101,11 @@
goto bail;
}
- args.blkno = blkno;
- args.flags = flags;
- args.ino = ino_from_blkno(sb, blkno);
+ args.fi_blkno = blkno;
+ args.fi_flags = 0;
+ args.fi_ino = ino_from_blkno(sb, blkno);
- inode = iget5_locked(sb, args.ino, ocfs2_find_actor,
+ inode = iget5_locked(sb, args.fi_ino, ocfs2_find_actor,
ocfs2_init_locked_inode, &args);
/* inode was *not* in the inode cache. 2.6.x requires
* us to do our own read_inode call and unlock it
@@ -151,9 +156,21 @@
mlog_bug_on_msg(!inode, "No inode in find actor!\n");
- if (OCFS2_I(inode)->ip_blkno != args->blkno)
+ if (OCFS2_I(inode)->ip_blkno != args->fi_blkno)
goto bail;
+ /* OCFS2_FI_FLAG_NOWAIT is *only* set from ocfs2_ilookup which
+ * won't create an inode for one that isn't
+ * found. ocfs2_ilookup is called from the vote thread which
+ * doesn't want to get an inode which is in the process of
+ * going away - otherwise the call to __wait_on_freeing_inode
+ * in find_inode_fast will cause it to deadlock on an inode
+ * which may be waiting on a vote (or lock release) in
+ * delete_inode */
+ if ((args->fi_flags & OCFS2_FI_FLAG_NOWAIT) &&
+ (inode->i_state & (I_FREEING|I_CLEAR)))
+ goto bail;
+
ret = 1;
bail:
mlog_exit(ret);
@@ -171,8 +188,8 @@
mlog_entry("inode = %p, opaque = %p\n", inode, opaque);
- inode->i_ino = args->ino;
- OCFS2_I(inode)->ip_blkno = args->blkno;
+ inode->i_ino = args->fi_ino;
+ OCFS2_I(inode)->ip_blkno = args->fi_blkno;
mlog_exit(0);
return 0;
@@ -330,7 +347,7 @@
/* Read the FE off disk. This is safe because the kernel only
* does one read_inode2 for a new inode, and if it doesn't
* exist yet then nobody can be working on it! */
- status = ocfs2_read_block(osb, args->blkno, &bh, 0, NULL);
+ status = ocfs2_read_block(osb, args->fi_blkno, &bh, 0, NULL);
if (status < 0) {
mlog_errno(status);
make_bad_inode(inode);
@@ -357,8 +374,7 @@
goto bail;
}
- if (args->blkno != fe->i_blkno)
- BUG();
+ BUG_ON(args->fi_blkno != fe->i_blkno);
if (sysfile)
OCFS2_I(inode)->ip_flags |= OCFS2_INODE_SYSTEM_FILE;
More information about the Ocfs2-commits
mailing list