linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] simplify udf_iget, fix race
@ 2004-12-12 13:34 Christoph Hellwig
  0 siblings, 0 replies; only message in thread
From: Christoph Hellwig @ 2004-12-12 13:34 UTC (permalink / raw)
  To: akpm; +Cc: linux-fsdevel

udf_iget calls __udf_read_inode after the inode has been unlocked and
other threads could access it.  Switching to iget_locked() fixes this
race and nicely simplifies the code.


--- 1.42/fs/udf/inode.c	2004-09-17 08:58:42 +02:00
+++ edited/fs/udf/inode.c	2004-12-12 14:00:57 +01:00
@@ -920,30 +902,6 @@
 	unlock_kernel();
 }
 
-/*
- * udf_read_inode
- *
- * PURPOSE
- *	Read an inode.
- *
- * DESCRIPTION
- *	This routine is called by iget() [which is called by udf_iget()]
- *      (clean_inode() will have been called first)
- *	when an inode is first read into memory.
- *
- * HISTORY
- *	July 1, 1997 - Andrew E. Mileski
- *	Written, tested, and released.
- *
- * 12/19/98 dgb  Updated to fix size problems.
- */
-
-void
-udf_read_inode(struct inode *inode)
-{
-	memset(&UDF_I_LOCATION(inode), 0xFF, sizeof(kernel_lb_addr));
-}
-
 static void
 __udf_read_inode(struct inode *inode)
 {
@@ -1567,66 +1525,36 @@
 	return err;
 }
 
-/*
- * udf_iget
- *
- * PURPOSE
- *	Get an inode.
- *
- * DESCRIPTION
- *	This routine replaces iget() and read_inode().
- *
- * HISTORY
- *	October 3, 1997 - Andrew E. Mileski
- *	Written, tested, and released.
- *
- * 12/19/98 dgb  Added semaphore and changed to be a wrapper of iget
- */
 struct inode *
 udf_iget(struct super_block *sb, kernel_lb_addr ino)
 {
-	struct inode *inode;
-	unsigned long block;
-
-	block = udf_get_lb_pblock(sb, ino, 0);
-
-	/* Get the inode */
-
-	inode = iget(sb, block);
-		/* calls udf_read_inode() ! */
+	unsigned long block = udf_get_lb_pblock(sb, ino, 0);
+	struct inode *inode = iget_locked(sb, block);
 
 	if (!inode)
-	{
-		printk(KERN_ERR "udf: iget() failed\n");
 		return NULL;
-	}
-	else if (is_bad_inode(inode))
-	{
-		iput(inode);
-		return NULL;
-	}
-	else if (UDF_I_LOCATION(inode).logicalBlockNum == 0xFFFFFFFF &&
-		UDF_I_LOCATION(inode).partitionReferenceNum == 0xFFFF)
-	{
+
+	if (inode->i_state & I_NEW) {
 		memcpy(&UDF_I_LOCATION(inode), &ino, sizeof(kernel_lb_addr));
 		__udf_read_inode(inode);
-		if (is_bad_inode(inode))
-		{
-			iput(inode);
-			return NULL;
-		}
+		unlock_new_inode(inode);
 	}
 
-	if ( ino.logicalBlockNum >= UDF_SB_PARTLEN(sb, ino.partitionReferenceNum) )
-	{
+	if (is_bad_inode(inode))
+		goto out_iput;
+
+	if (ino.logicalBlockNum >= UDF_SB_PARTLEN(sb, ino.partitionReferenceNum)) {
 		udf_debug("block=%d, partition=%d out of range\n",
 			ino.logicalBlockNum, ino.partitionReferenceNum);
 		make_bad_inode(inode);
-		iput(inode);
-		return NULL;
- 	}
+		goto out_iput;
+	}
 
 	return inode;
+
+ out_iput:
+	iput(inode);
+	return NULL;
 }
 
 int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset,
--- 1.45/fs/udf/super.c	2004-09-09 20:49:06 +02:00
+++ edited/fs/udf/super.c	2004-12-12 14:02:19 +01:00
@@ -162,7 +162,6 @@
 static struct super_operations udf_sb_ops = {
 	.alloc_inode		= udf_alloc_inode,
 	.destroy_inode		= udf_destroy_inode,
-	.read_inode		= udf_read_inode,
 	.write_inode		= udf_write_inode,
 	.put_inode		= udf_put_inode,
 	.delete_inode		= udf_delete_inode,

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2004-12-12 13:34 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-12-12 13:34 [PATCH] simplify udf_iget, fix race Christoph Hellwig

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).