Skip to content

Commit 9a005be

Browse files
committed
Merge tag '5.18-smb3-fixes-part2' of git://git.samba.org/sfrench/cifs-2.6
Pull more cifs updates from Steve French: - three fixes for big endian issues in how Persistent and Volatile file ids were stored - Various misc. fixes: including some for oops, 2 for ioctls, 1 for writeback - cleanup of how tcon (tree connection) status is tracked - Four changesets to move various duplicated protocol definitions (defined both in cifs.ko and ksmbd) into smbfs_common/smb2pdu.h - important performance improvement to use cached handles in some key compounding code paths (reduces numbers of opens/closes sent in some workloads) - fix to allow alternate DFS target to be used to retry on a failed i/o * tag '5.18-smb3-fixes-part2' of git://git.samba.org/sfrench/cifs-2.6: cifs: fix NULL ptr dereference in smb2_ioctl_query_info() cifs: prevent bad output lengths in smb2_ioctl_query_info() smb3: fix ksmbd bigendian bug in oplock break, and move its struct to smbfs_common smb3: cleanup and clarify status of tree connections smb3: move defines for query info and query fsinfo to smbfs_common smb3: move defines for ioctl protocol header and SMB2 sizes to smbfs_common [smb3] move more common protocol header definitions to smbfs_common cifs: fix incorrect use of list iterator after the loop ksmbd: store fids as opaque u64 integers cifs: fix bad fids sent over wire cifs: change smb2_query_info_compound to use a cached fid, if available cifs: convert the path to utf16 in smb2_query_info_compound cifs: writeback fix cifs: do not skip link targets when an I/O fails
2 parents ec251f3 + d6f5e35 commit 9a005be

18 files changed

Lines changed: 924 additions & 1377 deletions

fs/cifs/cifs_debug.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ static void cifs_debug_tcon(struct seq_file *m, struct cifs_tcon *tcon)
9494
le32_to_cpu(tcon->fsDevInfo.DeviceCharacteristics),
9595
le32_to_cpu(tcon->fsAttrInfo.Attributes),
9696
le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength),
97-
tcon->tidStatus);
97+
tcon->status);
9898
if (dev_type == FILE_DEVICE_DISK)
9999
seq_puts(m, " type: DISK ");
100100
else if (dev_type == FILE_DEVICE_CD_ROM)

fs/cifs/cifsfs.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -699,14 +699,14 @@ static void cifs_umount_begin(struct super_block *sb)
699699
tcon = cifs_sb_master_tcon(cifs_sb);
700700

