diff options
author | Pavel Shilovsky <piastry@etersoft.ru> | 2011-05-26 02:01:59 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2011-05-26 14:07:02 -0400 |
commit | fa2989f4473413a86890066aa3a5676a53b541e4 (patch) | |
tree | a033c59307ba77ae0819e818aec7d68178d11d4d /fs/cifs/file.c | |
parent | c28c89fc43e3f81436efc4748837534d4d46f90c (diff) |
CIFS: Use pid saved from cifsFileInfo in writepages and set_file_size
We need it to make them work with mandatory locking style because
we can fail in a situation like when kernel need to flush dirty pages
and there is a lock held by a process who opened file.
Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru>
Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r-- | fs/cifs/file.c | 31 |
1 files changed, 21 insertions, 10 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 00b926ce7935..dfc0d35b1470 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -857,7 +857,7 @@ cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset, | |||
857 | cifsi->server_eof = end_of_write; | 857 | cifsi->server_eof = end_of_write; |
858 | } | 858 | } |
859 | 859 | ||
860 | static ssize_t cifs_write(struct cifsFileInfo *open_file, | 860 | static ssize_t cifs_write(struct cifsFileInfo *open_file, __u32 pid, |
861 | const char *write_data, size_t write_size, | 861 | const char *write_data, size_t write_size, |
862 | loff_t *poffset) | 862 | loff_t *poffset) |
863 | { | 863 | { |
@@ -869,6 +869,7 @@ static ssize_t cifs_write(struct cifsFileInfo *open_file, | |||
869 | int xid; | 869 | int xid; |
870 | struct dentry *dentry = open_file->dentry; | 870 | struct dentry *dentry = open_file->dentry; |
871 | struct cifsInodeInfo *cifsi = CIFS_I(dentry->d_inode); | 871 | struct cifsInodeInfo *cifsi = CIFS_I(dentry->d_inode); |
872 | struct cifs_io_parms io_parms; | ||
872 | 873 | ||
873 | cifs_sb = CIFS_SB(dentry->d_sb); | 874 | cifs_sb = CIFS_SB(dentry->d_sb); |
874 | 875 | ||
@@ -901,8 +902,13 @@ static ssize_t cifs_write(struct cifsFileInfo *open_file, | |||
901 | /* iov[0] is reserved for smb header */ | 902 | /* iov[0] is reserved for smb header */ |
902 | iov[1].iov_base = (char *)write_data + total_written; | 903 | iov[1].iov_base = (char *)write_data + total_written; |
903 | iov[1].iov_len = len; | 904 | iov[1].iov_len = len; |
904 | rc = CIFSSMBWrite2(xid, pTcon, open_file->netfid, len, | 905 | io_parms.netfid = open_file->netfid; |
905 | *poffset, &bytes_written, iov, 1, 0); | 906 | io_parms.pid = pid; |
907 | io_parms.tcon = pTcon; | ||
908 | io_parms.offset = *poffset; | ||
909 | io_parms.length = len; | ||
910 | rc = CIFSSMBWrite2(xid, &io_parms, &bytes_written, iov, | ||
911 | 1, 0); | ||
906 | } | 912 | } |
907 | if (rc || (bytes_written == 0)) { | 913 | if (rc || (bytes_written == 0)) { |
908 | if (total_written) | 914 | if (total_written) |
@@ -1071,8 +1077,8 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to) | |||
1071 | 1077 | ||
1072 | open_file = find_writable_file(CIFS_I(mapping->host), false); | 1078 | open_file = find_writable_file(CIFS_I(mapping->host), false); |
1073 | if (open_file) { | 1079 | if (open_file) { |
1074 | bytes_written = cifs_write(open_file, write_data, | 1080 | bytes_written = cifs_write(open_file, open_file->pid, |
1075 | to - from, &offset); | 1081 | write_data, to - from, &offset); |
1076 | cifsFileInfo_put(open_file); | 1082 | cifsFileInfo_put(open_file); |
1077 | /* Does mm or vfs already set times? */ | 1083 | /* Does mm or vfs already set times? */ |
1078 | inode->i_atime = inode->i_mtime = current_fs_time(inode->i_sb); | 1084 | inode->i_atime = inode->i_mtime = current_fs_time(inode->i_sb); |
@@ -1363,8 +1369,8 @@ static int cifs_write_end(struct file *file, struct address_space *mapping, | |||
1363 | /* BB check if anything else missing out of ppw | 1369 | /* BB check if anything else missing out of ppw |
1364 | such as updating last write time */ | 1370 | such as updating last write time */ |
1365 | page_data = kmap(page); | 1371 | page_data = kmap(page); |
1366 | rc = cifs_write(file->private_data, page_data + offset, | 1372 | rc = cifs_write(file->private_data, current->tgid, |
1367 | copied, &pos); | 1373 | page_data + offset, copied, &pos); |
1368 | /* if (rc < 0) should we set writebehind rc? */ | 1374 | /* if (rc < 0) should we set writebehind rc? */ |
1369 | kunmap(page); | 1375 | kunmap(page); |
1370 | 1376 | ||
@@ -1515,6 +1521,7 @@ cifs_iovec_write(struct file *file, const struct iovec *iov, | |||
1515 | struct cifsFileInfo *open_file; | 1521 | struct cifsFileInfo *open_file; |
1516 | struct cifsTconInfo *pTcon; | 1522 | struct cifsTconInfo *pTcon; |
1517 | struct cifs_sb_info *cifs_sb; | 1523 | struct cifs_sb_info *cifs_sb; |
1524 | struct cifs_io_parms io_parms; | ||
1518 | int xid, rc; | 1525 | int xid, rc; |
1519 | 1526 | ||
1520 | len = iov_length(iov, nr_segs); | 1527 | len = iov_length(iov, nr_segs); |
@@ -1573,9 +1580,13 @@ cifs_iovec_write(struct file *file, const struct iovec *iov, | |||
1573 | if (rc != 0) | 1580 | if (rc != 0) |
1574 | break; | 1581 | break; |
1575 | } | 1582 | } |
1576 | rc = CIFSSMBWrite2(xid, pTcon, open_file->netfid, | 1583 | io_parms.netfid = open_file->netfid; |
1577 | cur_len, *poffset, &written, | 1584 | io_parms.pid = current->tgid; |
1578 | to_send, npages, 0); | 1585 | io_parms.tcon = pTcon; |
1586 | io_parms.offset = *poffset; | ||
1587 | io_parms.length = cur_len; | ||
1588 | rc = CIFSSMBWrite2(xid, &io_parms, &written, to_send, | ||
1589 | npages, 0); | ||
1579 | } while (rc == -EAGAIN); | 1590 | } while (rc == -EAGAIN); |
1580 | 1591 | ||
1581 | for (i = 0; i < npages; i++) | 1592 | for (i = 0; i < npages; i++) |