bk://cifs.bkbits.net/linux-2.5cifs
stevef@steveft21.ltcsamba|ChangeSet|20040707122718|23234 stevef

# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2004/07/07 07:27:18-05:00 stevef@steveft21.ltcsamba 
#   fix oops in build_wildcard_path_from_dentry
# 
# fs/cifs/file.c
#   2004/07/07 07:26:57-05:00 stevef@steveft21.ltcsamba +7 -0
#   fix oops in build_wildcard_path_from_dentry
# 
# fs/cifs/dir.c
#   2004/07/07 07:26:56-05:00 stevef@steveft21.ltcsamba +41 -10
#   fix oops in build_wildcard_path_from_dentry
# 
# fs/cifs/CHANGES
#   2004/07/07 07:26:56-05:00 stevef@steveft21.ltcsamba +2 -1
#   update cifs change log
# 
# ChangeSet
#   2004/07/05 12:53:43-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-cifs
# 
# fs/cifs/cifsfs.c
#   2004/07/05 12:53:40-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/06/25 14:19:24-07:00 akpm@bix.(none) 
#   Merge bk://cifs.bkbits.net/linux-2.5cifs
#   into bix.(none):/usr/src/bk-cifs
# 
# fs/cifs/cifssmb.c
#   2004/06/25 14:19:21-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/06/20 13:06:08-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-cifs
# 
# fs/cifs/cifssmb.c
#   2004/06/20 13:06:05-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/06/19 15:18:03-07:00 akpm@bix.(none) 
#   Merge bk://cifs.bkbits.net/linux-2.5cifs
#   into bix.(none):/usr/src/bk-cifs
# 
# fs/cifs/cifssmb.c
#   2004/06/19 15:17:59-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/06/18 11:48:49-07:00 akpm@bix.(none) 
#   Merge bk://cifs.bkbits.net/linux-2.5cifs
#   into bix.(none):/usr/src/bk-cifs
# 
# fs/cifs/cifssmb.c
#   2004/06/18 11:48:46-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/06/15 21:37:10-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-cifs
# 
# fs/cifs/cifssmb.c
#   2004/06/15 21:37:07-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/06/13 11:11:30-07:00 akpm@bix.(none) 
#   Merge bk://cifs.bkbits.net/linux-2.5cifs
#   into bix.(none):/usr/src/bk-cifs
# 
# fs/cifs/cifssmb.c
#   2004/06/13 11:11:26-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# fs/cifs/cifsfs.c
#   2004/06/13 11:11:26-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/06/07 14:00:04-07:00 akpm@bix.(none) 
#   Merge bk://cifs.bkbits.net/linux-2.5cifs
#   into bix.(none):/usr/src/bk-cifs
# 
# fs/cifs/cifssmb.c
#   2004/06/07 14:00:00-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/06/02 13:18:48-07:00 akpm@bix.(none) 
#   Merge bk://cifs.bkbits.net/linux-2.5cifs
#   into bix.(none):/usr/src/bk-cifs
# 
# fs/cifs/cifssmb.c
#   2004/06/02 13:18:44-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/27 21:24:47-07:00 akpm@bix.(none) 
#   Merge bk://cifs.bkbits.net/linux-2.5cifs
#   into bix.(none):/usr/src/bk-cifs
# 
# fs/cifs/cifssmb.c
#   2004/05/27 21:24:44-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# fs/cifs/cifsfs.c
#   2004/05/27 21:24:43-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/27 12:36:56-07:00 akpm@bix.(none) 
#   Merge bk://cifs.bkbits.net/linux-2.5cifs
#   into bix.(none):/usr/src/bk-cifs
# 
# fs/cifs/cifssmb.c
#   2004/05/27 12:36:53-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/25 21:18:56-07:00 akpm@bix.(none) 
#   Merge bk://cifs.bkbits.net/linux-2.5cifs
#   into bix.(none):/usr/src/bk-cifs
# 
# fs/cifs/cifssmb.c
#   2004/05/25 21:18:53-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/24 18:04:01-07:00 akpm@bix.(none) 
#   Merge bk://cifs.bkbits.net/linux-2.5cifs
#   into bix.(none):/usr/src/bk-cifs
# 
# fs/cifs/cifssmb.c
#   2004/05/24 18:03:57-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/22 23:28:34-07:00 akpm@bix.(none) 
#   Merge bk://cifs.bkbits.net/linux-2.5cifs
#   into bix.(none):/usr/src/bk-cifs
# 
# fs/cifs/cifssmb.c
#   2004/05/22 23:28:31-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/18 14:31:25-07:00 akpm@bix.(none) 
#   Merge bk://cifs.bkbits.net/linux-2.5cifs
#   into bix.(none):/usr/src/bk-cifs
# 
# fs/cifs/cifsfs.c
#   2004/05/18 14:31:22-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/11 16:37:09-07:00 akpm@bix.(none) 
#   Merge bk://cifs.bkbits.net/linux-2.5cifs
#   into bix.(none):/usr/src/bk-cifs
# 
# fs/cifs/cifssmb.c
#   2004/05/11 16:37:06-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/04 13:51:19-07:00 akpm@bix.(none) 
#   Merge bk://cifs.bkbits.net/linux-2.5cifs
#   into bix.(none):/usr/src/bk-cifs
# 
# fs/cifs/cifssmb.c
#   2004/05/04 13:51:17-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/02 21:56:11-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-cifs
# 
# fs/cifs/cifssmb.c
#   2004/05/02 21:56:09-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# fs/cifs/cifsfs.c
#   2004/05/02 21:56:08-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/01 15:05:17-07:00 akpm@bix.(none) 
#   Merge bk://cifs.bkbits.net/linux-2.5cifs
#   into bix.(none):/usr/src/bk-cifs
# 
# fs/cifs/cifssmb.c
#   2004/05/01 15:05:14-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/04/29 15:41:50-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-cifs
# 
# fs/cifs/cifssmb.c
#   2004/04/29 15:41:48-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/04/26 18:11:55-07:00 akpm@bix.(none) 
#   Merge bk://cifs.bkbits.net/linux-2.5cifs
#   into bix.(none):/usr/src/bk-cifs
# 
# fs/cifs/cifsfs.c
#   2004/04/26 18:11:52-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/04/23 12:36:52-07:00 akpm@bix.(none) 
#   Merge bk://cifs.bkbits.net/linux-2.5cifs
#   into bix.(none):/usr/src/bk-cifs
# 
# fs/cifs/cifsfs.c
#   2004/04/23 12:36:49-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/04/19 19:23:58-07:00 akpm@bix.(none) 
#   Merge bk://cifs.bkbits.net/linux-2.5cifs
#   into bix.(none):/usr/src/bk-cifs
# 
# fs/cifs/cifsfs.c
#   2004/04/19 19:23:56-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/04/16 20:19:53-07:00 akpm@bix.(none) 
#   Merge bk://cifs.bkbits.net/linux-2.5cifs
#   into bix.(none):/usr/src/bk-cifs
# 
# fs/cifs/cifsfs.c
#   2004/04/16 20:19:51-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/04/16 20:18:59-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-cifs
# 
# fs/cifs/cifsfs.c
#   2004/04/16 20:18:56-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
diff -Nru a/fs/cifs/CHANGES b/fs/cifs/CHANGES
--- a/fs/cifs/CHANGES	2004-07-08 18:11:17 -07:00
+++ b/fs/cifs/CHANGES	2004-07-08 18:11:17 -07:00
@@ -1,7 +1,8 @@
 Version 1.20
 ------------
 Make transaction counts more consistent. Merge /proc/fs/cifs/SimultaneousOps
