In file.c we are checking for Windows style lock conflicts (even though this is Linux) for cached i/o which seems wrong (unless user mouns with "forcemandatorylock" which today is ignored for non-POSIX mounts) One obvious way to fix this would be to do something like this change: diff --git a/fs/smb/client/file.c b/fs/smb/client/file.c index 45459af5044d..a6c97af31cdf 100644 --- a/fs/smb/client/file.c +++ b/fs/smb/client/file.c @@ -2789,9 +2789,6 @@ cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from) struct inode *inode = file_inode(iocb->ki_filp); struct cifsInodeInfo *cinode = CIFS_I(inode); struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); - struct cifsFileInfo *cfile = (struct cifsFileInfo *) - iocb->ki_filp->private_data; - struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); ssize_t written; written = cifs_get_writer(cinode); @@ -2799,9 +2796,7 @@ cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from) return written; if (CIFS_CACHE_WRITE(cinode)) { - if (cap_unix(tcon->ses) && - (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) && - ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) { + if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0) { written = netfs_file_write_iter(iocb, from); goto out; } Another would be something like: diff --git a/fs/smb/client/file.c b/fs/smb/client/file.c index 45459af5044d..57f9d934eb4e 100644 --- a/fs/smb/client/file.c +++ b/fs/smb/client/file.c @@ -2753,6 +2753,7 @@ cifs_writev(struct kiocb *iocb, struct iov_iter *from) struct inode *inode = file->f_mapping->host; struct cifsInodeInfo *cinode = CIFS_I(inode); struct TCP_Server_Info *server = tlink_tcon(cfile->tlink)->ses->server; + struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); ssize_t rc; rc = netfs_start_io_write(inode); @@ -2769,12 +2770,16 @@ cifs_writev(struct kiocb *iocb, struct iov_iter *from) if (rc <= 0) goto out; - if (!cifs_find_lock_conflict(cfile, iocb->ki_pos, iov_iter_count(from), + if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL)) + if (cifs_find_lock_conflict(cfile, iocb->ki_pos, iov_iter_count(from), server->vals->exclusive_lock_type, 0, - NULL, CIFS_WRITE_OP)) - rc = netfs_buffered_write_iter_locked(iocb, from, NULL); - else - rc = -EACCES; + NULL, CIFS_WRITE_OP)) { + rc = -EACCES; + goto out; + } + + rc = netfs_buffered_write_iter_locked(iocb, from, NULL); + out: up_read(&cinode->lock_sem); netfs_end_io_write(inode); Any opinions about which approach looks better? -- Thanks, Steve
diff --git a/fs/smb/client/file.c b/fs/smb/client/file.c index 45459af5044d..a6c97af31cdf 100644 --- a/fs/smb/client/file.c +++ b/fs/smb/client/file.c @@ -2789,9 +2789,6 @@ cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from) struct inode *inode = file_inode(iocb->ki_filp); struct cifsInodeInfo *cinode = CIFS_I(inode); struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); - struct cifsFileInfo *cfile = (struct cifsFileInfo *) - iocb->ki_filp->private_data; - struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); ssize_t written; written = cifs_get_writer(cinode); @@ -2799,9 +2796,7 @@ cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from) return written; if (CIFS_CACHE_WRITE(cinode)) { - if (cap_unix(tcon->ses) && - (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) && - ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) { + if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0) { written = netfs_file_write_iter(iocb, from); goto out; }
diff --git a/fs/smb/client/file.c b/fs/smb/client/file.c index 45459af5044d..57f9d934eb4e 100644 --- a/fs/smb/client/file.c +++ b/fs/smb/client/file.c @@ -2753,6 +2753,7 @@ cifs_writev(struct kiocb *iocb, struct iov_iter *from) struct inode *inode = file->f_mapping->host; struct cifsInodeInfo *cinode = CIFS_I(inode); struct TCP_Server_Info *server = tlink_tcon(cfile->tlink)->ses->server; + struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); ssize_t rc; rc = netfs_start_io_write(inode); @@ -2769,12 +2770,16 @@ cifs_writev(struct kiocb *iocb, struct iov_iter *from) if (rc <= 0) goto out; - if (!cifs_find_lock_conflict(cfile, iocb->ki_pos, iov_iter_count(from), + if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL)) + if (cifs_find_lock_conflict(cfile, iocb->ki_pos, iov_iter_count(from), server->vals->exclusive_lock_type, 0, - NULL, CIFS_WRITE_OP)) - rc = netfs_buffered_write_iter_locked(iocb, from, NULL); - else - rc = -EACCES; + NULL, CIFS_WRITE_OP)) { + rc = -EACCES; + goto out; + } + + rc = netfs_buffered_write_iter_locked(iocb, from, NULL); + out: up_read(&cinode->lock_sem); netfs_end_io_write(inode);