diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index 883db2ceba3f..f57ba8baa63b 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -9781,8 +9781,13 @@ int smb2_ioctl(struct ksmbd_work *work) ret = ksmbd_vfs_zero_data(work, fp, off, len); ksmbd_fd_put(work, fp); - if (ret < 0) + if (ret == -EAGAIN) { + rsp->hdr.Status = STATUS_FILE_LOCK_CONFLICT; + ret = 0; goto out; + } else if (ret < 0) { + goto out; + } } break; } diff --git a/fs/smb/server/vfs.c b/fs/smb/server/vfs.c index 92b6def5a229..12ab15b3bff9 100644 --- a/fs/smb/server/vfs.c +++ b/fs/smb/server/vfs.c @@ -928,6 +928,18 @@ int ksmbd_vfs_zero_data(struct ksmbd_work *work, struct ksmbd_file *fp, int err; smb_break_all_levII_oplock(work, fp, 1); + if (!work->tcon->posix_extensions) { + loff_t size = i_size_read(file_inode(fp->filp)); + + if (off < size) { + err = check_lock_range(fp->filp, off, + min(off + len, size) - 1, + WRITE); + if (err) + return -EAGAIN; + } + } + saved_cred = override_creds(fp->filp->f_cred); if (fp->f_ci->m_fattr & FILE_ATTRIBUTE_SPARSE_FILE_LE) err = vfs_fallocate(fp->filp,