diff options
| author | Enzo Matsumiya <ematsumiya@suse.de> | 2024-11-13 18:41:57 -0300 |
|---|---|---|
| committer | Enzo Matsumiya <ematsumiya@suse.de> | 2024-11-14 15:54:44 -0300 |
| commit | a10fb4913a4ad6d10166d1feba26fbc8b9deb322 (patch) | |
| tree | d7a5040015e7e1ef691debcce7314ecf12bd1501 | |
| parent | e0566abf2543a74e339660f0ffe45498dd439100 (diff) | |
| download | linux-a10fb4913a4ad6d10166d1feba26fbc8b9deb322.tar.gz linux-a10fb4913a4ad6d10166d1feba26fbc8b9deb322.tar.bz2 linux-a10fb4913a4ad6d10166d1feba26fbc8b9deb322.zip | |
smb: client: remove ->set_oplock_level op
Add set_oplock_level() that chooses the correct function based if
SMB 2.1 or >= 3.0.
Signed-off-by: Enzo Matsumiya <ematsumiya@suse.de>
| -rw-r--r-- | fs/smb/client/cifsglob.h | 3 | ||||
| -rw-r--r-- | fs/smb/client/smb2ops.c | 114 |
2 files changed, 58 insertions, 59 deletions
diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h index 5a8ed847bdc7..0e2a532ff1ab 100644 --- a/fs/smb/client/cifsglob.h +++ b/fs/smb/client/cifsglob.h @@ -302,9 +302,6 @@ struct smb_version_operations { struct TCP_Server_Info *server); int (*calc_signature)(struct smb_rqst *, struct TCP_Server_Info *, bool allocate_crypto); - /* set oplock level for the inode */ - void (*set_oplock_level)(struct cifsInodeInfo *, __u32, unsigned int, - bool *); /* create lease context buffer for CREATE request */ char * (*create_lease_buf)(u8 *lease_key, u8 oplock); /* parse lease context buffer and return oplock/epoch info */ diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c index 416104bc0966..6018411f9cbf 100644 --- a/fs/smb/client/smb2ops.c +++ b/fs/smb/client/smb2ops.c @@ -1388,6 +1388,9 @@ void smb2_print_stats(struct seq_file *m, struct cifs_tcon *tcon) atomic_read(&failed[SMB2_OPLOCK_BREAK_HE])); } +static void set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, unsigned int epoch, + bool *purge_cache, u16 protocol_id); + void smb2_set_fid(struct cifsFileInfo *cfile, struct cifs_fid *fid, __u32 oplock) { struct cifsInodeInfo *cinode = CIFS_I(d_inode(cfile->dentry)); @@ -1399,8 +1402,7 @@ void smb2_set_fid(struct cifsFileInfo *cfile, struct cifs_fid *fid, __u32 oplock #ifdef CONFIG_CIFS_DEBUG2 cfile->fid.mid = fid->mid; #endif /* CIFS_DEBUG2 */ - server->ops->set_oplock_level(cinode, oplock, fid->epoch, - &fid->purge_cache); + set_oplock_level(cinode, oplock, fid->epoch, &fid->purge_cache, server->vals->protocol_id); cinode->can_cache_brlcks = CIFS_CACHE_WRITE(cinode); memcpy(cfile->fid.create_guid, fid->create_guid, 16); } @@ -3846,50 +3848,16 @@ static long smb3_fallocate(struct file *file, struct cifs_tcon *tcon, int mode, return -EOPNOTSUPP; } -static void -smb2_downgrade_oplock(struct TCP_Server_Info *server, - struct cifsInodeInfo *cinode, __u32 oplock, - unsigned int epoch, bool *purge_cache) -{ - server->ops->set_oplock_level(cinode, oplock, 0, NULL); -} - -static void -smb21_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, - unsigned int epoch, bool *purge_cache); - -static void -smb3_downgrade_oplock(struct TCP_Server_Info *server, - struct cifsInodeInfo *cinode, __u32 oplock, - unsigned int epoch, bool *purge_cache) -{ - unsigned int old_state = cinode->oplock; - unsigned int old_epoch = cinode->epoch; - unsigned int new_state; - - if (epoch > old_epoch) { - smb21_set_oplock_level(cinode, oplock, 0, NULL); - cinode->epoch = epoch; - } - - new_state = cinode->oplock; - *purge_cache = false; - - if ((old_state & CIFS_CACHE_READ_FLG) != 0 && - (new_state & CIFS_CACHE_READ_FLG) == 0) - *purge_cache = true; - else if (old_state == new_state && (epoch - old_epoch > 1)) - *purge_cache = true; -} - -static void -smb2_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, - unsigned int epoch, bool *purge_cache) +static void __set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, unsigned int epoch, + bool *purge_cache) { oplock &= 0xFF; cinode->lease_granted = false; + if (oplock == SMB2_OPLOCK_LEVEL_NOCHANGE) return; + + cinode->oplock = 0; if (oplock == SMB2_OPLOCK_LEVEL_BATCH) { cinode->oplock = CIFS_CACHE_RHW_FLG; cifs_dbg(FYI, "Batch Oplock granted on inode %p\n", @@ -3902,13 +3870,11 @@ smb2_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, cinode->oplock = CIFS_CACHE_READ_FLG; cifs_dbg(FYI, "Level II Oplock granted on inode %p\n", &cinode->netfs.inode); - } else - cinode->oplock = 0; + } } -static void -smb21_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, - unsigned int epoch, bool *purge_cache) +static void smb21_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, unsigned int epoch, + bool *purge_cache) { char message[5] = {0}; unsigned int new_oplock = 0; @@ -3920,8 +3886,7 @@ smb21_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, /* Check if the server granted an oplock rather than a lease */ if (oplock & SMB2_OPLOCK_LEVEL_EXCLUSIVE) - return smb2_set_oplock_level(cinode, oplock, epoch, - purge_cache); + return __set_oplock_level(cinode, oplock, epoch, purge_cache); if (oplock & SMB2_LEASE_READ_CACHING_HE) { new_oplock |= CIFS_CACHE_READ_FLG; @@ -3939,13 +3904,11 @@ smb21_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, strscpy(message, "None"); cinode->oplock = new_oplock; - cifs_dbg(FYI, "%s Lease granted on inode %p\n", message, - &cinode->netfs.inode); + cifs_dbg(FYI, "%s Lease granted on inode %p\n", message, &cinode->netfs.inode); } -static void -smb3_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, - unsigned int epoch, bool *purge_cache) +static void smb3_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, unsigned int epoch, + bool *purge_cache) { unsigned int old_oplock = cinode->oplock; @@ -3978,6 +3941,48 @@ smb3_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, } } +static void set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, unsigned int epoch, + bool *purge_cache, u16 protocol_id) +{ + if (protocol_id >= SMB30_PROT_ID) + smb3_set_oplock_level(cinode, oplock, epoch, purge_cache); + else if (protocol_id == SMB21_PROT_ID) + smb21_set_oplock_level(cinode, oplock, epoch, purge_cache); + else + pr_warn_once("unsupported protocol id 0x%x\n", protocol_id); +} + +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); +} + +static void +smb3_downgrade_oplock(struct TCP_Server_Info *server, + struct cifsInodeInfo *cinode, __u32 oplock, + unsigned int epoch, bool *purge_cache) +{ + unsigned int old_state = cinode->oplock; + unsigned int old_epoch = cinode->epoch; + unsigned int new_state; + + if (epoch > old_epoch) { + smb21_set_oplock_level(cinode, oplock, 0, NULL); + cinode->epoch = epoch; + } + + new_state = cinode->oplock; + *purge_cache = false; + + if ((old_state & CIFS_CACHE_READ_FLG) != 0 && + (new_state & CIFS_CACHE_READ_FLG) == 0) + *purge_cache = true; + else if (old_state == new_state && (epoch - old_epoch > 1)) + *purge_cache = true; +} bool smb21_is_read_op(__u32 oplock) { @@ -5086,7 +5091,6 @@ struct smb_version_operations smb21_operations = { .qfs_tcon = smb2_qfs_tcon, .queryfs = smb2_queryfs, .calc_signature = smb2_calc_signature, - .set_oplock_level = smb21_set_oplock_level, .create_lease_buf = smb2_create_lease_buf, .parse_lease_buf = smb2_parse_lease_buf, }; @@ -5102,7 +5106,6 @@ struct smb_version_operations smb30_operations = { .queryfs = smb2_queryfs, .generate_signingkey = generate_smb30signingkey, .calc_signature = smb3_calc_signature, - .set_oplock_level = smb3_set_oplock_level, .create_lease_buf = smb3_create_lease_buf, .parse_lease_buf = smb3_parse_lease_buf, .duplicate_extents = smb2_duplicate_extents, @@ -5123,7 +5126,6 @@ struct smb_version_operations smb311_operations = { .queryfs = smb311_queryfs, .generate_signingkey = generate_smb311signingkey, .calc_signature = smb3_calc_signature, - .set_oplock_level = smb3_set_oplock_level, .create_lease_buf = smb3_create_lease_buf, .parse_lease_buf = smb3_parse_lease_buf, .duplicate_extents = smb2_duplicate_extents, |
