public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [BK] [2.4] reiserfs: iget4() race fix, resend
@ 2003-05-12 19:43 Hans Reiser
  0 siblings, 0 replies; only message in thread
From: Hans Reiser @ 2003-05-12 19:43 UTC (permalink / raw)
  To: Linux Kernel Mailing List

[-- Attachment #1: Type: text/plain, Size: 60 bytes --]

I sent this to Marcelo but forgot to cc lkml....

-- 
Hans


[-- Attachment #2: [2.4] reiserfs: iget4() race fix, resend --]
[-- Type: message/rfc822, Size: 3775 bytes --]

From: Oleg Drokin <green@namesys.com>
To: reiser@namesys.com
Subject: [2.4] reiserfs: iget4() race fix, resend
Date: Mon, 12 May 2003 18:09:06 +0400
Message-ID: <20030512140906.GF4165@namesys.com>

Hello!

    This changeset implements a fix for iget4() race possible on reiserfs filesystems.
    This is minimalistic fix that is intended to be replaced with iget5_locked()
    implementation later on. The iget5_locked patch is too much of a change for
    2.4.21-rc2, I afraid. The race itself may lead to pretty much disasters, we've already
    seen it may lead to direntries pointing to nowhere, incorrect nlink counts,
    NFS problems.

    Please pull from bk://namesys.com/bk/reiser3-linux-2.4-race-fix

Diffstat:
 inode.c |   26 ++++++++++++++++++++++++--
 1 files changed, 24 insertions(+), 2 deletions(-)

Plain text patch:

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.1209  -> 1.1210 
#	 fs/reiserfs/inode.c	1.42    -> 1.43   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/05/12	green@angband.namesys.com	1.1210
# reiserfs: iget4() race fix
# --------------------------------------------
#
diff -Nru a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
--- a/fs/reiserfs/inode.c	Mon May 12 17:59:42 2003
+++ b/fs/reiserfs/inode.c	Mon May 12 17:59:42 2003
@@ -20,6 +20,10 @@
 static int reiserfs_get_block (struct inode * inode, long block,
 			       struct buffer_head * bh_result, int create);
 
+/* This spinlock guards inode pkey in private part of inode
+   against race between find_actor() vs reiserfs_read_inode2 */
+static spinlock_t keycopy_lock = SPIN_LOCK_UNLOCKED;
+
 void reiserfs_delete_inode (struct inode * inode)
 {
     int jbegin_count = JOURNAL_PER_BALANCE_CNT * 2; 
@@ -898,8 +902,9 @@
     bh = PATH_PLAST_BUFFER (path);
     ih = PATH_PITEM_HEAD (path);
 
-
+    spin_lock(&keycopy_lock);
     copy_key (INODE_PKEY (inode), &(ih->ih_key));
+    spin_unlock(&keycopy_lock);
     inode->i_blksize = PAGE_SIZE;
 
     INIT_LIST_HEAD(&inode->u.reiserfs_i.i_prealloc_list) ;
@@ -1220,10 +1225,27 @@
 				unsigned long inode_no, void *opaque )
 {
     struct reiserfs_iget4_args *args;
+    int retval;
 
     args = opaque;
+    /* We protect against possible parallel init_inode() on another CPU here. */
+    spin_lock(&keycopy_lock);
     /* args is already in CPU order */
-    return le32_to_cpu(INODE_PKEY(inode)->k_dir_id) == args -> objectid;
+    if (le32_to_cpu(INODE_PKEY(inode)->k_dir_id) == args -> objectid)
+	retval = 1;
+    else
+	/* If The key does not match, lets see if we are racing
+	   with another iget4, that already progressed so far
+	   to reiserfs_read_inode2() and was preempted in
+	   call to search_by_key(). The signs of that are:
+	     Inode is locked
+	     dirid and object id are zero (not yet initialized)*/
+	retval = (inode->i_state & I_LOCK) &&
+		 !INODE_PKEY(inode)->k_dir_id &&
+		 !INODE_PKEY(inode)->k_objectid;
+
+    spin_unlock(&keycopy_lock);
+    return retval;
 }
 
 struct inode * reiserfs_iget (struct super_block * s, const struct cpu_key * key)



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

only message in thread, other threads:[~2003-05-12 19:31 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-05-12 19:43 [BK] [2.4] reiserfs: iget4() race fix, resend Hans Reiser

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox