Skip to content

Commit 7836195

Browse files
committed
Merge tag '4.20-rc7-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6
Pull smb3 fix from Steve French: "An important smb3 fix for an regression to some servers introduced by compounding optimization to rmdir. This fix has been tested by multiple developers (including me) with the usual private xfstesting, but also by the new cifs/smb3 "buildbot" xfstest VMs (thank you Ronnie and Aurelien for good work on this automation). The automated testing has been updated so that it will catch problems like this in the future. Note that Pavel discovered (very recently) some unrelated but extremely important bugs in credit handling (smb3 flow control problem that can lead to disconnects/reconnects) when compounding, that I would have liked to send in ASAP but the complete testing of those two fixes may not be done in time and have to wait for 4.21" * tag '4.20-rc7-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6: smb3: Fix rmdir compounding regression to strict servers
2 parents 9097a05 + 271b9c0 commit 7836195

File tree

3 files changed

+25
-17
lines changed

3 files changed

+25
-17
lines changed

fs/cifs/smb2inode.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
9797
if (rc)
9898
goto finished;
9999

100-
smb2_set_next_command(server, &rqst[num_rqst++]);
100+
smb2_set_next_command(server, &rqst[num_rqst++], 0);
101101

102102
/* Operation */
103103
switch (command) {
@@ -111,7 +111,7 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
111111
SMB2_O_INFO_FILE, 0,
112112
sizeof(struct smb2_file_all_info) +
113113
PATH_MAX * 2, 0, NULL);
114-
smb2_set_next_command(server, &rqst[num_rqst]);
114+
smb2_set_next_command(server, &rqst[num_rqst], 0);
115115
smb2_set_related(&rqst[num_rqst++]);
116116
break;
117117
case SMB2_OP_DELETE:
@@ -127,14 +127,14 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
127127
rqst[num_rqst].rq_iov = si_iov;
128128
rqst[num_rqst].rq_nvec = 1;
129129

130-
size[0] = 8;
130+
size[0] = 1; /* sizeof __u8 See MS-FSCC section 2.4.11 */
131131
data[0] = &delete_pending[0];
132132

133133
rc = SMB2_set_info_init(tcon, &rqst[num_rqst], COMPOUND_FID,
134134
COMPOUND_FID, current->tgid,
135135
FILE_DISPOSITION_INFORMATION,
136136
SMB2_O_INFO_FILE, 0, data, size);
137-
smb2_set_next_command(server, &rqst[num_rqst]);
137+
smb2_set_next_command(server, &rqst[num_rqst], 1);
138138
smb2_set_related(&rqst[num_rqst++]);
139139
break;
140140
case SMB2_OP_SET_EOF:
@@ -149,7 +149,7 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
149149
COMPOUND_FID, current->tgid,
150150
FILE_END_OF_FILE_INFORMATION,
151151
SMB2_O_INFO_FILE, 0, data, size);
152-
smb2_set_next_command(server, &rqst[num_rqst]);
152+
smb2_set_next_command(server, &rqst[num_rqst], 0);
153153
smb2_set_related(&rqst[num_rqst++]);
154154
break;
155155
case SMB2_OP_SET_INFO:
@@ -165,7 +165,7 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
165165
COMPOUND_FID, current->tgid,
166166
FILE_BASIC_INFORMATION,
167167
SMB2_O_INFO_FILE, 0, data, size);
168-
smb2_set_next_command(server, &rqst[num_rqst]);
168+
smb2_set_next_command(server, &rqst[num_rqst], 0);
169169
smb2_set_related(&rqst[num_rqst++]);
170170
break;
171171
case SMB2_OP_RENAME:
@@ -189,7 +189,7 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
189189
COMPOUND_FID, current->tgid,
190190
FILE_RENAME_INFORMATION,
191191
SMB2_O_INFO_FILE, 0, data, size);
192-
smb2_set_next_command(server, &rqst[num_rqst]);
192+
smb2_set_next_command(server, &rqst[num_rqst], 0);
193193
smb2_set_related(&rqst[num_rqst++]);
194194
break;
195195
case SMB2_OP_HARDLINK:
@@ -213,7 +213,7 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
213213
COMPOUND_FID, current->tgid,
214214
FILE_LINK_INFORMATION,
215215
SMB2_O_INFO_FILE, 0, data, size);
216-
smb2_set_next_command(server, &rqst[num_rqst]);
216+
smb2_set_next_command(server, &rqst[num_rqst], 0);
217217
smb2_set_related(&rqst[num_rqst++]);
218218
break;
219219
default:

