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:
commit
2b75305398
8 changed files with 48 additions and 56 deletions
|
@ -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 */
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue