aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2007-07-26 11:54:16 -0400
committerSteve French <sfrench@us.ibm.com>2007-07-26 11:54:16 -0400
commita403a0a370946e7dbcda6464a3509089daee54bc (patch)
tree6775fb2faae0a8a0ecab8304fb9c24006cc2e773 /fs
parente4903fb59590f86190280a549420f6cb85bd7f7e (diff)
[CIFS] Fix hang in find_writable_file
Caused by unneeded reopen during reconnect while spinlock held. Fixes kernel bugzilla bug #7903 Thanks to Lin Feng Shen for testing this, and Amit Arora for some nice problem determination to narrow this down. Acked-by: Dave Kleikamp <shaggy@us.ibm.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/cifs/CHANGES5
-rw-r--r--fs/cifs/README7
-rw-r--r--fs/cifs/TODO3
-rw-r--r--fs/cifs/file.c33
4 files changed, 35 insertions, 13 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index 6d84ca2beead..bed6215c0794 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -3,7 +3,10 @@ Version 1.50
3Fix NTLMv2 signing. NFS server mounted over cifs works (if cifs mount is 3Fix NTLMv2 signing. NFS server mounted over cifs works (if cifs mount is
4done with "serverino" mount option). Add support for POSIX Unlink 4done with "serverino" mount option). Add support for POSIX Unlink
5(helps with certain sharing violation cases when server such as 5(helps with certain sharing violation cases when server such as
6Samba supports newer POSIX CIFS Protocol Extensions). 6Samba supports newer POSIX CIFS Protocol Extensions). Add "nounix"
7mount option to allow disabling the CIFS Unix Extensions for just
8that mount. Fix hang on spinlock in find_writable_file (race when
9reopening file after session crash).
7 10
8Version 1.49 11Version 1.49
9------------ 12------------
diff --git a/fs/cifs/README b/fs/cifs/README
index 85f1eb14083e..fa096f9c824d 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -444,6 +444,13 @@ A partial list of the supported mount options follows:
444 noposixpaths If CIFS Unix extensions are supported, do not request 444 noposixpaths If CIFS Unix extensions are supported, do not request
445 posix path name support (this may cause servers to 445 posix path name support (this may cause servers to
446 reject creatingfile with certain reserved characters). 446 reject creatingfile with certain reserved characters).
447 nounix Disable the CIFS Unix Extensions for this mount (tree
448 connection). This is rarely needed, but it may be useful
449 in order to turn off multiple settings all at once (ie
450 posix acls, posix locks, posix paths, symlink support
451 and retrieving uids/gids/mode from the server) or to
452 work around a bug in server which implement the Unix
453 Extensions.
447 nobrl Do not send byte range lock requests to the server. 454 nobrl Do not send byte range lock requests to the server.
448 This is necessary for certain applications that break 455 This is necessary for certain applications that break
449 with cifs style mandatory byte range locks (and most 456 with cifs style mandatory byte range locks (and most
diff --git a/fs/cifs/TODO b/fs/cifs/TODO
index d7bd51575fd6..29d4b2715254 100644
--- a/fs/cifs/TODO
+++ b/fs/cifs/TODO
@@ -82,8 +82,7 @@ u) DOS attrs - returned as pseudo-xattr in Samba format (check VFAT and NTFS for
82 82
83v) mount check for unmatched uids 83v) mount check for unmatched uids
84 84
85w) Add mount option for Linux extension disable per mount, and partial 85w) Add support for new vfs entry points for setlease and fallocate
86disable per mount (uid off, symlink/fifo/mknod on but what about posix acls?)
87 86
88x) Fix Samba 3 server to handle Linux kernel aio so dbench with lots of 87x) Fix Samba 3 server to handle Linux kernel aio so dbench with lots of
89processes can proceed better in parallel (on the server) 88processes can proceed better in parallel (on the server)
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index e13592afca9c..894b1f7b299d 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -1904,6 +1904,25 @@ static int cifs_readpage(struct file *file, struct page *page)
1904 return rc; 1904 return rc;
1905} 1905}
1906 1906
1907static int is_inode_writable(struct cifsInodeInfo *cifs_inode)
1908{
1909 struct cifsFileInfo *open_file;
1910
1911 read_lock(&GlobalSMBSeslock);
1912 list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
1913 if (open_file->closePend)
1914 continue;
1915 if (open_file->pfile &&
1916 ((open_file->pfile->f_flags & O_RDWR) ||
1917 (open_file->pfile->f_flags & O_WRONLY))) {
1918 read_unlock(&GlobalSMBSeslock);
1919 return 1;
1920 }
1921 }
1922 read_unlock(&GlobalSMBSeslock);
1923 return 0;
1924}
1925
1907/* We do not want to update the file size from server for inodes 1926/* We do not want to update the file size from server for inodes
1908 open for write - to avoid races with writepage extending 1927 open for write - to avoid races with writepage extending
1909 the file - in the future we could consider allowing 1928 the file - in the future we could consider allowing
@@ -1912,19 +1931,13 @@ static int cifs_readpage(struct file *file, struct page *page)
1912 page caching in the current Linux kernel design */ 1931 page caching in the current Linux kernel design */
1913int is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file) 1932int is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file)
1914{ 1933{
1915 struct cifsFileInfo *open_file = NULL; 1934 if (!cifsInode)
1916 1935 return 1;
1917 if (cifsInode)
1918 open_file = find_writable_file(cifsInode);
1919 1936
1920 if (open_file) { 1937 if (is_inode_writable(cifsInode)) {
1938 /* This inode is open for write at least once */
1921 struct cifs_sb_info *cifs_sb; 1939 struct cifs_sb_info *cifs_sb;
1922 1940
1923 /* there is not actually a write pending so let
1924 this handle go free and allow it to
1925 be closable if needed */
1926 atomic_dec(&open_file->wrtPending);
1927
1928 cifs_sb = CIFS_SB(cifsInode->vfs_inode.i_sb); 1941 cifs_sb = CIFS_SB(cifsInode->vfs_inode.i_sb);
1929 if ( cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO ) { 1942 if ( cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO ) {
1930 /* since no page cache to corrupt on directio 1943 /* since no page cache to corrupt on directio