fs/cifs/smb2ops.c

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1194,7 +1194,7 @@ smb2_ioctl_query_info(const unsigned int xid,
11941194
rc = SMB2_open_init(tcon, &rqst[0], &oplock, &oparms, path);
11951195
if (rc)
11961196
goto iqinf_exit;
1197-
smb2_set_next_command(ses->server, &rqst[0]);
1197+
smb2_set_next_command(ses->server, &rqst[0], 0);
11981198

11991199
/* Query */
12001200
memset(&qi_iov, 0, sizeof(qi_iov));
@@ -1208,7 +1208,7 @@ smb2_ioctl_query_info(const unsigned int xid,
12081208
qi.output_buffer_length, buffer);
12091209
if (rc)
12101210
goto iqinf_exit;
1211-
smb2_set_next_command(ses->server, &rqst[1]);
1211+
smb2_set_next_command(ses->server, &rqst[1], 0);
12121212
smb2_set_related(&rqst[1]);
12131213

12141214
/* Close */
@@ -1761,16 +1761,23 @@ smb2_set_related(struct smb_rqst *rqst)
17611761
char smb2_padding[7] = {0, 0, 0, 0, 0, 0, 0};
17621762

17631763
void
1764-
smb2_set_next_command(struct TCP_Server_Info *server, struct smb_rqst *rqst)
1764+
smb2_set_next_command(struct TCP_Server_Info *server, struct smb_rqst *rqst,
1765+
bool has_space_for_padding)
17651766
{
17661767
struct smb2_sync_hdr *shdr;
17671768
unsigned long len = smb_rqst_len(server, rqst);
17681769

17691770
/* SMB headers in a compound are 8 byte aligned. */
17701771
if (len & 7) {
1771-
rqst->rq_iov[rqst->rq_nvec].iov_base = smb2_padding;
1772-
rqst->rq_iov[rqst->rq_nvec].iov_len = 8 - (len & 7);
1773-
rqst->rq_nvec++;
1772+
if (has_space_for_padding) {
1773+
len = rqst->rq_iov[rqst->rq_nvec - 1].iov_len;
1774+
rqst->rq_iov[rqst->rq_nvec - 1].iov_len =
1775+
(len + 7) & ~7;
1776+
} else {
1777+
rqst->rq_iov[rqst->rq_nvec].iov_base = smb2_padding;
1778+
rqst->rq_iov[rqst->rq_nvec].iov_len = 8 - (len & 7);
1779+
rqst->rq_nvec++;
1780+
}
17741781
len = smb_rqst_len(server, rqst);
17751782
}
17761783

@@ -1820,7 +1827,7 @@ smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
18201827
rc = SMB2_open_init(tcon, &rqst[0], &oplock, &oparms, &srch_path);
18211828
if (rc)
18221829
goto qfs_exit;
1823-
smb2_set_next_command(server, &rqst[0]);
1830+
smb2_set_next_command(server, &rqst[0], 0);
18241831

18251832
memset(&qi_iov, 0, sizeof(qi_iov));
18261833
rqst[1].rq_iov = qi_iov;
@@ -1833,7 +1840,7 @@ smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
18331840
NULL);
18341841
if (rc)
18351842
goto qfs_exit;
1836-
smb2_set_next_command(server, &rqst[1]);
1843+
smb2_set_next_command(server, &rqst[1], 0);
18371844
smb2_set_related(&rqst[1]);
18381845

18391846
memset(&close_iov, 0, sizeof(close_iov));

fs/cifs/smb2proto.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,8 @@ extern int smb3_crypto_aead_allocate(struct TCP_Server_Info *server);
117117
extern unsigned long smb_rqst_len(struct TCP_Server_Info *server,
118118
struct smb_rqst *rqst);
119119
extern void smb2_set_next_command(struct TCP_Server_Info *server,
120-
struct smb_rqst *rqst);
120+
struct smb_rqst *rqst,
121+
bool has_space_for_padding);
121122
extern void smb2_set_related(struct smb_rqst *rqst);
122123

123124
/*

0 commit comments

Comments
 (0)