cifs: vary timeout on writes past EOF based on offset (try #5)

This is the fourth version of this patch:

The first three generated a compiler warning asking for explicit curly
braces.

The first two didn't handle update the size correctly when writes that
didn't start at the eof were done.

The first patch also didn't update the size correctly when it explicitly
set via truncate().

This patch adds code to track the client's current understanding of the
size of the file on the server separate from the i_size, and then to use
this info to semi-intelligently set the timeout for writes past the EOF.

This helps prevent timeouts when trying to write large, sparse files on
windows servers.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>

authored by Jeff Layton and committed by Steve French fbec9ab9 d036f50f

+61 -19
+1
fs/cifs/cifsfs.c
··· 316 cifs_inode->clientCanCacheAll = false; 317 cifs_inode->delete_pending = false; 318 cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */ 319 320 /* Can not set i_flags here - they get immediately overwritten 321 to zero by the VFS */
··· 316 cifs_inode->clientCanCacheAll = false; 317 cifs_inode->delete_pending = false; 318 cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */ 319 + cifs_inode->server_eof = 0; 320 321 /* Can not set i_flags here - they get immediately overwritten 322 to zero by the VFS */
+1
fs/cifs/cifsglob.h
··· 370 bool clientCanCacheAll:1; /* read and writebehind oplock */ 371 bool oplockPending:1; 372 bool delete_pending:1; /* DELETE_ON_CLOSE is set */ 373 struct inode vfs_inode; 374 }; 375
··· 370 bool clientCanCacheAll:1; /* read and writebehind oplock */ 371 bool oplockPending:1; 372 bool delete_pending:1; /* DELETE_ON_CLOSE is set */ 373 + u64 server_eof; /* current file size on server */ 374 struct inode vfs_inode; 375 }; 376
+2 -2
fs/cifs/cifssmb.c
··· 1626 int smb_hdr_len; 1627 int resp_buf_type = 0; 1628 1629 cFYI(1, ("write2 at %lld %d bytes", (long long)offset, count)); 1630 1631 if (tcon->ses->capabilities & CAP_LARGE_FILES) { ··· 1684 cifs_stats_inc(&tcon->num_writes); 1685 if (rc) { 1686 cFYI(1, ("Send error Write2 = %d", rc)); 1687 - *nbytes = 0; 1688 } else if (resp_buf_type == 0) { 1689 /* presumably this can not happen, but best to be safe */ 1690 rc = -EIO; 1691 - *nbytes = 0; 1692 } else { 1693 WRITE_RSP *pSMBr = (WRITE_RSP *)iov[0].iov_base; 1694 *nbytes = le16_to_cpu(pSMBr->CountHigh);
··· 1626 int smb_hdr_len; 1627 int resp_buf_type = 0; 1628 1629 + *nbytes = 0; 1630 + 1631 cFYI(1, ("write2 at %lld %d bytes", (long long)offset, count)); 1632 1633 if (tcon->ses->capabilities & CAP_LARGE_FILES) { ··· 1682 cifs_stats_inc(&tcon->num_writes); 1683 if (rc) { 1684 cFYI(1, ("Send error Write2 = %d", rc)); 1685 } else if (resp_buf_type == 0) { 1686 /* presumably this can not happen, but best to be safe */ 1687 rc = -EIO; 1688 } else { 1689 WRITE_RSP *pSMBr = (WRITE_RSP *)iov[0].iov_base; 1690 *nbytes = le16_to_cpu(pSMBr->CountHigh);
+50 -14
fs/cifs/file.c
··· 971 return rc; 972 } 973 974 ssize_t cifs_user_write(struct file *file, const char __user *write_data, 975 size_t write_size, loff_t *poffset) 976 { ··· 1015 struct cifsTconInfo *pTcon; 1016 int xid, long_op; 1017 struct cifsFileInfo *open_file; 1018 1019 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 1020 ··· 1035 1036 xid = GetXid(); 1037 1038 - if (*poffset > file->f_path.dentry->d_inode->i_size) 1039 - long_op = CIFS_VLONG_OP; /* writes past EOF take long time */ 1040 - else 1041 - long_op = CIFS_LONG_OP; 1042 - 1043 for (total_written = 0; write_size > total_written; 1044 total_written += bytes_written) { 1045 rc = -EAGAIN; ··· 1079 FreeXid(xid); 1080 return rc; 1081 } 1082 - } else 1083 *poffset += bytes_written; 1084 long_op = CIFS_STD_OP; /* subsequent writes fast - 1085 15 seconds is plenty */ 1086 } ··· 1118 struct cifsTconInfo *pTcon; 1119 int xid, long_op; 1120 struct cifsFileInfo *open_file; 1121 1122 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 1123 ··· 1133 1134 xid = GetXid(); 1135 1136 - if (*poffset > file->f_path.dentry->d_inode->i_size) 1137 - long_op = CIFS_VLONG_OP; /* writes past EOF can be slow */ 1138 - else 1139 - long_op = CIFS_LONG_OP; 1140 - 1141 for (total_written = 0; write_size > total_written; 1142 total_written += bytes_written) { 1143 rc = -EAGAIN; ··· 1196 FreeXid(xid); 1197 return rc; 1198 } 1199 - } else 1200 *poffset += bytes_written; 1201 long_op = CIFS_STD_OP; /* subsequent writes fast - 1202 15 seconds is plenty */ 1203 } ··· 1412 int nr_pages; 1413 __u64 offset = 0; 1414 struct cifsFileInfo *open_file; 1415 struct page *page; 1416 struct pagevec pvec; 1417 int rc = 0; 1418 int scanned = 0; 1419 - int xid; 1420 1421 cifs_sb = CIFS_SB(mapping->host->i_sb); 1422 ··· 1561 cERROR(1, ("No writable handles for inode")); 1562 rc = -EBADF; 1563 } else { 1564 rc = CIFSSMBWrite2(xid, cifs_sb->tcon, 1565 open_file->netfid, 1566 bytes_to_write, offset, 1567 &bytes_written, iov, n_iov, 1568 - CIFS_LONG_OP); 1569 atomic_dec(&open_file->wrtPending); 1570 if (rc || bytes_written < bytes_to_write) { 1571 cERROR(1, ("Write2 ret %d, wrote %d", 1572 rc, bytes_written));
··· 971 return rc; 972 } 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 + */ 986 + static int 987 + cifs_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 */ 998 + static void 999 + cifs_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 + 1008 ssize_t cifs_user_write(struct file *file, const char __user *write_data, 1009 size_t write_size, loff_t *poffset) 1010 { ··· 981 struct cifsTconInfo *pTcon; 982 int xid, long_op; 983 struct cifsFileInfo *open_file; 984 + struct cifsInodeInfo *cifsi = CIFS_I(file->f_path.dentry->d_inode); 985 986 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 987 ··· 1000 1001 xid = GetXid(); 1002 1003 + long_op = cifs_write_timeout(cifsi, *poffset); 1004 for (total_written = 0; write_size > total_written; 1005 total_written += bytes_written) { 1006 rc = -EAGAIN; ··· 1048 FreeXid(xid); 1049 return rc; 1050 } 1051 + } else { 1052 + cifs_update_eof(cifsi, *poffset, bytes_written); 1053 *poffset += bytes_written; 1054 + } 1055 long_op = CIFS_STD_OP; /* subsequent writes fast - 1056 15 seconds is plenty */ 1057 } ··· 1085 struct cifsTconInfo *pTcon; 1086 int xid, long_op; 1087 struct cifsFileInfo *open_file; 1088 + struct cifsInodeInfo *cifsi = CIFS_I(file->f_path.dentry->d_inode); 1089 1090 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 1091 ··· 1099 1100 xid = GetXid(); 1101 1102 + long_op = cifs_write_timeout(cifsi, *poffset); 1103 for (total_written = 0; write_size > total_written; 1104 total_written += bytes_written) { 1105 rc = -EAGAIN; ··· 1166 FreeXid(xid); 1167 return rc; 1168 } 1169 + } else { 1170 + cifs_update_eof(cifsi, *poffset, bytes_written); 1171 *poffset += bytes_written; 1172 + } 1173 long_op = CIFS_STD_OP; /* subsequent writes fast - 1174 15 seconds is plenty */ 1175 } ··· 1380 int nr_pages; 1381 __u64 offset = 0; 1382 struct cifsFileInfo *open_file; 1383 + struct cifsInodeInfo *cifsi = CIFS_I(mapping->host); 1384 struct page *page; 1385 struct pagevec pvec; 1386 int rc = 0; 1387 int scanned = 0; 1388 + int xid, long_op; 1389 1390 cifs_sb = CIFS_SB(mapping->host->i_sb); 1391 ··· 1528 cERROR(1, ("No writable handles for inode")); 1529 rc = -EBADF; 1530 } else { 1531 + long_op = cifs_write_timeout(cifsi, offset); 1532 rc = CIFSSMBWrite2(xid, cifs_sb->tcon, 1533 open_file->netfid, 1534 bytes_to_write, offset, 1535 &bytes_written, iov, n_iov, 1536 + long_op); 1537 atomic_dec(&open_file->wrtPending); 1538 + cifs_update_eof(cifsi, offset, bytes_written); 1539 + 1540 if (rc || bytes_written < bytes_to_write) { 1541 cERROR(1, ("Write2 ret %d, wrote %d", 1542 rc, bytes_written));
+5 -3
fs/cifs/inode.c
··· 143 144 inode->i_nlink = le64_to_cpu(info->Nlinks); 145 146 spin_lock(&inode->i_lock); 147 if (is_size_safe_to_change(cifsInfo, end_of_file)) { 148 /* ··· 607 inode->i_mode |= S_IFREG; 608 } 609 610 spin_lock(&inode->i_lock); 611 - if (is_size_safe_to_change(cifsInfo, 612 - le64_to_cpu(pfindData->EndOfFile))) { 613 /* can not safely shrink the file size here if the 614 client is writing to it due to potential races */ 615 - i_size_write(inode, le64_to_cpu(pfindData->EndOfFile)); 616 617 /* 512 bytes (2**9) is the fake blocksize that must be 618 used for this calculation */ ··· 1756 } 1757 1758 if (rc == 0) { 1759 rc = cifs_vmtruncate(inode, attrs->ia_size); 1760 cifs_truncate_page(inode->i_mapping, inode->i_size); 1761 }
··· 143 144 inode->i_nlink = le64_to_cpu(info->Nlinks); 145 146 + cifsInfo->server_eof = end_of_file; 147 spin_lock(&inode->i_lock); 148 if (is_size_safe_to_change(cifsInfo, end_of_file)) { 149 /* ··· 606 inode->i_mode |= S_IFREG; 607 } 608 609 + cifsInfo->server_eof = le64_to_cpu(pfindData->EndOfFile); 610 spin_lock(&inode->i_lock); 611 + if (is_size_safe_to_change(cifsInfo, cifsInfo->server_eof)) { 612 /* can not safely shrink the file size here if the 613 client is writing to it due to potential races */ 614 + i_size_write(inode, cifsInfo->server_eof); 615 616 /* 512 bytes (2**9) is the fake blocksize that must be 617 used for this calculation */ ··· 1755 } 1756 1757 if (rc == 0) { 1758 + cifsInode->server_eof = attrs->ia_size; 1759 rc = cifs_vmtruncate(inode, attrs->ia_size); 1760 cifs_truncate_page(inode->i_mapping, inode->i_size); 1761 }
+2
fs/cifs/readdir.c
··· 239 if (atomic_read(&cifsInfo->inUse) == 0) 240 atomic_set(&cifsInfo->inUse, 1); 241 242 spin_lock(&tmp_inode->i_lock); 243 if (is_size_safe_to_change(cifsInfo, end_of_file)) { 244 /* can not safely change the file size here if the ··· 376 tmp_inode->i_gid = le64_to_cpu(pfindData->Gid); 377 tmp_inode->i_nlink = le64_to_cpu(pfindData->Nlinks); 378 379 spin_lock(&tmp_inode->i_lock); 380 if (is_size_safe_to_change(cifsInfo, end_of_file)) { 381 /* can not safely change the file size here if the
··· 239 if (atomic_read(&cifsInfo->inUse) == 0) 240 atomic_set(&cifsInfo->inUse, 1); 241 242 + cifsInfo->server_eof = end_of_file; 243 spin_lock(&tmp_inode->i_lock); 244 if (is_size_safe_to_change(cifsInfo, end_of_file)) { 245 /* can not safely change the file size here if the ··· 375 tmp_inode->i_gid = le64_to_cpu(pfindData->Gid); 376 tmp_inode->i_nlink = le64_to_cpu(pfindData->Nlinks); 377 378 + cifsInfo->server_eof = end_of_file; 379 spin_lock(&tmp_inode->i_lock); 380 if (is_size_safe_to_change(cifsInfo, end_of_file)) { 381 /* can not safely change the file size here if the