aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/inode.c
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2009-04-03 13:44:00 -0400
committerSteve French <sfrench@us.ibm.com>2009-04-16 21:26:49 -0400
commitfbec9ab952d4810960e620035c8e95f0fbbae4be (patch)
treee4d8ef8e0fbe2703d98390d96151cbf40d32f434 /fs/cifs/inode.c
parentd036f50fc202e1a851a25dc5edc215ebd0086201 (diff)
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>
Diffstat (limited to 'fs/cifs/inode.c')
-rw-r--r--fs/cifs/inode.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index fceebee39f27..09082ac85185 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -143,6 +143,7 @@ static void cifs_unix_info_to_inode(struct inode *inode,
143 143
144 inode->i_nlink = le64_to_cpu(info->Nlinks); 144 inode->i_nlink = le64_to_cpu(info->Nlinks);
145 145
146 cifsInfo->server_eof = end_of_file;
146 spin_lock(&inode->i_lock); 147 spin_lock(&inode->i_lock);
147 if (is_size_safe_to_change(cifsInfo, end_of_file)) { 148 if (is_size_safe_to_change(cifsInfo, end_of_file)) {
148 /* 149 /*
@@ -606,12 +607,12 @@ int cifs_get_inode_info(struct inode **pinode,
606 inode->i_mode |= S_IFREG; 607 inode->i_mode |= S_IFREG;
607 } 608 }
608 609
610 cifsInfo->server_eof = le64_to_cpu(pfindData->EndOfFile);
609 spin_lock(&inode->i_lock); 611 spin_lock(&inode->i_lock);
610 if (is_size_safe_to_change(cifsInfo, 612 if (is_size_safe_to_change(cifsInfo, cifsInfo->server_eof)) {
611 le64_to_cpu(pfindData->EndOfFile))) {
612 /* can not safely shrink the file size here if the 613 /* can not safely shrink the file size here if the
613 client is writing to it due to potential races */ 614 client is writing to it due to potential races */
614 i_size_write(inode, le64_to_cpu(pfindData->EndOfFile)); 615 i_size_write(inode, cifsInfo->server_eof);
615 616
616 /* 512 bytes (2**9) is the fake blocksize that must be 617 /* 512 bytes (2**9) is the fake blocksize that must be
617 used for this calculation */ 618 used for this calculation */
@@ -1755,6 +1756,7 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
1755 } 1756 }
1756 1757
1757 if (rc == 0) { 1758 if (rc == 0) {
1759 cifsInode->server_eof = attrs->ia_size;
1758 rc = cifs_vmtruncate(inode, attrs->ia_size); 1760 rc = cifs_vmtruncate(inode, attrs->ia_size);
1759 cifs_truncate_page(inode->i_mapping, inode->i_size); 1761 cifs_truncate_page(inode->i_mapping, inode->i_size);
1760 } 1762 }