diff options
author | Jeff Layton <jlayton@redhat.com> | 2009-04-03 13:44:00 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2009-04-16 21:26:49 -0400 |
commit | fbec9ab952d4810960e620035c8e95f0fbbae4be (patch) | |
tree | e4d8ef8e0fbe2703d98390d96151cbf40d32f434 /fs/cifs/inode.c | |
parent | d036f50fc202e1a851a25dc5edc215ebd0086201 (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.c | 8 |
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 | } |