summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/smb/client/cifsfs.c22
-rw-r--r--fs/smb/client/inode.c1
-rw-r--r--fs/smb/client/smb2ops.c18
3 files changed, 26 insertions, 15 deletions
diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c
index 1775c2b7528f..05b1fa76e8cc 100644
--- a/fs/smb/client/cifsfs.c
+++ b/fs/smb/client/cifsfs.c
@@ -392,11 +392,27 @@ static long cifs_fallocate(struct file *file, int mode, loff_t off, loff_t len)
struct cifs_sb_info *cifs_sb = CIFS_FILE_SB(file);
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
struct TCP_Server_Info *server = tcon->ses->server;
+ struct inode *inode = file_inode(file);
+ int rc;
+
+ if (!server->ops->fallocate)
+ return -EOPNOTSUPP;
+
+ rc = inode_lock_killable(inode);
+ if (rc)
+ return rc;
+
+ netfs_wait_for_outstanding_io(inode);
- if (server->ops->fallocate)
- return server->ops->fallocate(file, tcon, mode, off, len);
+ rc = file_modified(file);
+ if (rc)
+ goto out_unlock;
+
+ rc = server->ops->fallocate(file, tcon, mode, off, len);
- return -EOPNOTSUPP;
+out_unlock:
+ inode_unlock(inode);
+ return rc;
}
static int cifs_permission(struct mnt_idmap *idmap,
diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c
index fbfd5b556815..239dd84a336f 100644
--- a/fs/smb/client/inode.c
+++ b/fs/smb/client/inode.c
@@ -3012,6 +3012,7 @@ void cifs_setsize(struct inode *inode, loff_t offset)
spin_unlock(&inode->i_lock);
inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode));
truncate_pagecache(inode, offset);
+ netfs_wait_for_outstanding_io(inode);
}
int cifs_file_set_size(const unsigned int xid, struct dentry *dentry,
diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
index 83d9cde8a718..7c392cf5940b 100644
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -3367,7 +3367,6 @@ static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon,
trace_smb3_zero_enter(xid, cfile->fid.persistent_fid, tcon->tid,
ses->Suid, offset, len);
- inode_lock(inode);
filemap_invalidate_lock(inode->i_mapping);
i_size = i_size_read(inode);
@@ -3385,6 +3384,7 @@ static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon,
* first, otherwise the data may be inconsistent with the server.
*/
truncate_pagecache_range(inode, offset, offset + len - 1);
+ netfs_wait_for_outstanding_io(inode);
/* if file not oplocked can't be sure whether asking to extend size */
rc = -EOPNOTSUPP;
@@ -3413,7 +3413,6 @@ static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon,
zero_range_exit:
filemap_invalidate_unlock(inode->i_mapping);
- inode_unlock(inode);
free_xid(xid);
if (rc)
trace_smb3_zero_err(xid, cfile->fid.persistent_fid, tcon->tid,
@@ -3437,7 +3436,6 @@ static long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon,
xid = get_xid();
- inode_lock(inode);
/* Need to make file sparse, if not already, before freeing range. */
/* Consider adding equivalent for compressed since it could also work */
if (!smb2_set_sparse(xid, tcon, cfile, inode, set_sparse)) {
@@ -3451,6 +3449,7 @@ static long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon,
* caches first, otherwise the data may be inconsistent with the server.
*/
truncate_pagecache_range(inode, offset, offset + len - 1);
+ netfs_wait_for_outstanding_io(inode);
cifs_dbg(FYI, "Offset %lld len %lld\n", offset, len);
@@ -3485,7 +3484,6 @@ static long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon,
unlock:
filemap_invalidate_unlock(inode->i_mapping);
out:
- inode_unlock(inode);
free_xid(xid);
return rc;
}
@@ -3749,8 +3747,6 @@ static long smb3_collapse_range(struct file *file, struct cifs_tcon *tcon,
xid = get_xid();
- inode_lock(inode);
-
old_eof = i_size_read(inode);
if ((off >= old_eof) ||
off + len >= old_eof) {
@@ -3765,6 +3761,7 @@ static long smb3_collapse_range(struct file *file, struct cifs_tcon *tcon,
truncate_pagecache_range(inode, off, old_eof);
ictx->zero_point = old_eof;
+ netfs_wait_for_outstanding_io(inode);
rc = smb2_copychunk_range(xid, cfile, cfile, off + len,
old_eof - off - len, off);
@@ -3785,8 +3782,7 @@ static long smb3_collapse_range(struct file *file, struct cifs_tcon *tcon,
fscache_resize_cookie(cifs_inode_cookie(inode), new_eof);
out_2:
filemap_invalidate_unlock(inode->i_mapping);
- out:
- inode_unlock(inode);
+out:
free_xid(xid);
return rc;
}
@@ -3803,8 +3799,6 @@ static long smb3_insert_range(struct file *file, struct cifs_tcon *tcon,
xid = get_xid();
- inode_lock(inode);
-
old_eof = i_size_read(inode);
if (off >= old_eof) {
rc = -EINVAL;
@@ -3819,6 +3813,7 @@ static long smb3_insert_range(struct file *file, struct cifs_tcon *tcon,
if (rc < 0)
goto out_2;
truncate_pagecache_range(inode, off, old_eof);
+ netfs_wait_for_outstanding_io(inode);
rc = SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid,
cfile->fid.volatile_fid, cfile->pid, new_eof);
@@ -3841,8 +3836,7 @@ static long smb3_insert_range(struct file *file, struct cifs_tcon *tcon,
rc = 0;
out_2:
filemap_invalidate_unlock(inode->i_mapping);
- out:
- inode_unlock(inode);
+out:
free_xid(xid);
return rc;
}