summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenrique Carvalho <henrique.carvalho@suse.com>2024-11-14 15:37:32 -0300
committerHenrique Carvalho <henrique.carvalho@suse.com>2024-11-14 16:15:27 -0300
commit2d1151570f25cf7f806c3617c76c5b219fa128e5 (patch)
tree130978057a4e19ac6570422d0ea7b99d7ddfac0e
parent7e3961347e34e2c8034cce81b4a0988192777e94 (diff)
downloadlinux-2d1151570f25cf7f806c3617c76c5b219fa128e5.tar.gz
linux-2d1151570f25cf7f806c3617c76c5b219fa128e5.tar.bz2
linux-2d1151570f25cf7f806c3617c76c5b219fa128e5.zip
smb: client: remove ->downgrade_oplock op
Add generic smb_downgrade_oplock function for smb21, smb30, and smb311. Signed-off-by: Henrique Carvalho <henrique.carvalho@suse.com>
-rw-r--r--fs/smb/client/cifsglob.h6
-rw-r--r--fs/smb/client/connect.c7
-rw-r--r--fs/smb/client/file.c3
-rw-r--r--fs/smb/client/smb2ops.c33
-rw-r--r--fs/smb/client/smb2proto.h6
5 files changed, 35 insertions, 20 deletions
diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
index 92ca5ed8e85d..83768480dcc4 100644
--- a/fs/smb/client/cifsglob.h
+++ b/fs/smb/client/cifsglob.h
@@ -274,12 +274,6 @@ struct cifs_open_parms;
struct cifs_credits;
struct smb_version_operations {
- /* verify the message */
- void (*downgrade_oplock)(struct TCP_Server_Info *server,
- struct cifsInodeInfo *cinode, __u32 oplock,
- unsigned int epoch, bool *purge_cache);
- /* set negotiated write size */
- unsigned int (*negotiate_wsize)(struct cifs_tcon *tcon, struct smb3_fs_context *ctx);
/* create directory */
int (*posix_mkdir)(const unsigned int xid, struct inode *inode,
umode_t mode, struct cifs_tcon *tcon,
diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c
index 7968d025495e..18403471876d 100644
--- a/fs/smb/client/connect.c
+++ b/fs/smb/client/connect.c
@@ -3289,10 +3289,9 @@ int cifs_mount_get_tcon(struct cifs_mount_ctx *mnt_ctx)
* and set the rsize/wsize to the negotiated values if not passed in by
* the user on mount
*/
- if ((cifs_sb->ctx->wsize == 0) ||
- (cifs_sb->ctx->wsize > server->ops->negotiate_wsize(tcon, ctx))) {
- cifs_sb->ctx->wsize =
- round_down(server->ops->negotiate_wsize(tcon, ctx), PAGE_SIZE);
+ unsigned int negotiated_wsize = smb_negotiate_wsize(tcon, ctx);
+ if ((cifs_sb->ctx->wsize == 0) || (cifs_sb->ctx->wsize > negotiated_wsize)) {
+ cifs_sb->ctx->wsize = round_down(negotiated_wsize, PAGE_SIZE);
/*
* in the very unlikely event that the server sent a max write size under PAGE_SIZE,
* (which would get rounded down to 0) then reset wsize to absolute minimum eg 4096
diff --git a/fs/smb/client/file.c b/fs/smb/client/file.c
index b671bd061af4..3b401c4e1af5 100644
--- a/fs/smb/client/file.c
+++ b/fs/smb/client/file.c
@@ -2484,8 +2484,7 @@ void cifs_oplock_break(struct work_struct *work)
tcon = tlink_tcon(tlink);
server = tcon->ses->server;
- server->ops->downgrade_oplock(server, cinode, cfile->oplock_level,
- cfile->oplock_epoch, &purge_cache);
+ smb_downgrade_oplock(server, cinode, cfile->oplock_level, cfile->oplock_epoch, &purge_cache);
if (!CIFS_CACHE_WRITE(cinode) && CIFS_CACHE_READ(cinode) &&
cifs_has_mand_locks(cinode)) {
diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
index fafdab06b681..f6981a9a667d 100644
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -486,6 +486,19 @@ smb3_negotiate_wsize(struct cifs_tcon *tcon, struct smb3_fs_context *ctx)
return wsize;
}
+unsigned int
+smb_negotiate_wsize(struct cifs_tcon *tcon, struct smb3_fs_context *ctx)
+{
+ u16 protocol_id = tcon->ses->server->vals->protocol_id;
+ if (protocol_id >= SMB30_PROT_ID)
+ return smb3_negotiate_wsize(tcon, ctx);
+ else if (protocol_id == SMB21_PROT_ID)
+ return smb2_negotiate_wsize(tcon, ctx);
+ else
+ pr_warn_once("unsupported protocol id 0x%x\n", protocol_id);
+ return -ENOTSUPP;
+}
+
static unsigned int
smb2_negotiate_rsize(struct cifs_tcon *tcon, struct smb3_fs_context *ctx)
{
@@ -3980,8 +3993,6 @@ static void set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, unsigne
static void smb2_downgrade_oplock(struct TCP_Server_Info *server, struct cifsInodeInfo *cinode,
__u32 oplock, unsigned int epoch, bool *purge_cache)
{
- WARN_ON(server->vals->protocol_id != SMB21_PROT_ID);
-
set_oplock_level(cinode, oplock, 0, NULL, server->vals->protocol_id);
}
@@ -4009,6 +4020,18 @@ smb3_downgrade_oplock(struct TCP_Server_Info *server,
*purge_cache = true;
}
+void smb_downgrade_oplock(struct TCP_Server_Info *server, struct cifsInodeInfo *cinode,
+ __u32 oplock, unsigned int epoch, bool *purge_cache)
+{
+ u16 protocol_id = server->vals->protocol_id;
+ if (protocol_id >= SMB30_PROT_ID)
+ smb3_downgrade_oplock(server, cinode, oplock, epoch, purge_cache);
+ else if (protocol_id == SMB21_PROT_ID)
+ smb2_downgrade_oplock(server, cinode, oplock, epoch, purge_cache);
+ else
+ pr_warn_once("unsupported protocol id 0x%x\n", protocol_id);
+}
+
bool smb21_is_read_op(__u32 oplock)
{
return (oplock & SMB2_LEASE_READ_CACHING_HE) &&
@@ -5045,16 +5068,12 @@ int smb2_make_node(unsigned int xid, struct inode *inode,
struct smb_version_operations smb21_operations = {
/* send_cancel is missing */
- .downgrade_oplock = smb2_downgrade_oplock,
- .negotiate_wsize = smb2_negotiate_wsize,
.queryfs = smb2_queryfs,
.calc_signature = smb2_calc_signature,
.parse_lease_buf = smb2_parse_lease_buf,
};
struct smb_version_operations smb30_operations = {
- .downgrade_oplock = smb3_downgrade_oplock,
- .negotiate_wsize = smb3_negotiate_wsize,
/* WSL tags introduced long after smb2.1, enable for SMB3, 3.11 only */
.close_getattr = smb2_close_getattr,
.queryfs = smb2_queryfs,
@@ -5069,8 +5088,6 @@ struct smb_version_operations smb30_operations = {
};
struct smb_version_operations smb311_operations = {
- .downgrade_oplock = smb3_downgrade_oplock,
- .negotiate_wsize = smb3_negotiate_wsize,
.posix_mkdir = smb311_posix_mkdir,
.close_getattr = smb2_close_getattr,
.queryfs = smb311_queryfs,
diff --git a/fs/smb/client/smb2proto.h b/fs/smb/client/smb2proto.h
index 957441d83607..6a73a0c2dd8e 100644
--- a/fs/smb/client/smb2proto.h
+++ b/fs/smb/client/smb2proto.h
@@ -25,6 +25,7 @@ struct smb2_hdr;
struct smb_rqst;
struct mid_q_entry;
struct TCP_Server_Info;
+struct cifs_tcon;
struct cifs_ses;
struct cifs_credits;
struct cifs_io_subrequest;
@@ -54,7 +55,12 @@ struct smb3_fs_context;
*****************************************************************
*/
extern unsigned int smb_negotiate_rsize(struct cifs_tcon *tcon, struct smb3_fs_context *ctx);
+extern unsigned int smb_negotiate_wsize(struct cifs_tcon *tcon, struct smb3_fs_context *ctx);
extern void smb_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon, struct cifs_sb_info *cifs_sb);
+extern void smb_downgrade_oplock(struct TCP_Server_Info *server,
+ struct cifsInodeInfo *cinode, __u32 oplock,
+ unsigned int epoch, bool *purge_cache);
+
extern int map_smb2_to_linux_error(char *buf, bool log_err);
extern int smb2_check_message(char *buf, unsigned int length,