1
0
Fork 0
mirror of synced 2025-03-06 20:59:54 +01:00

four SMB3 client fixes, 3 DFS related

-----BEGIN PGP SIGNATURE-----
 
 iQGzBAABCgAdFiEE6fsu8pdIjtWE/DpLiiy9cAdyT1EFAmemwI0ACgkQiiy9cAdy
 T1Fb+Qv7BaDI7Vf/URbRn3W1ALrbuKDCqQhC810IKPdLai5dudKZkFJXN2NkJY/l
 +u+EfttcaOyzLakKcci6fwnMBukyZgEpvc4ksHqvx88/iwiH1pBGugyQIp9X+MRI
 CZnApOU+3vekCOrRo+/d41sNC95U/lJbZvafqbWjFx7zaqujrItc8kO3Bz6W75yr
 QWzVd1SukjfGk1TRi0PK8ShpjU/mkknIxYfZuFS+uSDJRRrnzzXPVHLlhEAQ3nfJ
 3Ec12JTRfKZkRAJolCuEH4gUALx/qA2wTapNKJj9GGw1SZO03x543Lbam/A5LAvK
 3JjVG+l89v7xmknI8njf454Vqse5YKmlw9hBnisZzSHobZkWtBIl3xVrPQGuQ9Jq
 SU/EXbrPyg8WS3yE3wmxaocY/P3++vcpiM5+EcBcnMIv4I3wcCon6Fuzuss4VoOy
 nx8zt+GJ8SwhuJJyais2+kIsqC+0+v+ohy1y6dqSwk/kBQ1Smjb9V1l5lLFywtZ+
 9K/BkLxF
 =b8eh
 -----END PGP SIGNATURE-----

Merge tag 'v6.14rc1-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6

Pull smb client fixes from Steve French:

 - Three DFS fixes: DFS mount fix, fix for noisy log msg and one to
   remove some unused code

 - SMB3 Lease fix

* tag 'v6.14rc1-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6:
  smb: client: change lease epoch type from unsigned int to __u16
  smb: client: get rid of kstrdup() in get_ses_refpath()
  smb: client: fix noisy when tree connecting to DFS interlink targets
  smb: client: don't trust DFSREF_STORAGE_SERVER bit
This commit is contained in:
Linus Torvalds 2025-02-07 19:23:06 -08:00
commit 2b75305398
8 changed files with 48 additions and 56 deletions

View file

