* [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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.