summaryrefslogtreecommitdiffstats
path: root/fs/cifs/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r--fs/cifs/file.c44
1 files changed, 28 insertions, 16 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 68ad4ca0cfa3..dd26e2759b17 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -130,7 +130,9 @@ static inline int cifs_open_inode_helper(struct inode *inode, struct file *file,
if (file->f_path.dentry->d_inode->i_mapping) {
/* BB no need to lock inode until after invalidate
since namei code should already have it locked? */
- filemap_write_and_wait(file->f_path.dentry->d_inode->i_mapping);
+ rc = filemap_write_and_wait(file->f_path.dentry->d_inode->i_mapping);
+ if (rc != 0)
+ CIFS_I(file->f_path.dentry->d_inode)->write_behind_rc = rc;
}
cFYI(1, ("invalidating remote inode since open detected it "
"changed"));
@@ -425,7 +427,9 @@ reopen_error_exit:
pCifsInode = CIFS_I(inode);
if (pCifsInode) {
if (can_flush) {
- filemap_write_and_wait(inode->i_mapping);
+ rc = filemap_write_and_wait(inode->i_mapping);
+ if (rc != 0)
+ CIFS_I(inode)->write_behind_rc = rc;
/* temporarily disable caching while we
go to server to get inode info */
pCifsInode->clientCanCacheAll = FALSE;
@@ -835,9 +839,9 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
xid = GetXid();
if (*poffset > file->f_path.dentry->d_inode->i_size)
- long_op = 2; /* writes past end of file can take a long time */
+ long_op = CIFS_VLONG_OP; /* writes past EOF take long time */
else
- long_op = 1;
+ long_op = CIFS_LONG_OP;
for (total_written = 0; write_size > total_written;
total_written += bytes_written) {
@@ -884,7 +888,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
}
} else
*poffset += bytes_written;
- long_op = FALSE; /* subsequent writes fast -
+ long_op = CIFS_STD_OP; /* subsequent writes fast -
15 seconds is plenty */
}
@@ -934,9 +938,9 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
xid = GetXid();
if (*poffset > file->f_path.dentry->d_inode->i_size)
- long_op = 2; /* writes past end of file can take a long time */
+ long_op = CIFS_VLONG_OP; /* writes past EOF can be slow */
else
- long_op = 1;
+ long_op = CIFS_LONG_OP;
for (total_written = 0; write_size > total_written;
total_written += bytes_written) {
@@ -1002,7 +1006,7 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
}
} else
*poffset += bytes_written;
- long_op = FALSE; /* subsequent writes fast -
+ long_op = CIFS_STD_OP; /* subsequent writes fast -
15 seconds is plenty */
}
@@ -1087,11 +1091,11 @@ refind_writable:
read_unlock(&GlobalSMBSeslock);
return open_file;
}
-
+
read_unlock(&GlobalSMBSeslock);
/* Had to unlock since following call can block */
rc = cifs_reopen_file(open_file->pfile, FALSE);
- if (!rc) {
+ if (!rc) {
if (!open_file->closePend)
return open_file;
else { /* start over in case this was deleted */
@@ -1114,7 +1118,7 @@ refind_writable:
/* can not use this handle, no write
pending on this one after all */
atomic_dec(&open_file->wrtPending);
-
+
if (open_file->closePend) /* list could have changed */
goto refind_writable;
/* else we simply continue to the next entry. Thus
@@ -1360,14 +1364,17 @@ retry:
open_file->netfid,
bytes_to_write, offset,
&bytes_written, iov, n_iov,
- 1);
+ CIFS_LONG_OP);
atomic_dec(&open_file->wrtPending);
if (rc || bytes_written < bytes_to_write) {
cERROR(1, ("Write2 ret %d, wrote %d",
rc, bytes_written));
/* BB what if continued retry is
requested via mount flags? */
- set_bit(AS_EIO, &mapping->flags);
+ if (rc == -ENOSPC)
+ set_bit(AS_ENOSPC, &mapping->flags);
+ else
+ set_bit(AS_EIO, &mapping->flags);
} else {
cifs_stats_bytes_written(cifs_sb->tcon,
bytes_written);
@@ -1499,9 +1506,11 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync)
cFYI(1, ("Sync file - name: %s datasync: 0x%x",
dentry->d_name.name, datasync));
- rc = filemap_fdatawrite(inode->i_mapping);
- if (rc == 0)
+ rc = filemap_write_and_wait(inode->i_mapping);
+ if (rc == 0) {
+ rc = CIFS_I(inode)->write_behind_rc;
CIFS_I(inode)->write_behind_rc = 0;
+ }
FreeXid(xid);
return rc;
}
@@ -1553,8 +1562,11 @@ int cifs_flush(struct file *file, fl_owner_t id)
filemapfdatawrite appears easier for the time being */
rc = filemap_fdatawrite(inode->i_mapping);
- if (!rc) /* reset wb rc if we were able to write out dirty pages */
+ /* reset wb rc if we were able to write out dirty pages */
+ if (!rc) {
+ rc = CIFS_I(inode)->write_behind_rc;
CIFS_I(inode)->write_behind_rc = 0;
+ }
cFYI(1, ("Flush inode %p file %p rc %d", inode, file, rc));
OpenPOWER on IntegriCloud