701701
spin_lock(&cifs_tcp_ses_lock);
702-
if ((tcon->tc_count > 1) || (tcon->tidStatus == CifsExiting)) {
702+
if ((tcon->tc_count > 1) || (tcon->status == TID_EXITING)) {
703703
/* we have other mounts to same share or we have
704704
already tried to force umount this and woken up
705705
all waiting network requests, nothing to do */
706706
spin_unlock(&cifs_tcp_ses_lock);
707707
return;
708708
} else if (tcon->tc_count == 1)
709-
tcon->tidStatus = CifsExiting;
709+
tcon->status = TID_EXITING;
710710
spin_unlock(&cifs_tcp_ses_lock);
711711

712712
/* cancel_brl_requests(tcon); */ /* BB mark all brl mids as exiting */

fs/cifs/cifsglob.h

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,18 @@ enum statusEnum {
116116
CifsInNegotiate,
117117
CifsNeedSessSetup,
118118
CifsInSessSetup,
119-
CifsNeedTcon,
120-
CifsInTcon,
121-
CifsNeedFilesInvalidate,
122-
CifsInFilesInvalidate
119+
};
120+
121+
/* associated with each tree connection to the server */
122+
enum tid_status_enum {
123+
TID_NEW = 0,
124+
TID_GOOD,
125+
TID_EXITING,
126+
TID_NEED_RECON,
127+
TID_NEED_TCON,
128+
TID_IN_TCON,
129+
TID_NEED_FILES_INVALIDATE, /* currently unused */
130+
TID_IN_FILES_INVALIDATE
123131
};
124132

125133
enum securityEnum {
@@ -853,13 +861,7 @@ compare_mid(__u16 mid, const struct smb_hdr *smb)
853861
#define CIFS_MAX_RFC1002_WSIZE ((1<<17) - 1 - sizeof(WRITE_REQ) + 4)
854862
#define CIFS_MAX_RFC1002_RSIZE ((1<<17) - 1 - sizeof(READ_RSP) + 4)
855863

856-
/*
857-
* The default wsize is 1M. find_get_pages seems to return a maximum of 256
858-
* pages in a single call. With PAGE_SIZE == 4k, this means we can fill
859-
* a single wsize request with a single call.
860-
*/
861864
#define CIFS_DEFAULT_IOSIZE (1024 * 1024)
862-
#define SMB3_DEFAULT_IOSIZE (4 * 1024 * 1024)
863865

864866
/*
865867
* Windows only supports a max of 60kb reads and 65535 byte writes. Default to
@@ -1039,7 +1041,7 @@ struct cifs_tcon {
10391041
char *password; /* for share-level security */
10401042
__u32 tid; /* The 4 byte tree id */
10411043
__u16 Flags; /* optional support bits */
1042-
enum statusEnum tidStatus;
1044+
enum tid_status_enum status;
10431045
atomic_t num_smbs_sent;
10441046
union {
10451047
struct {

fs/cifs/cifspdu.h

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -123,18 +123,6 @@
123123
*/
124124
#define CIFS_SESS_KEY_SIZE (16)
125125

126-
/*
127-
* Size of the smb3 signing key
128-
*/
129-
#define SMB3_SIGN_KEY_SIZE (16)
130-
131-
/*
132-
* Size of the smb3 encryption/decryption key storage.
133-
* This size is big enough to store any cipher key types.
134-
*/
135-
#define SMB3_ENC_DEC_KEY_SIZE (32)
136-
137-
#define CIFS_CLIENT_CHALLENGE_SIZE (8)
138126
#define CIFS_SERVER_CHALLENGE_SIZE (8)
139127
#define CIFS_HMAC_MD5_HASH_SIZE (16)
140128
#define CIFS_CPHTXT_SIZE (16)
@@ -1658,7 +1646,7 @@ struct smb_t2_rsp {
16581646
#define SMB_FIND_FILE_ID_FULL_DIR_INFO 0x105
16591647
#define SMB_FIND_FILE_ID_BOTH_DIR_INFO 0x106
16601648
#define SMB_FIND_FILE_UNIX 0x202
1661-
#define SMB_FIND_FILE_POSIX_INFO 0x064
1649+
/* #define SMB_FIND_FILE_POSIX_INFO 0x064 */
16621650

16631651
typedef struct smb_com_transaction2_qpi_req {
16641652
struct smb_hdr hdr; /* wct = 14+ */

fs/cifs/cifssmb.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,11 @@ cifs_mark_open_files_invalid(struct cifs_tcon *tcon)
7575

7676
/* only send once per connect */
7777
spin_lock(&cifs_tcp_ses_lock);
78-
if (tcon->ses->status != CifsGood ||
79-
tcon->tidStatus != CifsNeedReconnect) {
78+
if ((tcon->ses->status != CifsGood) || (tcon->status != TID_NEED_RECON)) {
8079
spin_unlock(&cifs_tcp_ses_lock);
8180
return;
8281
}
83-
tcon->tidStatus = CifsInFilesInvalidate;
82+
tcon->status = TID_IN_FILES_INVALIDATE;
8483
spin_unlock(&cifs_tcp_ses_lock);
8584

8685
/* list all files open on tree connection and mark them invalid */
@@ -100,8 +99,8 @@ cifs_mark_open_files_invalid(struct cifs_tcon *tcon)
10099
mutex_unlock(&tcon->crfid.fid_mutex);
101100

102101
spin_lock(&cifs_tcp_ses_lock);
103-
if (tcon->tidStatus == CifsInFilesInvalidate)
104-
tcon->tidStatus = CifsNeedTcon;
102+
if (tcon->status == TID_IN_FILES_INVALIDATE)
103+
tcon->status = TID_NEED_TCON;
105104
spin_unlock(&cifs_tcp_ses_lock);
106105

107106
/*
@@ -136,7 +135,7 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
136135
* have tcon) are allowed as we start force umount
137136
*/
138137
spin_lock(&cifs_tcp_ses_lock);
139-
if (tcon->tidStatus == CifsExiting) {
138+
if (tcon->status == TID_EXITING) {
140139
if (smb_command != SMB_COM_WRITE_ANDX &&
141140
smb_command != SMB_COM_OPEN_ANDX &&
142141
smb_command != SMB_COM_TREE_DISCONNECT) {

fs/cifs/connect.c

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ cifs_mark_tcp_ses_conns_for_reconnect(struct TCP_Server_Info *server,
245245

246246
list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
247247
tcon->need_reconnect = true;
248-
tcon->tidStatus = CifsNeedReconnect;
248+
tcon->status = TID_NEED_RECON;
249249
}
250250
if (ses->tcon_ipc)
251251
ses->tcon_ipc->need_reconnect = true;
@@ -2207,7 +2207,7 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
22072207

22082208
static int match_tcon(struct cifs_tcon *tcon, struct smb3_fs_context *ctx)
22092209
{
2210-
if (tcon->tidStatus == CifsExiting)
2210+
if (tcon->status == TID_EXITING)
22112211
return 0;
22122212
if (strncmp(tcon->treeName, ctx->UNC, MAX_TREE_SIZE))
22132213
return 0;
@@ -3513,6 +3513,9 @@ static int connect_dfs_target(struct mount_ctx *mnt_ctx, const char *full_path,
35133513
struct cifs_sb_info *cifs_sb = mnt_ctx->cifs_sb;
35143514
char *oldmnt = cifs_sb->ctx->mount_options;
35153515

3516+
cifs_dbg(FYI, "%s: full_path=%s ref_path=%s target=%s\n", __func__, full_path, ref_path,
3517+
dfs_cache_get_tgt_name(tit));
3518+
35163519
rc = dfs_cache_get_tgt_referral(ref_path, tit, &ref);
35173520
if (rc)
35183521
goto out;
@@ -3611,13 +3614,18 @@ static int __follow_dfs_link(struct mount_ctx *mnt_ctx)
36113614
if (rc)
36123615
goto out;
36133616

3614-
/* Try all dfs link targets */
3617+
/* Try all dfs link targets. If an I/O fails from currently connected DFS target with an
3618+
* error other than STATUS_PATH_NOT_COVERED (-EREMOTE), then retry it from other targets as
3619+
* specified in MS-DFSC "3.1.5.2 I/O Operation to Target Fails with an Error Other Than
3620+
* STATUS_PATH_NOT_COVERED."
3621+
*/
36153622
for (rc = -ENOENT, tit = dfs_cache_get_tgt_iterator(&tl);
36163623
tit; tit = dfs_cache_get_next_tgt(&tl, tit)) {
36173624
rc = connect_dfs_target(mnt_ctx, full_path, mnt_ctx->leaf_fullpath + 1, tit);
36183625
if (!rc) {
36193626
rc = is_path_remote(mnt_ctx);
3620-
break;
3627+
if (!rc || rc == -EREMOTE)
3628+
break;
36213629
}
36223630
}
36233631

@@ -3691,7 +3699,7 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx)
36913699
goto error;
36923700

36933701
rc = is_path_remote(&mnt_ctx);
3694-
if (rc == -EREMOTE)
3702+
if (rc)
36953703
rc = follow_dfs_link(&mnt_ctx);
36963704
if (rc)
36973705
goto error;
@@ -4478,12 +4486,12 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru
44784486
/* only send once per connect */
44794487
spin_lock(&cifs_tcp_ses_lock);
44804488
if (tcon->ses->status != CifsGood ||
4481-
(tcon->tidStatus != CifsNew &&
4482-
tcon->tidStatus != CifsNeedTcon)) {
4489+
(tcon->status != TID_NEW &&
4490+
tcon->status != TID_NEED_TCON)) {
44834491
spin_unlock(&cifs_tcp_ses_lock);
44844492
return 0;
44854493
}
4486-
tcon->tidStatus = CifsInTcon;
4494+
tcon->status = TID_IN_TCON;
44874495
spin_unlock(&cifs_tcp_ses_lock);
44884496

44894497
tree = kzalloc(MAX_TREE_SIZE, GFP_KERNEL);
@@ -4524,13 +4532,13 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru
45244532

45254533
if (rc) {
45264534
spin_lock(&cifs_tcp_ses_lock);
4527-
if (tcon->tidStatus == CifsInTcon)
4528-
tcon->tidStatus = CifsNeedTcon;
4535+
if (tcon->status == TID_IN_TCON)
4536+
tcon->status = TID_NEED_TCON;
45294537
spin_unlock(&cifs_tcp_ses_lock);
45304538
} else {
45314539
spin_lock(&cifs_tcp_ses_lock);
4532-
if (tcon->tidStatus == CifsInTcon)
4533-
tcon->tidStatus = CifsGood;
4540+
if (tcon->status == TID_IN_TCON)
4541+
tcon->status = TID_GOOD;
45344542
spin_unlock(&cifs_tcp_ses_lock);
45354543
tcon->need_reconnect = false;
45364544
}
@@ -4546,24 +4554,24 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru
45464554
/* only send once per connect */
45474555
spin_lock(&cifs_tcp_ses_lock);
45484556
if (tcon->ses->status != CifsGood ||
4549-
(tcon->tidStatus != CifsNew &&
4550-
tcon->tidStatus != CifsNeedTcon)) {
4557+
(tcon->status != TID_NEW &&
4558+
tcon->status != TID_NEED_TCON)) {
45514559
spin_unlock(&cifs_tcp_ses_lock);
45524560
return 0;
45534561
}
4554-
tcon->tidStatus = CifsInTcon;
4562+
tcon->status = TID_IN_TCON;
45554563
spin_unlock(&cifs_tcp_ses_lock);
45564564

45574565
rc = ops->tree_connect(xid, tcon->ses, tcon->treeName, tcon, nlsc);
45584566
if (rc) {
45594567
spin_lock(&cifs_tcp_ses_lock);
4560-
if (tcon->tidStatus == CifsInTcon)
4561-
tcon->tidStatus = CifsNeedTcon;
4568+
if (tcon->status == TID_IN_TCON)
4569+
tcon->status = TID_NEED_TCON;
45624570
spin_unlock(&cifs_tcp_ses_lock);
45634571
} else {
45644572
spin_lock(&cifs_tcp_ses_lock);
4565-
if (tcon->tidStatus == CifsInTcon)
4566-
tcon->tidStatus = CifsGood;
4573+
if (tcon->status == TID_IN_TCON)
4574+
tcon->status = TID_GOOD;
45674575
spin_unlock(&cifs_tcp_ses_lock);
45684576
tcon->need_reconnect = false;
45694577
}

fs/cifs/file.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4210,13 +4210,19 @@ cifs_page_mkwrite(struct vm_fault *vmf)
42104210
{
42114211
struct page *page = vmf->page;
42124212

4213+
/* Wait for the page to be written to the cache before we allow it to
4214+
* be modified. We then assume the entire page will need writing back.
4215+
*/
42134216
#ifdef CONFIG_CIFS_FSCACHE
42144217
if (PageFsCache(page) &&
42154218
wait_on_page_fscache_killable(page) < 0)
42164219
return VM_FAULT_RETRY;
42174220
#endif
42184221

4219-
lock_page(page);
4222+
wait_on_page_writeback(page);
4223+
4224+
if (lock_page_killable(page) < 0)
4225+
return VM_FAULT_RETRY;
42204226
return VM_FAULT_LOCKED;
42214227
}
42224228

fs/cifs/misc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ tconInfoAlloc(void)
116116
}
117117

118118
atomic_inc(&tconInfoAllocCount);
119-
ret_buf->tidStatus = CifsNew;
119+
ret_buf->status = TID_NEW;
120120
++ret_buf->tc_count;
121121
INIT_LIST_HEAD(&ret_buf->openFileList);
122122
INIT_LIST_HEAD(&ret_buf->tcon_list);

fs/cifs/smb2glob.h

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,4 @@
4141
#define END_OF_CHAIN 4
4242
#define RELATED_REQUEST 8
4343

44-
#define SMB2_SIGNATURE_SIZE (16)
45-
#define SMB2_NTLMV2_SESSKEY_SIZE (16)
46-
#define SMB2_HMACSHA256_SIZE (32)
47-
#define SMB2_CMACAES_SIZE (16)
48-
#define SMB3_SIGNKEY_SIZE (16)
49-
#define SMB3_GCM128_CRYPTKEY_SIZE (16)
50-
#define SMB3_GCM256_CRYPTKEY_SIZE (32)
51-
52-
/* Maximum buffer size value we can send with 1 credit */
53-
#define SMB2_MAX_BUFFER_SIZE 65536
54-
5544
#endif /* _SMB2_GLOB_H */

fs/cifs/smb2misc.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *srvr)
203203

204204
if (smb2_rsp_struct_sizes[command] != pdu->StructureSize2) {
205205
if (command != SMB2_OPLOCK_BREAK_HE && (shdr->Status == 0 ||
206-
pdu->StructureSize2 != SMB2_ERROR_STRUCTURE_SIZE2)) {
206+
pdu->StructureSize2 != SMB2_ERROR_STRUCTURE_SIZE2_LE)) {
207207
/* error packets have 9 byte structure size */
208208
cifs_dbg(VFS, "Invalid response size %u for command %d\n",
209209
le16_to_cpu(pdu->StructureSize2), command);
@@ -303,7 +303,7 @@ smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *shdr)
303303
/* error responses do not have data area */
304304
if (shdr->Status && shdr->Status != STATUS_MORE_PROCESSING_REQUIRED &&
305305
(((struct smb2_err_rsp *)shdr)->StructureSize) ==
306-
SMB2_ERROR_STRUCTURE_SIZE2)
306+
SMB2_ERROR_STRUCTURE_SIZE2_LE)
307307
return NULL;
308308

309309
/*
@@ -478,11 +478,11 @@ smb2_get_lease_state(struct cifsInodeInfo *cinode)
478478
__le32 lease = 0;
479479

480480
if (CIFS_CACHE_WRITE(cinode))
481-
lease |= SMB2_LEASE_WRITE_CACHING;
481+
lease |= SMB2_LEASE_WRITE_CACHING_LE;
482482
if (CIFS_CACHE_HANDLE(cinode))
483-
lease |= SMB2_LEASE_HANDLE_CACHING;
483+
lease |= SMB2_LEASE_HANDLE_CACHING_LE;
484484
if (CIFS_CACHE_READ(cinode))
485-
lease |= SMB2_LEASE_READ_CACHING;
485+
lease |= SMB2_LEASE_READ_CACHING_LE;
486486
return lease;
487487
}
488488

@@ -832,8 +832,8 @@ smb2_handle_cancelled_mid(struct mid_q_entry *mid, struct TCP_Server_Info *serve
832832
rc = __smb2_handle_cancelled_cmd(tcon,
833833
le16_to_cpu(hdr->Command),
834834
le64_to_cpu(hdr->MessageId),
835-
le64_to_cpu(rsp->PersistentFileId),
836-
le64_to_cpu(rsp->VolatileFileId));
835+
rsp->PersistentFileId,
836+
rsp->VolatileFileId);
837837
if (rc)
838838
cifs_put_tcon(tcon);
839839

0 commit comments

Comments
 (0)