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.c105
1 files changed, 63 insertions, 42 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index a1265c9bfec0..2d3275bedb55 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -879,18 +879,19 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
879 cifs_stats_bytes_written(pTcon, total_written); 879 cifs_stats_bytes_written(pTcon, total_written);
880 880
881 /* since the write may have blocked check these pointers again */ 881 /* since the write may have blocked check these pointers again */
882 if (file->f_path.dentry) { 882 if ((file->f_path.dentry) && (file->f_path.dentry->d_inode)) {
883 if (file->f_path.dentry->d_inode) { 883 struct inode *inode = file->f_path.dentry->d_inode;
884 struct inode *inode = file->f_path.dentry->d_inode; 884/* Do not update local mtime - server will set its actual value on write
885 inode->i_ctime = inode->i_mtime = 885 * inode->i_ctime = inode->i_mtime =
886 current_fs_time(inode->i_sb); 886 * current_fs_time(inode->i_sb);*/
887 if (total_written > 0) { 887 if (total_written > 0) {
888 if (*poffset > file->f_path.dentry->d_inode->i_size) 888 spin_lock(&inode->i_lock);
889 i_size_write(file->f_path.dentry->d_inode, 889 if (*poffset > file->f_path.dentry->d_inode->i_size)
890 i_size_write(file->f_path.dentry->d_inode,
890 *poffset); 891 *poffset);
891 } 892 spin_unlock(&inode->i_lock);
892 mark_inode_dirty_sync(file->f_path.dentry->d_inode);
893 } 893 }
894 mark_inode_dirty_sync(file->f_path.dentry->d_inode);
894 } 895 }
895 FreeXid(xid); 896 FreeXid(xid);
896 return total_written; 897 return total_written;
@@ -1012,18 +1013,18 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
1012 cifs_stats_bytes_written(pTcon, total_written); 1013 cifs_stats_bytes_written(pTcon, total_written);
1013 1014
1014 /* since the write may have blocked check these pointers again */ 1015 /* since the write may have blocked check these pointers again */
1015 if (file->f_path.dentry) { 1016 if ((file->f_path.dentry) && (file->f_path.dentry->d_inode)) {
1016 if (file->f_path.dentry->d_inode) {
1017/*BB We could make this contingent on superblock ATIME flag too */ 1017/*BB We could make this contingent on superblock ATIME flag too */
1018/* file->f_path.dentry->d_inode->i_ctime = 1018/* file->f_path.dentry->d_inode->i_ctime =
1019 file->f_path.dentry->d_inode->i_mtime = CURRENT_TIME;*/ 1019 file->f_path.dentry->d_inode->i_mtime = CURRENT_TIME;*/
1020 if (total_written > 0) { 1020 if (total_written > 0) {
1021 if (*poffset > file->f_path.dentry->d_inode->i_size) 1021 spin_lock(&file->f_path.dentry->d_inode->i_lock);
1022 i_size_write(file->f_path.dentry->d_inode, 1022 if (*poffset > file->f_path.dentry->d_inode->i_size)
1023 *poffset); 1023 i_size_write(file->f_path.dentry->d_inode,
1024 } 1024 *poffset);
1025 mark_inode_dirty_sync(file->f_path.dentry->d_inode); 1025 spin_unlock(&file->f_path.dentry->d_inode->i_lock);
1026 } 1026 }
1027 mark_inode_dirty_sync(file->f_path.dentry->d_inode);
1027 } 1028 }
1028 FreeXid(xid); 1029 FreeXid(xid);
1029 return total_written; 1030 return total_written;
@@ -1400,6 +1401,7 @@ static int cifs_commit_write(struct file *file, struct page *page,
1400 xid = GetXid(); 1401 xid = GetXid();
1401 cFYI(1, ("commit write for page %p up to position %lld for %d", 1402 cFYI(1, ("commit write for page %p up to position %lld for %d",
1402 page, position, to)); 1403 page, position, to));
1404 spin_lock(&inode->i_lock);
1403 if (position > inode->i_size) { 1405 if (position > inode->i_size) {
1404 i_size_write(inode, position); 1406 i_size_write(inode, position);
1405 /* if (file->private_data == NULL) { 1407 /* if (file->private_data == NULL) {
@@ -1429,6 +1431,7 @@ static int cifs_commit_write(struct file *file, struct page *page,
1429 cFYI(1, (" SetEOF (commit write) rc = %d", rc)); 1431 cFYI(1, (" SetEOF (commit write) rc = %d", rc));
1430 } */ 1432 } */
1431 } 1433 }
1434 spin_unlock(&inode->i_lock);
1432 if (!PageUptodate(page)) { 1435 if (!PageUptodate(page)) {
1433 position = ((loff_t)page->index << PAGE_CACHE_SHIFT) + offset; 1436 position = ((loff_t)page->index << PAGE_CACHE_SHIFT) + offset;
1434 /* can not rely on (or let) writepage write this data */ 1437 /* can not rely on (or let) writepage write this data */
@@ -1989,34 +1992,52 @@ static int cifs_prepare_write(struct file *file, struct page *page,
1989 unsigned from, unsigned to) 1992 unsigned from, unsigned to)
1990{ 1993{
1991 int rc = 0; 1994 int rc = 0;
1992 loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT; 1995 loff_t i_size;
1996 loff_t offset;
1997
1993 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));
1994 if (!PageUptodate(page)) { 1999 if (PageUptodate(page))
1995 /* if (to - from != PAGE_CACHE_SIZE) { 2000 return 0;
1996 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)
1997 memset(kaddr, 0, from); 2021 memset(kaddr, 0, from);
2022 if (to < PAGE_CACHE_SIZE)
1998 memset(kaddr + to, 0, PAGE_CACHE_SIZE - to); 2023 memset(kaddr + to, 0, PAGE_CACHE_SIZE - to);
1999 flush_dcache_page(page); 2024 flush_dcache_page(page);
2000 kunmap_atomic(kaddr, KM_USER0); 2025 kunmap_atomic(kaddr, KM_USER0);
2001 } */ 2026 SetPageUptodate(page);
2002 /* If we are writing a full page it will be up to date, 2027 } else if ((file->f_flags & O_ACCMODE) != O_WRONLY) {
2003 no need to read from the server */
2004 if ((to == PAGE_CACHE_SIZE) && (from == 0))
2005 SetPageUptodate(page);
2006
2007 /* might as well read a page, it is fast enough */ 2028 /* might as well read a page, it is fast enough */
2008 if ((file->f_flags & O_ACCMODE) != O_WRONLY) { 2029 rc = cifs_readpage_worker(file, page, &offset);
2009 rc = cifs_readpage_worker(file, page, &offset); 2030 } else {
2010 } else { 2031 /* we could try using another file handle if there is one -
2011 /* should we try using another file handle if there is one - 2032 but how would we lock it to prevent close of that handle
2012 how would we lock it to prevent close of that handle 2033 racing with this read? In any case
2013 racing with this read? 2034 this will be written out by commit_write so is fine */
2014 In any case this will be written out by commit_write */
2015 }
2016 } 2035 }
2017 2036
2018 /* BB should we pass any errors back? 2037 /* we do not need to pass errors back
2019 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
2020 return 0; 2041 return 0;
2021} 2042}
2022 2043