-info into /proc/fs/cifs/DebugData
+info into /proc/fs/cifs/DebugData.  Fix oops in rare oops in readdir 
+(in build_wildcard_path_from_dentry).
 
 Version 1.19
 ------------
diff -Nru a/fs/cifs/dir.c b/fs/cifs/dir.c
--- a/fs/cifs/dir.c	2004-07-08 18:11:17 -07:00
+++ b/fs/cifs/dir.c	2004-07-08 18:11:17 -07:00
@@ -101,6 +101,7 @@
 	return full_path;
 }
 
+/* Note: caller must free return buffer */
 char *
 build_wildcard_path_from_dentry(struct dentry *direntry)
 {
@@ -108,18 +109,28 @@
 	int namelen = 0;
 	char *full_path;
 
+	if(direntry == NULL)
+		return NULL;  /* not much we can do if dentry is freed and
+		we need to reopen the file after it was closed implicitly
+		when the server crashed */
+
+cifs_bwp_rename_retry:
 	for (temp = direntry; !IS_ROOT(temp);) {
 		namelen += (1 + temp->d_name.len);
 		temp = temp->d_parent;
+		if(temp == NULL) {
+			cERROR(1,("corrupt dentry"));
+			return NULL;
+		}
 	}
-	namelen += 3;		/* allow for trailing null and wildcard (slash and *) */
-	full_path = kmalloc(namelen, GFP_KERNEL);
-	namelen--;
-	full_path[namelen] = 0;	/* trailing null */
-	namelen--;
-	full_path[namelen] = '*';
-	namelen--;
+
+	full_path = kmalloc(namelen+3, GFP_KERNEL);
+	if(full_path == NULL)
+		return full_path;
+
 	full_path[namelen] = '\\';
+	full_path[namelen+1] = '*';
+	full_path[namelen+2] = 0;  /* trailing null */
 
 	for (temp = direntry; !IS_ROOT(temp);) {
 		namelen -= 1 + temp->d_name.len;
@@ -129,13 +140,26 @@
 			full_path[namelen] = '\\';
 			strncpy(full_path + namelen + 1, temp->d_name.name,
 				temp->d_name.len);
+			cFYI(0, (" name: %s ", full_path + namelen));
 		}
 		temp = temp->d_parent;
+		if(temp == NULL) {
+			cERROR(1,("corrupt dentry"));
+			kfree(full_path);
+			return NULL;
+		}
 	}
