Commit 7a5cfb1965854132f2f382eade8c6ce2eeb6f692
Committed by
Steve French
1 parent
1d8c4c0009
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
CIFS: Add SMB2 support for flush
Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org> Signed-off-by: Steve French <smfrench@gmail.com>
Showing 4 changed files with 63 additions and 0 deletions Side-by-side Diff
fs/cifs/smb2ops.c
... | ... | @@ -329,6 +329,13 @@ |
329 | 329 | return SMB2_close(xid, tcon, fid->persistent_fid, fid->volatile_fid); |
330 | 330 | } |
331 | 331 | |
332 | +static int | |
333 | +smb2_flush_file(const unsigned int xid, struct cifs_tcon *tcon, | |
334 | + struct cifs_fid *fid) | |
335 | +{ | |
336 | + return SMB2_flush(xid, tcon, fid->persistent_fid, fid->volatile_fid); | |
337 | +} | |
338 | + | |
332 | 339 | struct smb_version_operations smb21_operations = { |
333 | 340 | .setup_request = smb2_setup_request, |
334 | 341 | .setup_async_request = smb2_setup_async_request, |
... | ... | @@ -363,6 +370,7 @@ |
363 | 370 | .open = smb2_open_file, |
364 | 371 | .set_fid = smb2_set_fid, |
365 | 372 | .close = smb2_close_file, |
373 | + .flush = smb2_flush_file, | |
366 | 374 | }; |
367 | 375 | |
368 | 376 | struct smb_version_values smb21_values = { |
fs/cifs/smb2pdu.c
... | ... | @@ -1152,4 +1152,42 @@ |
1152 | 1152 | cifs_small_buf_release(req); |
1153 | 1153 | return rc; |
1154 | 1154 | } |
1155 | + | |
1156 | +int | |
1157 | +SMB2_flush(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, | |
1158 | + u64 volatile_fid) | |
1159 | +{ | |
1160 | + struct smb2_flush_req *req; | |
1161 | + struct TCP_Server_Info *server; | |
1162 | + struct cifs_ses *ses = tcon->ses; | |
1163 | + struct kvec iov[1]; | |
1164 | + int resp_buftype; | |
1165 | + int rc = 0; | |
1166 | + | |
1167 | + cFYI(1, "Flush"); | |
1168 | + | |
1169 | + if (ses && (ses->server)) | |
1170 | + server = ses->server; | |
1171 | + else | |
1172 | + return -EIO; | |
1173 | + | |
1174 | + rc = small_smb2_init(SMB2_FLUSH, tcon, (void **) &req); | |
1175 | + if (rc) | |
1176 | + return rc; | |
1177 | + | |
1178 | + req->PersistentFileId = persistent_fid; | |
1179 | + req->VolatileFileId = volatile_fid; | |
1180 | + | |
1181 | + iov[0].iov_base = (char *)req; | |
1182 | + /* 4 for rfc1002 length field */ | |
1183 | + iov[0].iov_len = get_rfc1002_length(req) + 4; | |
1184 | + | |
1185 | + rc = SendReceive2(xid, ses, iov, 1, &resp_buftype, 0); | |
1186 | + | |
1187 | + if ((rc != 0) && tcon) | |
1188 | + cifs_stats_fail_inc(tcon, SMB2_FLUSH_HE); | |
1189 | + | |
1190 | + free_rsp_buf(resp_buftype, iov[0].iov_base); | |
1191 | + return rc; | |
1192 | +} |
fs/cifs/smb2pdu.h
... | ... | @@ -453,6 +453,21 @@ |
453 | 453 | __le32 Attributes; |
454 | 454 | } __packed; |
455 | 455 | |
456 | +struct smb2_flush_req { | |
457 | + struct smb2_hdr hdr; | |
458 | + __le16 StructureSize; /* Must be 24 */ | |
459 | + __le16 Reserved1; | |
460 | + __le32 Reserved2; | |
461 | + __u64 PersistentFileId; /* opaque endianness */ | |
462 | + __u64 VolatileFileId; /* opaque endianness */ | |
463 | +} __packed; | |
464 | + | |
465 | +struct smb2_flush_rsp { | |
466 | + struct smb2_hdr hdr; | |
467 | + __le16 StructureSize; | |
468 | + __le16 Reserved; | |
469 | +} __packed; | |
470 | + | |
456 | 471 | struct smb2_echo_req { |
457 | 472 | struct smb2_hdr hdr; |
458 | 473 | __le16 StructureSize; /* Must be 4 */ |
fs/cifs/smb2proto.h
... | ... | @@ -89,6 +89,8 @@ |
89 | 89 | struct smb2_file_all_info *buf); |
90 | 90 | extern int SMB2_close(const unsigned int xid, struct cifs_tcon *tcon, |
91 | 91 | u64 persistent_file_id, u64 volatile_file_id); |
92 | +extern int SMB2_flush(const unsigned int xid, struct cifs_tcon *tcon, | |
93 | + u64 persistent_file_id, u64 volatile_file_id); | |
92 | 94 | extern int SMB2_query_info(const unsigned int xid, struct cifs_tcon *tcon, |
93 | 95 | u64 persistent_file_id, u64 volatile_file_id, |
94 | 96 | struct smb2_file_all_info *data); |