@ -357,7 +357,7 @@ struct smb_version_operations {
int (*handle_cancelled_mid)(struct mid_q_entry *, struct TCP_Server_Info *);
void (*downgrade_oplock)(struct TCP_Server_Info *server,
struct cifsInodeInfo *cinode, __u32 oplock,
unsigned int epoch, bool *purge_cache);
__u16 epoch, bool *purge_cache);
/* process transaction2 response */
bool (*check_trans2)(struct mid_q_entry *, struct TCP_Server_Info *,
char *, int);
@ -552,12 +552,12 @@ struct smb_version_operations {
/* if we can do cache read operations */
bool (*is_read_op)(__u32);
/* set oplock level for the inode */
void (*set_oplock_level)(struct cifsInodeInfo *, __u32, unsigned int,
bool *);
void (*set_oplock_level)(struct cifsInodeInfo *cinode, __u32 oplock, __u16 epoch,
bool *purge_cache);
/* 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 */
__u8 (*parse_lease_buf)(void *buf, unsigned int *epoch, char *lkey);
__u8 (*parse_lease_buf)(void *buf, __u16 *epoch, char *lkey);
ssize_t (*copychunk_range)(const unsigned int,
struct cifsFileInfo *src_file,
struct cifsFileInfo *target_file,
@ -1447,7 +1447,7 @@ struct cifs_fid {
__u8 create_guid[16];
__u32 access;
struct cifs_pending_open *pending_open;
unsigned int epoch;
__u16 epoch;
#ifdef CONFIG_CIFS_DEBUG2
__u64 mid;
#endif /* CIFS_DEBUG2 */
@ -1480,7 +1480,7 @@ struct cifsFileInfo {
bool oplock_break_cancelled:1;
bool status_file_deleted:1; /* file has been deleted */
bool offload:1; /* offload final part of _put to a wq */
unsigned int oplock_epoch; /* epoch from the lease break */
__u16 oplock_epoch; /* epoch from the lease break */
__u32 oplock_level; /* oplock/lease level from the lease break */
int count;
spinlock_t file_info_lock; /* protects four flag/count fields above */
@ -1577,7 +1577,7 @@ struct cifsInodeInfo {
spinlock_t open_file_lock; /* protects openFileList */
__u32 cifsAttrs; /* e.g. DOS archive bit, sparse, compressed, system */
unsigned int oplock; /* oplock/lease level we have */
unsigned int epoch; /* used to track lease state changes */
__u16 epoch; /* used to track lease state changes */
#define CIFS_INODE_PENDING_OPLOCK_BREAK (0) /* oplock break in progress */
#define CIFS_INODE_PENDING_WRITERS (1) /* Writes in progress */
#define CIFS_INODE_FLAG_UNUSED (2) /* Unused flag */

View file

@ -150,25 +150,27 @@ again:
if (rc)
continue;
if (tgt.flags & DFSREF_STORAGE_SERVER) {
rc = cifs_mount_get_tcon(mnt_ctx);
if (!rc)
rc = cifs_is_path_remote(mnt_ctx);
rc = cifs_mount_get_tcon(mnt_ctx);
if (rc) {
if (tgt.server_type == DFS_TYPE_LINK &&
DFS_INTERLINK(tgt.flags))
rc = -EREMOTE;
} else {
rc = cifs_is_path_remote(mnt_ctx);
if (!rc) {
ref_walk_set_tgt_hint(rw);
break;
}
if (rc != -EREMOTE)
continue;
}
rc = ref_walk_advance(rw);
if (!rc) {
rc = setup_dfs_ref(&tgt, rw);
if (rc)
break;
ref_walk_mark_end(rw);
goto again;
if (rc == -EREMOTE) {
rc = ref_walk_advance(rw);
if (!rc) {
rc = setup_dfs_ref(&tgt, rw);
if (rc)
break;
ref_walk_mark_end(rw);
goto again;
}
}
}
} while (rc && ref_walk_descend(rw));

View file

@ -188,4 +188,11 @@ static inline void dfs_put_root_smb_sessions(struct list_head *head)
}
}
static inline const char *dfs_ses_refpath(struct cifs_ses *ses)
{
const char *path = ses->server->leaf_fullpath;
return path ? path + 1 : ERR_PTR(-ENOENT);
}
#endif /* _CIFS_DFS_H */

View file

@ -1136,33 +1136,19 @@ static bool is_ses_good(struct cifs_ses *ses)
return ret;
}
static char *get_ses_refpath(struct cifs_ses *ses)
{
struct TCP_Server_Info *server = ses->server;
char *path = ERR_PTR(-ENOENT);
if (server->leaf_fullpath) {
path = kstrdup(server->leaf_fullpath + 1, GFP_KERNEL);
if (!path)
path = ERR_PTR(-ENOMEM);
}
return path;
}
/* Refresh dfs referral of @ses */
static void refresh_ses_referral(struct cifs_ses *ses)
{
struct cache_entry *ce;
unsigned int xid;
char *path;
const char *path;
int rc = 0;
xid = get_xid();
path = get_ses_refpath(ses);
path = dfs_ses_refpath(ses);
if (IS_ERR(path)) {
rc = PTR_ERR(path);
path = NULL;
goto out;
}
@ -1181,7 +1167,6 @@ static void refresh_ses_referral(struct cifs_ses *ses)
out:
free_xid(xid);
kfree(path);
}
static int __refresh_tcon_referral(struct cifs_tcon *tcon,
@ -1231,19 +1216,18 @@ static void refresh_tcon_referral(struct cifs_tcon *tcon, bool force_refresh)
struct dfs_info3_param *refs = NULL;
struct cache_entry *ce;
struct cifs_ses *ses;
unsigned int xid;
bool needs_refresh;
char *path;
const char *path;
unsigned int xid;
int numrefs = 0;
int rc = 0;
xid = get_xid();
ses = tcon->ses;
path = get_ses_refpath(ses);
path = dfs_ses_refpath(ses);
if (IS_ERR(path)) {
rc = PTR_ERR(path);
path = NULL;
goto out;
}
@ -1271,7 +1255,6 @@ static void refresh_tcon_referral(struct cifs_tcon *tcon, bool force_refresh)
out:
free_xid(xid);
kfree(path);
free_dfs_info_array(refs, numrefs);
}

View file

@ -377,7 +377,7 @@ coalesce_t2(char *second_buf, struct smb_hdr *target_hdr)
static void
cifs_downgrade_oplock(struct TCP_Server_Info *server,
struct cifsInodeInfo *cinode, __u32 oplock,
unsigned int epoch, bool *purge_cache)
__u16 epoch, bool *purge_cache)
{
cifs_set_oplock_level(cinode, oplock);
}

View file

@ -3904,22 +3904,22 @@ static long smb3_fallocate(struct file *file, struct cifs_tcon *tcon, int mode,
static void
smb2_downgrade_oplock(struct TCP_Server_Info *server,
struct cifsInodeInfo *cinode, __u32 oplock,
unsigned int epoch, bool *purge_cache)
__u16 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);
__u16 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)
__u16 epoch, bool *purge_cache)
{
unsigned int old_state = cinode->oplock;
unsigned int old_epoch = cinode->epoch;
__u16 old_epoch = cinode->epoch;
unsigned int new_state;
if (epoch > old_epoch) {
@ -3939,7 +3939,7 @@ smb3_downgrade_oplock(struct TCP_Server_Info *server,
static void
smb2_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock,
unsigned int epoch, bool *purge_cache)
__u16 epoch, bool *purge_cache)
{
oplock &= 0xFF;
cinode->lease_granted = false;
@ -3963,7 +3963,7 @@ smb2_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock,
static void
smb21_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock,
unsigned int epoch, bool *purge_cache)
__u16 epoch, bool *purge_cache)
{
char message[5] = {0};
unsigned int new_oplock = 0;
@ -4000,7 +4000,7 @@ smb21_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock,
static void
smb3_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock,
unsigned int epoch, bool *purge_cache)
__u16 epoch, bool *purge_cache)
{
unsigned int old_oplock = cinode->oplock;
@ -4114,7 +4114,7 @@ smb3_create_lease_buf(u8 *lease_key, u8 oplock)
}
static __u8
smb2_parse_lease_buf(void *buf, unsigned int *epoch, char *lease_key)
smb2_parse_lease_buf(void *buf, __u16 *epoch, char *lease_key)
{
struct create_lease *lc = (struct create_lease *)buf;
@ -4125,7 +4125,7 @@ smb2_parse_lease_buf(void *buf, unsigned int *epoch, char *lease_key)
}
static __u8
smb3_parse_lease_buf(void *buf, unsigned int *epoch, char *lease_key)
smb3_parse_lease_buf(void *buf, __u16 *epoch, char *lease_key)
{
struct create_lease_v2 *lc = (struct create_lease_v2 *)buf;

View file

@ -2169,7 +2169,7 @@ tcon_exit:
tcon_error_exit:
if (rsp && rsp->hdr.Status == STATUS_BAD_NETWORK_NAME)
cifs_tcon_dbg(VFS, "BAD_NETWORK_NAME: %s\n", tree);
cifs_dbg(VFS | ONCE, "BAD_NETWORK_NAME: %s\n", tree);
goto tcon_exit;
}
@ -2329,7 +2329,7 @@ parse_posix_ctxt(struct create_context *cc, struct smb2_file_all_info *info,
int smb2_parse_contexts(struct TCP_Server_Info *server,
struct kvec *rsp_iov,
unsigned int *epoch,
__u16 *epoch,
char *lease_key, __u8 *oplock,
struct smb2_file_all_info *buf,
struct create_posix_rsp *posix)

View file

@ -283,7 +283,7 @@ extern enum securityEnum smb2_select_sectype(struct TCP_Server_Info *,
enum securityEnum);
int smb2_parse_contexts(struct TCP_Server_Info *server,
struct kvec *rsp_iov,
unsigned int *epoch,
__u16 *epoch,
char *lease_key, __u8 *oplock,
struct smb2_file_all_info *buf,
struct create_posix_rsp *posix);