diff options
author | Dave Kleikamp <shaggy@linux.vnet.ibm.com> | 2009-08-31 11:07:12 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2009-09-01 18:35:01 -0400 |
commit | 6ab409b53dcaf28f83d518a6702f904b7cee3f41 (patch) | |
tree | 050bfb690ac9df049343034681478a5bb174a823 /fs/cifs/inode.c | |
parent | 1b49c5566136455764a8d17ead25784f534c202d (diff) |
cifs: Replace wrtPending with a real reference count
Currently, cifs_close() tries to wait until all I/O is complete and then
frees the file private data. If I/O does not completely in a reasonable
amount of time it frees the structure anyway, leaving a potential use-
after-free situation.
This patch changes the wrtPending counter to a complete reference count and
lets the last user free the structure.
Signed-off-by: Dave Kleikamp <shaggy@linux.vnet.ibm.com>
Reviewed-by: Jeff Layton <jlayton@redhat.com>
Tested-by: Shirish Pargaonkar <shirishp@us.ibm.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/inode.c')
-rw-r--r-- | fs/cifs/inode.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 82d83839655e..1f09c7619319 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -800,7 +800,7 @@ set_via_filehandle: | |||
800 | if (open_file == NULL) | 800 | if (open_file == NULL) |
801 | CIFSSMBClose(xid, pTcon, netfid); | 801 | CIFSSMBClose(xid, pTcon, netfid); |
802 | else | 802 | else |
803 | atomic_dec(&open_file->wrtPending); | 803 | cifsFileInfo_put(open_file); |
804 | out: | 804 | out: |
805 | return rc; | 805 | return rc; |
806 | } | 806 | } |
@@ -1635,7 +1635,7 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs, | |||
1635 | __u32 npid = open_file->pid; | 1635 | __u32 npid = open_file->pid; |
1636 | rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, nfid, | 1636 | rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, nfid, |
1637 | npid, false); | 1637 | npid, false); |
1638 | atomic_dec(&open_file->wrtPending); | 1638 | cifsFileInfo_put(open_file); |
1639 | cFYI(1, ("SetFSize for attrs rc = %d", rc)); | 1639 | cFYI(1, ("SetFSize for attrs rc = %d", rc)); |
1640 | if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { | 1640 | if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { |
1641 | unsigned int bytes_written; | 1641 | unsigned int bytes_written; |
@@ -1790,7 +1790,7 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs) | |||
1790 | u16 nfid = open_file->netfid; | 1790 | u16 nfid = open_file->netfid; |
1791 | u32 npid = open_file->pid; | 1791 | u32 npid = open_file->pid; |
1792 | rc = CIFSSMBUnixSetFileInfo(xid, pTcon, args, nfid, npid); | 1792 | rc = CIFSSMBUnixSetFileInfo(xid, pTcon, args, nfid, npid); |
1793 | atomic_dec(&open_file->wrtPending); | 1793 | cifsFileInfo_put(open_file); |
1794 | } else { | 1794 | } else { |
1795 | rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, args, | 1795 | rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, args, |
1796 | cifs_sb->local_nls, | 1796 | cifs_sb->local_nls, |