FAILED: patch "[PATCH] smb3: missing inode locks in zero range" failed to apply to 4.19-stable tree
[email protected]
maintainerThe patch below does not apply to the 4.19-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From c919c164fc87bcca8e80b3b9224492fa5b6455ba Mon Sep 17 00:00:00 2001
From: David Howells <[email protected]>
Date: Tue, 23 Aug 2022 01:01:36 -0500
Subject: [PATCH] smb3: missing inode locks in zero range
smb3 fallocate zero range was not grabbing the inode or filemap_invalidate locks so could have race with pagemap reinstantiating the page.
Signed-off-by David Howells <[email protected]>
Signed-off-by Steve French <[email protected]>
fs/cifs/smb2ops.c +30 -25
@@ -3307,26 +3307,43 @@ get_smb2_acl(struct cifs_sb_info *cifs_sb,return pntsd; } +static long smb3_zero_data (struct file *file,struct cifs_tcon *tcon, +loff_t offset,loff_t len,unsigned int xid) +{ +struct cifsFileInfo *cfile = file->private_data; +struct file_zero_data_information fsctl_buf; + +cifs_dbg (FYI ,"Offset %lld len %lld\n" , offset, len); + + fsctl_buf.FileOffset =cpu_to_le64 (offset); + fsctl_buf.BeyondFinalZero =cpu_to_le64 (offset + len); + +return SMB2_ioctl (xid, tcon, cfile->fid.persistent_fid, + cfile->fid.volatile_fid,FSCTL_SET_ZERO_DATA , + (char *)&fsctl_buf, +sizeof (struct file_zero_data_information ), +0 ,NULL ,NULL ); +} +static long smb3_zero_range (struct file *file,struct cifs_tcon *tcon,loff_t offset,loff_t len,bool keep_size) {struct cifs_ses *ses = tcon->ses; -struct inode *inode; -struct cifsInodeInfo *cifsi; +struct inode *inode =file_inode (file); +struct cifsInodeInfo *cifsi =CIFS_I (inode);struct cifsFileInfo *cfile = file->private_data; -struct file_zero_data_information fsctl_buf;long rc;unsigned int xid;__le64 eof; xid =get_xid (); - inode =d_inode (cfile->dentry); - cifsi =CIFS_I (inode); -trace_smb3_zero_enter (xid, cfile->fid.persistent_fid, tcon->tid, ses->Suid, offset, len); +inode_lock (inode); +filemap_invalidate_lock (inode->i_mapping); +/* * We zero the range through ioctl, so we need remove the page caches * first, otherwise the data may be inconsistent with the server.
@@ -3334,26 +3351,12 @@ static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon,truncate_pagecache_range (inode, offset, offset + len -1 );/* if file not oplocked can't be sure whether asking to extend size */ -if (!CIFS_CACHE_READ (cifsi)) -if (keep_size == false) { - rc = -EOPNOTSUPP ; -trace_smb3_zero_err (xid, cfile->fid.persistent_fid, - tcon->tid, ses->Suid, offset, len, rc); -free_xid (xid); -return rc; - } - -cifs_dbg (FYI ,"Offset %lld len %lld\n" , offset, len); - - fsctl_buf.FileOffset =cpu_to_le64 (offset); - fsctl_buf.BeyondFinalZero =cpu_to_le64 (offset + len); + rc = -EOPNOTSUPP ; +if (keep_size == false && !CIFS_CACHE_READ (cifsi)) + goto zero_range_exit; - rc =SMB2_ioctl (xid, tcon, cfile->fid.persistent_fid, - cfile->fid.volatile_fid,FSCTL_SET_ZERO_DATA , - (char *)&fsctl_buf, -sizeof (struct file_zero_data_information ), -0 ,NULL ,NULL ); -if (rc) + rc =smb3_zero_data (file, tcon, offset, len, xid); +if (rc <0 ) goto zero_range_exit;/*
@@ -3366,6 +3369,8 @@ 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,