summaryrefslogtreecommitdiff
path: root/fs/cifs/smb2ops.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/smb2ops.c')
-rw-r--r--fs/cifs/smb2ops.c49
1 files changed, 45 insertions, 4 deletions
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index a7f328f79c6f..a5c96bc522cb 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -1178,7 +1178,7 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
memset(&close_iov, 0, sizeof(close_iov));
rqst[2].rq_iov = close_iov;
rqst[2].rq_nvec = 1;
- rc = SMB2_close_init(tcon, &rqst[2], COMPOUND_FID, COMPOUND_FID);
+ rc = SMB2_close_init(tcon, &rqst[2], COMPOUND_FID, COMPOUND_FID, false);
smb2_set_related(&rqst[2]);
rc = compound_send_recv(xid, ses, flags, 3, rqst,
@@ -1332,6 +1332,45 @@ smb2_close_file(const unsigned int xid, struct cifs_tcon *tcon,
SMB2_close(xid, tcon, fid->persistent_fid, fid->volatile_fid);
}
+static void
+smb2_close_getattr(const unsigned int xid, struct cifs_tcon *tcon,
+ struct cifsFileInfo *cfile)
+{
+ struct smb2_file_network_open_info file_inf;
+ struct inode *inode;
+ int rc;
+
+ rc = __SMB2_close(xid, tcon, cfile->fid.persistent_fid,
+ cfile->fid.volatile_fid, &file_inf);
+ if (rc)
+ return;
+
+ inode = d_inode(cfile->dentry);
+
+ spin_lock(&inode->i_lock);
+ CIFS_I(inode)->time = jiffies;
+
+ /* Creation time should not need to be updated on close */
+ if (file_inf.LastWriteTime)
+ inode->i_mtime = cifs_NTtimeToUnix(file_inf.LastWriteTime);
+ if (file_inf.ChangeTime)
+ inode->i_ctime = cifs_NTtimeToUnix(file_inf.ChangeTime);
+ if (file_inf.LastAccessTime)
+ inode->i_atime = cifs_NTtimeToUnix(file_inf.LastAccessTime);
+
+ /*
+ * i_blocks is not related to (i_size / i_blksize),
+ * but instead 512 byte (2**9) size is required for
+ * calculating num blocks.
+ */
+ if (le64_to_cpu(file_inf.AllocationSize) > 4096)
+ inode->i_blocks =
+ (512 - 1 + le64_to_cpu(file_inf.AllocationSize)) >> 9;
+
+ /* End of file and Attributes should not have to be updated on close */
+ spin_unlock(&inode->i_lock);
+}
+
static int
SMB2_request_res_key(const unsigned int xid, struct cifs_tcon *tcon,
u64 persistent_fid, u64 volatile_fid,
@@ -1512,7 +1551,7 @@ smb2_ioctl_query_info(const unsigned int xid,
rqst[2].rq_iov = close_iov;
rqst[2].rq_nvec = 1;
- rc = SMB2_close_init(tcon, &rqst[2], COMPOUND_FID, COMPOUND_FID);
+ rc = SMB2_close_init(tcon, &rqst[2], COMPOUND_FID, COMPOUND_FID, false);
if (rc)
goto iqinf_exit;
smb2_set_related(&rqst[2]);
@@ -2241,7 +2280,7 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
rqst[2].rq_iov = close_iov;
rqst[2].rq_nvec = 1;
- rc = SMB2_close_init(tcon, &rqst[2], COMPOUND_FID, COMPOUND_FID);
+ rc = SMB2_close_init(tcon, &rqst[2], COMPOUND_FID, COMPOUND_FID, false);
if (rc)
goto qic_exit;
smb2_set_related(&rqst[2]);
@@ -2654,7 +2693,7 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
rqst[2].rq_iov = close_iov;
rqst[2].rq_nvec = 1;
- rc = SMB2_close_init(tcon, &rqst[2], COMPOUND_FID, COMPOUND_FID);
+ rc = SMB2_close_init(tcon, &rqst[2], COMPOUND_FID, COMPOUND_FID, false);
if (rc)
goto querty_exit;
@@ -4707,6 +4746,7 @@ struct smb_version_operations smb30_operations = {
.open = smb2_open_file,
.set_fid = smb2_set_fid,
.close = smb2_close_file,
+ .close_getattr = smb2_close_getattr,
.flush = smb2_flush_file,
.async_readv = smb2_async_readv,
.async_writev = smb2_async_writev,
@@ -4816,6 +4856,7 @@ struct smb_version_operations smb311_operations = {
.open = smb2_open_file,
.set_fid = smb2_set_fid,
.close = smb2_close_file,
+ .close_getattr = smb2_close_getattr,
.flush = smb2_flush_file,
.async_readv = smb2_async_readv,
.async_writev = smb2_async_writev,