aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2007-03-05 19:31:00 -0500
committerSteve French <sfrench@us.ibm.com>2007-03-05 19:31:00 -0500
commit8a236264f7d6db3f52881d37a86c5a5f704072b0 (patch)
tree2caf0cb67d6986b8e3544405b89135f24c05c137
parentc7af1857ef74873bf5a9c8fcab0cfd79883492ac (diff)
[CIFS] cifs_prepare_write was incorrectly rereading page in some cases
Noticed by Shaggy. Signed-off-by: Shaggy <shaggy@us.ibm.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
-rw-r--r--fs/cifs/CHANGES5
-rw-r--r--fs/cifs/file.c62
-rw-r--r--fs/cifs/transport.c6
3 files changed, 45 insertions, 28 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index e08a147c09e1..6247628bdaed 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -2,8 +2,9 @@ Verison 1.48
2------------ 2------------
3Fix mtime bouncing around from local idea of last write times to remote time. 3Fix mtime bouncing around from local idea of last write times to remote time.
4Fix hang (in i_size_read) when simultaneous size update of same remote file 4Fix hang (in i_size_read) when simultaneous size update of same remote file
5on smp system corrupts sequence number. 5on smp system corrupts sequence number. Do not reread unnecessarily partial page
6 6(which we are about to overwrite anyway) when writing out file opened rw.
7
7Version 1.47 8Version 1.47
8------------ 9------------
9Fix oops in list_del during mount caused by unaligned string. 10Fix oops in list_del during mount caused by unaligned string.
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index c07ff8317a8b..2d3275bedb55 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -1992,34 +1992,52 @@ static int cifs_prepare_write(struct file *file, struct page *page,
1992 unsigned from, unsigned to) 1992 unsigned from, unsigned to)
1993{ 1993{
1994 int rc = 0; 1994 int rc = 0;
1995 loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT; 1995 loff_t i_size;
1996 loff_t offset;
1997
1996 cFYI(1, ("prepare write for page %p from %d to %d",page,from,to)); 1998 cFYI(1, ("prepare write for page %p from %d to %d",page,from,to));
1997 if (!PageUptodate(page)) { 1999 if (PageUptodate(page))
1998 /* if (to - from != PAGE_CACHE_SIZE) { 2000 return 0;
1999 void *kaddr = kmap_atomic(page, KM_USER0); 2001
2002 /* If we are writing a full page it will be up to date,
2003 no need to read from the server */
2004 if ((to == PAGE_CACHE_SIZE) && (from == 0)) {
2005 SetPageUptodate(page);
2006 return 0;
2007 }
2008
2009 offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
2010 i_size = i_size_read(page->mapping->host);
2011
2012 if ((offset >= i_size) ||
2013 ((from == 0) && (offset + to) >= i_size)) {
2014 /*
2015 * We don't need to read data beyond the end of the file.
2016 * zero it, and set the page uptodate
2017 */
2018 void *kaddr = kmap_atomic(page, KM_USER0);
2019
2020 if (from)
2000 memset(kaddr, 0, from); 2021 memset(kaddr, 0, from);
2022 if (to < PAGE_CACHE_SIZE)
2001 memset(kaddr + to, 0, PAGE_CACHE_SIZE - to); 2023 memset(kaddr + to, 0, PAGE_CACHE_SIZE - to);
2002 flush_dcache_page(page); 2024 flush_dcache_page(page);
2003 kunmap_atomic(kaddr, KM_USER0); 2025 kunmap_atomic(kaddr, KM_USER0);
2004 } */ 2026 SetPageUptodate(page);
2005 /* If we are writing a full page it will be up to date, 2027 } else if ((file->f_flags & O_ACCMODE) != O_WRONLY) {
2006 no need to read from the server */
2007 if ((to == PAGE_CACHE_SIZE) && (from == 0))
2008 SetPageUptodate(page);
2009
2010 /* might as well read a page, it is fast enough */ 2028 /* might as well read a page, it is fast enough */
2011 if ((file->f_flags & O_ACCMODE) != O_WRONLY) { 2029 rc = cifs_readpage_worker(file, page, &offset);
2012 rc = cifs_readpage_worker(file, page, &offset); 2030 } else {
2013 } else { 2031 /* we could try using another file handle if there is one -
2014 /* should we try using another file handle if there is one - 2032 but how would we lock it to prevent close of that handle
2015 how would we lock it to prevent close of that handle 2033 racing with this read? In any case
2016 racing with this read? 2034 this will be written out by commit_write so is fine */
2017 In any case this will be written out by commit_write */
2018 }
2019 } 2035 }
2020 2036
2021 /* BB should we pass any errors back? 2037 /* we do not need to pass errors back
2022 e.g. if we do not have read access to the file */ 2038 e.g. if we do not have read access to the file
2039 because cifs_commit_write will do the right thing. -- shaggy */
2040
2023 return 0; 2041 return 0;
2024} 2042}
2025 2043
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index f80007eaebf4..5f468459a1e2 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -499,7 +499,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
499 due to last connection to this server being unmounted */ 499 due to last connection to this server being unmounted */
500 if (signal_pending(current)) { 500 if (signal_pending(current)) {
501 /* if signal pending do not hold up user for full smb timeout 501 /* if signal pending do not hold up user for full smb timeout
502 but we still give response a change to complete */ 502 but we still give response a chance to complete */
503 timeout = 2 * HZ; 503 timeout = 2 * HZ;
504 } 504 }
505 505
@@ -587,7 +587,6 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
587 } 587 }
588 588
589out: 589out:
590
591 DeleteMidQEntry(midQ); 590 DeleteMidQEntry(midQ);
592 atomic_dec(&ses->server->inFlight); 591 atomic_dec(&ses->server->inFlight);
593 wake_up(&ses->server->request_q); 592 wake_up(&ses->server->request_q);
@@ -681,7 +680,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
681 due to last connection to this server being unmounted */ 680 due to last connection to this server being unmounted */
682 if (signal_pending(current)) { 681 if (signal_pending(current)) {
683 /* if signal pending do not hold up user for full smb timeout 682 /* if signal pending do not hold up user for full smb timeout
684 but we still give response a change to complete */ 683 but we still give response a chance to complete */
685 timeout = 2 * HZ; 684 timeout = 2 * HZ;
686 } 685 }
687 686
@@ -765,7 +764,6 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
765 } 764 }
766 765
767out: 766out:
768
769 DeleteMidQEntry(midQ); 767 DeleteMidQEntry(midQ);
770 atomic_dec(&ses->server->inFlight); 768 atomic_dec(&ses->server->inFlight);
771 wake_up(&ses->server->request_q); 769 wake_up(&ses->server->request_q);