[PATCH] i_nlink should be checked while holding commit_sem (1 of 1)

Dave Kleikamp <[email protected]> Mon, 3 Nov 2003 09:27:46 -0600
Newsgroups gmane.comp.file-systems.jfs.patches
Message-ID <[email protected]>
# 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.1173.1.1 -> 1.1173.2.1
#	      fs/jfs/namei.c	1.19    -> 1.20   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/10/31	[email protected]	1.1173.2.1
# JFS: i_nlink should be checked while holding commit_sem
# 
# In the 2.6 kernel, both jfs_link and jfs_unlink are called while holding
# i_sem.  This is not true in the 2.4 kernel.  There is still a window where a
# race between link and unlink can cause i_nlink to go to zero and then back
# to one.  This fix closes that window.
# --------------------------------------------
#
diff -Nru a/fs/jfs/namei.c b/fs/jfs/namei.c
--- a/fs/jfs/namei.c	Mon Nov  3 09:13:29 2003
+++ b/fs/jfs/namei.c	Mon Nov  3 09:13:29 2003
@@ -758,12 +758,6 @@
 	jfs_info("jfs_link: %s %s", old_dentry->d_name.name,
 		 dentry->d_name.name);
 
-	if (ip->i_nlink == JFS_LINK_MAX)
-		return -EMLINK;
-
-	if (ip->i_nlink == 0)
-		return -ENOENT;
-
 	/* JFS does NOT support link() on directories */
 	if (S_ISDIR(ip->i_mode))
 		return -EPERM;
@@ -772,6 +766,16 @@
 
 	down(&JFS_IP(dir)->commit_sem);
 	down(&JFS_IP(ip)->commit_sem);
+
+	if (ip->i_nlink == JFS_LINK_MAX) {
+		rc = -EMLINK;
+		goto out;
+	}
+
+	if (ip->i_nlink == 0) {
+		rc = -ENOENT;
+		goto out;
+	}
 
 	/*
 	 * scan parent directory for entry/freespace