aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r--fs/cifs/file.c64
1 files changed, 50 insertions, 14 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 81747acca4c4..dfd3e6c52a1e 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -971,6 +971,40 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
971 return rc; 971 return rc;
972} 972}
973 973
974/*
975 * Set the timeout on write requests past EOF. For some servers (Windows)
976 * these calls can be very long.
977 *
978 * If we're writing >10M past the EOF we give a 180s timeout. Anything less
979 * than that gets a 45s timeout. Writes not past EOF get 15s timeouts.
980 * The 10M cutoff is totally arbitrary. A better scheme for this would be
981 * welcome if someone wants to suggest one.
982 *
983 * We may be able to do a better job with this if there were some way to
984 * declare that a file should be sparse.
985 */
986static int
987cifs_write_timeout(struct cifsInodeInfo *cifsi, loff_t offset)
988{
989 if (offset <= cifsi->server_eof)
990 return CIFS_STD_OP;
991 else if (offset > (cifsi->server_eof + (10 * 1024 * 1024)))
992 return CIFS_VLONG_OP;
993 else
994 return CIFS_LONG_OP;
995}
996
997/* update the file size (if needed) after a write */
998static void
999cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset,
1000 unsigned int bytes_written)
1001{
1002 loff_t end_of_write = offset + bytes_written;
1003
1004 if (end_of_write > cifsi->server_eof)
1005 cifsi->server_eof = end_of_write;
1006}
1007
974ssize_t cifs_user_write(struct file *file, const char __user *write_data, 1008ssize_t cifs_user_write(struct file *file, const char __user *write_data,
975 size_t write_size, loff_t *poffset) 1009 size_t write_size, loff_t *poffset)
976{ 1010{
@@ -981,6 +1015,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
981 struct cifsTconInfo *pTcon; 1015 struct cifsTconInfo *pTcon;
982 int xid, long_op; 1016 int xid, long_op;
983 struct cifsFileInfo *open_file; 1017 struct cifsFileInfo *open_file;
1018 struct cifsInodeInfo *cifsi = CIFS_I(file->f_path.dentry->d_inode);
984 1019
985 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 1020 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
986 1021
@@ -1000,11 +1035,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
1000 1035
1001 xid = GetXid(); 1036 xid = GetXid();
1002 1037
1003 if (*poffset > file->f_path.dentry->d_inode->i_size) 1038 long_op = cifs_write_timeout(cifsi, *poffset);
1004 long_op = CIFS_VLONG_OP; /* writes past EOF take long time */
1005 else
1006 long_op = CIFS_LONG_OP;
1007
1008 for (total_written = 0; write_size > total_written; 1039 for (total_written = 0; write_size > total_written;
1009 total_written += bytes_written) { 1040 total_written += bytes_written) {
1010 rc = -EAGAIN; 1041 rc = -EAGAIN;
@@ -1048,8 +1079,10 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
1048 FreeXid(xid); 1079 FreeXid(xid);
1049 return rc; 1080 return rc;
1050 } 1081 }
1051 } else 1082 } else {
1083 cifs_update_eof(cifsi, *poffset, bytes_written);
1052 *poffset += bytes_written; 1084 *poffset += bytes_written;
1085 }
1053 long_op = CIFS_STD_OP; /* subsequent writes fast - 1086 long_op = CIFS_STD_OP; /* subsequent writes fast -
1054 15 seconds is plenty */ 1087 15 seconds is plenty */
1055 } 1088 }
@@ -1085,6 +1118,7 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
1085 struct cifsTconInfo *pTcon; 1118 struct cifsTconInfo *pTcon;
1086 int xid, long_op; 1119 int xid, long_op;
1087 struct cifsFileInfo *open_file; 1120 struct cifsFileInfo *open_file;
1121 struct cifsInodeInfo *cifsi = CIFS_I(file->f_path.dentry->d_inode);
1088 1122
1089 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 1123 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
1090 1124
@@ -1099,11 +1133,7 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
1099 1133
1100 xid = GetXid(); 1134 xid = GetXid();
1101 1135
1102 if (*poffset > file->f_path.dentry->d_inode->i_size) 1136 long_op = cifs_write_timeout(cifsi, *poffset);
1103 long_op = CIFS_VLONG_OP; /* writes past EOF can be slow */
1104 else
1105 long_op = CIFS_LONG_OP;
1106
1107 for (total_written = 0; write_size > total_written; 1137 for (total_written = 0; write_size > total_written;
1108 total_written += bytes_written) { 1138 total_written += bytes_written) {
1109 rc = -EAGAIN; 1139 rc = -EAGAIN;
@@ -1166,8 +1196,10 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
1166 FreeXid(xid); 1196 FreeXid(xid);
1167 return rc; 1197 return rc;
1168 } 1198 }
1169 } else 1199 } else {
1200 cifs_update_eof(cifsi, *poffset, bytes_written);
1170 *poffset += bytes_written; 1201 *poffset += bytes_written;
1202 }
1171 long_op = CIFS_STD_OP; /* subsequent writes fast - 1203 long_op = CIFS_STD_OP; /* subsequent writes fast -
1172 15 seconds is plenty */ 1204 15 seconds is plenty */
1173 } 1205 }
@@ -1380,11 +1412,12 @@ static int cifs_writepages(struct address_space *mapping,
1380 int nr_pages; 1412 int nr_pages;
1381 __u64 offset = 0; 1413 __u64 offset = 0;
1382 struct cifsFileInfo *open_file; 1414 struct cifsFileInfo *open_file;
1415 struct cifsInodeInfo *cifsi = CIFS_I(mapping->host);
1383 struct page *page; 1416 struct page *page;
1384 struct pagevec pvec; 1417 struct pagevec pvec;
1385 int rc = 0; 1418 int rc = 0;
1386 int scanned = 0; 1419 int scanned = 0;
1387 int xid; 1420 int xid, long_op;
1388 1421
1389 cifs_sb = CIFS_SB(mapping->host->i_sb); 1422 cifs_sb = CIFS_SB(mapping->host->i_sb);
1390 1423
@@ -1528,12 +1561,15 @@ retry:
1528 cERROR(1, ("No writable handles for inode")); 1561 cERROR(1, ("No writable handles for inode"));
1529 rc = -EBADF; 1562 rc = -EBADF;
1530 } else { 1563 } else {
1564 long_op = cifs_write_timeout(cifsi, offset);
1531 rc = CIFSSMBWrite2(xid, cifs_sb->tcon, 1565 rc = CIFSSMBWrite2(xid, cifs_sb->tcon,
1532 open_file->netfid, 1566 open_file->netfid,
1533 bytes_to_write, offset, 1567 bytes_to_write, offset,
1534 &bytes_written, iov, n_iov, 1568 &bytes_written, iov, n_iov,
1535 CIFS_LONG_OP); 1569 long_op);
1536 atomic_dec(&open_file->wrtPending); 1570 atomic_dec(&open_file->wrtPending);
1571 cifs_update_eof(cifsi, offset, bytes_written);
1572
1537 if (rc || bytes_written < bytes_to_write) { 1573 if (rc || bytes_written < bytes_to_write) {
1538 cERROR(1, ("Write2 ret %d, wrote %d", 1574 cERROR(1, ("Write2 ret %d, wrote %d",
1539 rc, bytes_written)); 1575 rc, bytes_written));