-	if (namelen != 0)
+	if (namelen != 0) {
 		cERROR(1,
 		       ("We did not end path lookup where we expected namelen is %d",
 			namelen));
+		/* presumably this is only possible if we were racing with a rename 
+		of one of the parent directories  (we can not lock the dentries
+		above us to prevent this, but retrying should be harmless) */
+		kfree(full_path);
+		namelen = 0;
+		goto cifs_bwp_rename_retry;
+	}
 
 	return full_path;
 }
@@ -431,9 +455,16 @@
 	cifs_sb = CIFS_SB(inode->i_sb);
 	pTcon = cifs_sb->tcon;
 
-	full_path = build_wildcard_path_from_dentry(file->f_dentry);
+	if(file->f_dentry) {
+		down(&file->f_dentry->d_sb->s_vfs_rename_sem);
+		full_path = build_wildcard_path_from_dentry(file->f_dentry);
+		up(&file->f_dentry->d_sb->s_vfs_rename_sem);
+	} else {
+		FreeXid(xid);
+		return -EIO;
+	}
 
-	cFYI(1, (" inode = 0x%p and full path is %s", inode, full_path));
+	cFYI(1, ("inode = 0x%p and full path is %s", inode, full_path));
 
 	if (full_path)
 		kfree(full_path);
diff -Nru a/fs/cifs/file.c b/fs/cifs/file.c
--- a/fs/cifs/file.c	2004-07-08 18:11:17 -07:00
+++ b/fs/cifs/file.c	2004-07-08 18:11:17 -07:00
@@ -1682,7 +1682,14 @@
 	data = kmalloc(bufsize, GFP_KERNEL);
 	pfindData = (FILE_DIRECTORY_INFO *) data;
 
+	if(file->f_dentry == NULL) {
+		FreeXid(xid);
+		return -EIO;
+	}
+	down(&file->f_dentry->d_sb->s_vfs_rename_sem);
 	full_path = build_wildcard_path_from_dentry(file->f_dentry);
+	up(&file->f_dentry->d_sb->s_vfs_rename_sem);
+
 
 	cFYI(1, ("Full path: %s start at: %lld ", full_path, file->f_pos));
 
