summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/smb/client/cifsfs.h1
-rw-r--r--fs/smb/client/inode.c24
-rw-r--r--fs/smb/client/smb2ops.c9
3 files changed, 23 insertions, 11 deletions
diff --git a/fs/smb/client/cifsfs.h b/fs/smb/client/cifsfs.h
index 854e672a4e37..651670c19c2b 100644
--- a/fs/smb/client/cifsfs.h
+++ b/fs/smb/client/cifsfs.h
@@ -147,6 +147,7 @@ ssize_t cifs_file_copychunk_range(unsigned int xid, struct file *src_file,
long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg);
void cifs_setsize(struct inode *inode, loff_t offset);
+void cifs_resize_file_locked(struct inode *inode, loff_t offset);
struct fs_context;
struct smb3_fs_context;
diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c
index 5f58fb46363d..098d5496e779 100644
--- a/fs/smb/client/inode.c
+++ b/fs/smb/client/inode.c
@@ -3059,7 +3059,23 @@ void cifs_setsize(struct inode *inode, loff_t offset)
inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode));
truncate_pagecache(inode, offset);
netfs_wait_for_outstanding_io(inode);
- fscache_resize_cookie(cifs_inode_cookie(inode), offset);
+}
+
+void cifs_resize_file_locked(struct inode *inode, loff_t offset)
+{
+ struct fscache_cookie *cookie = cifs_inode_cookie(inode);
+
+ lockdep_assert_held_write(&inode->i_rwsem);
+
+ netfs_resize_file(netfs_inode(inode), offset, true);
+ cifs_setsize(inode, offset);
+
+ if (!cookie)
+ return;
+
+ fscache_use_cookie(cookie, true);
+ fscache_resize_cookie(cookie, offset);
+ cifs_fscache_unuse_inode_cookie(inode, true);
}
int cifs_file_set_size(const unsigned int xid, struct dentry *dentry,
@@ -3125,10 +3141,8 @@ int cifs_file_set_size(const unsigned int xid, struct dentry *dentry,
cifs_put_tlink(tlink);
set_size_out:
- if (rc == 0) {
- netfs_resize_file(&cifsInode->netfs, size, true);
- cifs_setsize(inode, size);
- }
+ if (rc == 0)
+ cifs_resize_file_locked(inode, size);
return rc;
}
diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
index 192649fec25d..0e872d58fae7 100644
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -2222,8 +2222,7 @@ smb2_duplicate_extents(const unsigned int xid,
rc = smb2_set_file_size(xid, tcon, trgtfile, dest_off + len, false);
if (rc)
goto duplicate_extents_out;
- netfs_resize_file(netfs_inode(inode), dest_off + len, true);
- cifs_setsize(inode, dest_off + len);
+ cifs_resize_file_locked(inode, dest_off + len);
}
rc = SMB2_ioctl(xid, tcon, trgtfile->fid.persistent_fid,
trgtfile->fid.volatile_fid,
@@ -3776,8 +3775,7 @@ static long smb3_simple_falloc(struct file *file, struct cifs_tcon *tcon,
}
new_eof = off + len;
- netfs_resize_file(&cifsi->netfs, new_eof, true);
- cifs_setsize(inode, new_eof);
+ cifs_resize_file_locked(inode, new_eof);
qrc = SMB2_query_info(xid, tcon,
cfile->fid.persistent_fid,
@@ -3825,8 +3823,7 @@ static long smb3_simple_falloc(struct file *file, struct cifs_tcon *tcon,
if (rc)
goto out;
- netfs_resize_file(&cifsi->netfs, new_eof, true);
- cifs_setsize(inode, new_eof);
+ cifs_resize_file_locked(inode, new_eof);
qrc = SMB2_query_info(xid, tcon,
cfile->fid.persistent_fid,