patch-2.4.0-test3 linux/fs/ncpfs/dir.c

Next file: linux/fs/ncpfs/file.c
Previous file: linux/fs/namei.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0-test2/linux/fs/ncpfs/dir.c linux/fs/ncpfs/dir.c
@@ -21,6 +21,7 @@
 #include <asm/uaccess.h>
 #include <asm/byteorder.h>
 #include <linux/locks.h>
+#include <linux/smp_lock.h>
 
 #include <linux/ncp_fs.h>
 
@@ -253,7 +254,7 @@
 
 
 static int
-ncp_lookup_validate(struct dentry * dentry, int flags)
+__ncp_lookup_validate(struct dentry * dentry, int flags)
 {
 	struct ncp_server *server;
 	struct inode *dir = dentry->d_parent->d_inode;
@@ -315,6 +316,16 @@
 	return val;
 }
 
+static int
+ncp_lookup_validate(struct dentry * dentry, int flags)
+{
+	int res;
+	lock_kernel();
+	res = __ncp_lookup_validate(dentry, flags);
+	unlock_kernel();
+	return res;
+}
+
 /* most parts from nfsd_d_validate() */
 static int
 ncp_d_validate(struct dentry *dentry)
@@ -361,26 +372,38 @@
 	struct dentry *dent = dentry;
 	struct list_head *next;
 
-	if (ncp_d_validate(dent))
-		if ((dent->d_parent == parent) &&
-		    ((unsigned long)dent->d_fsdata == fpos))
-			goto out;
+	if (ncp_d_validate(dent)) {
+		if (dent->d_parent == parent &&
+		   (unsigned long)dent->d_fsdata == fpos) {
+			if (!dent->d_inode) {
+				dput(dent);
+				dent = NULL;
+			}
+			return dent;
+		}
+		dput(dent);
+	}
 
 	/* If a pointer is invalid, we search the dentry. */
+	spin_lock(&dcache_lock);
 	next = parent->d_subdirs.next;
 	while (next != &parent->d_subdirs) {
 		dent = list_entry(next, struct dentry, d_child);
-		if ((unsigned long)dent->d_fsdata == fpos)
+		if ((unsigned long)dent->d_fsdata == fpos) {
+			if (dent->d_inode)
+				dget_locked(dent);
+			else
+				dent = NULL;
+			spin_unlock(&dcache_lock);
 			goto out;
+		}
 		next = next->next;
 	}
+	spin_unlock(&dcache_lock);
 	return NULL;
 
 out:
-	if (dent->d_inode)
-		return dget(dent);
-
-	return NULL;
+	return dent;
 }
 
 static time_t ncp_obtain_mtime(struct dentry *dentry)
@@ -973,7 +996,7 @@
 	/*
 	 * Check whether to close the file ...
 	 */
-	if (inode && NCP_FINFO(inode)->opened) {
+	if (inode) {
 		PPRINTK("ncp_unlink: closing file\n");
 		ncp_make_closed(inode);
 	}
@@ -982,7 +1005,7 @@
 #ifdef CONFIG_NCPFS_STRONG
 	/* 9C is Invalid path.. It should be 8F, 90 - read only, but
 	   it is not :-( */
-	if (error == 0x9C && server->m.flags & NCP_MOUNT_STRONG) { /* R/O */
+	if ((error == 0x9C || error == 0x90) && server->m.flags & NCP_MOUNT_STRONG) { /* R/O */
 		error = ncp_force_unlink(dir, dentry);
 	}
 #endif
@@ -1051,7 +1074,7 @@
 	error = ncp_ren_or_mov_file_or_subdir(server, old_dir, __old_name,
 						      new_dir, __new_name);
 #ifdef CONFIG_NCPFS_STRONG
-	if ((error == 0x90 || error == -EACCES) &&
+	if ((error == 0x90 || error == 0x8B || error == -EACCES) &&
 			server->m.flags & NCP_MOUNT_STRONG) {	/* RO */
 		error = ncp_force_rename(old_dir, old_dentry, __old_name,
 					 new_dir, new_dentry, __new_name);

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)