CIFS: Add SMB2 support for flush
authorPavel Shilovsky <pshilovsky@samba.org>
Tue, 18 Sep 2012 23:20:28 +0000 (16:20 -0700)
committerSteve French <smfrench@gmail.com>
Tue, 25 Sep 2012 02:46:27 +0000 (21:46 -0500)
Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org>
Signed-off-by: Steve French <smfrench@gmail.com>
fs/cifs/smb2ops.c
fs/cifs/smb2pdu.c
fs/cifs/smb2pdu.h
fs/cifs/smb2proto.h

index 0fd5801682526eb4ffd6fe3684b92aba33c8804a..d81e1daeb8f0102d286083f56a9cd59df32a8cc6 100644 (file)
@@ -329,6 +329,13 @@ smb2_close_file(const unsigned int xid, struct cifs_tcon *tcon,
        return SMB2_close(xid, tcon, fid->persistent_fid, fid->volatile_fid);
 }
 
+static int
+smb2_flush_file(const unsigned int xid, struct cifs_tcon *tcon,
+               struct cifs_fid *fid)
+{
+       return SMB2_flush(xid, tcon, fid->persistent_fid, fid->volatile_fid);
+}
+
 struct smb_version_operations smb21_operations = {
        .setup_request = smb2_setup_request,
        .setup_async_request = smb2_setup_async_request,
@@ -363,6 +370,7 @@ struct smb_version_operations smb21_operations = {
        .open = smb2_open_file,
        .set_fid = smb2_set_fid,
        .close = smb2_close_file,
+       .flush = smb2_flush_file,
 };
 
 struct smb_version_values smb21_values = {
index 231e9701ab856495b5a3f583cb58bbc76bb07450..ff374063f4e27d451b652522c394ea22e9fb1241 100644 (file)
@@ -1152,3 +1152,41 @@ SMB2_echo(struct TCP_Server_Info *server)
        cifs_small_buf_release(req);
        return rc;
 }
+
+int
+SMB2_flush(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
+          u64 volatile_fid)
+{
+       struct smb2_flush_req *req;
+       struct TCP_Server_Info *server;
+       struct cifs_ses *ses = tcon->ses;
+       struct kvec iov[1];
+       int resp_buftype;
+       int rc = 0;
+
+       cFYI(1, "Flush");
+
+       if (ses && (ses->server))
+               server = ses->server;
+       else
+               return -EIO;
+
+       rc = small_smb2_init(SMB2_FLUSH, tcon, (void **) &req);
+       if (rc)
+               return rc;
+
+       req->PersistentFileId = persistent_fid;
+       req->VolatileFileId = volatile_fid;
+
+       iov[0].iov_base = (char *)req;
+       /* 4 for rfc1002 length field */
+       iov[0].iov_len = get_rfc1002_length(req) + 4;
+
+       rc = SendReceive2(xid, ses, iov, 1, &resp_buftype, 0);
+
+       if ((rc != 0) && tcon)
+               cifs_stats_fail_inc(tcon, SMB2_FLUSH_HE);
+
+       free_rsp_buf(resp_buftype, iov[0].iov_base);
+       return rc;
+}
index 0e962cbf8166314ef94630b913fd1736dfc45349..f5bf63f66971c151d8e6c554b1022d11033785be 100644 (file)
@@ -453,6 +453,21 @@ struct smb2_close_rsp {
        __le32 Attributes;
 } __packed;
 
+struct smb2_flush_req {
+       struct smb2_hdr hdr;
+       __le16 StructureSize;   /* Must be 24 */
+       __le16 Reserved1;
+       __le32 Reserved2;
+       __u64  PersistentFileId; /* opaque endianness */
+       __u64  VolatileFileId; /* opaque endianness */
+} __packed;
+
+struct smb2_flush_rsp {
+       struct smb2_hdr hdr;
+       __le16 StructureSize;
+       __le16 Reserved;
+} __packed;
+
 struct smb2_echo_req {
        struct smb2_hdr hdr;
        __le16 StructureSize;   /* Must be 4 */
index 624d344e1a579209834e2d8c5bb5c103e2fda971..51e6cd185c79a67d0f9660795b1a33e25b89fa2e 100644 (file)
@@ -89,6 +89,8 @@ extern int SMB2_open(const unsigned int xid, struct cifs_tcon *tcon,
                     struct smb2_file_all_info *buf);
 extern int SMB2_close(const unsigned int xid, struct cifs_tcon *tcon,
                      u64 persistent_file_id, u64 volatile_file_id);
+extern int SMB2_flush(const unsigned int xid, struct cifs_tcon *tcon,
+                     u64 persistent_file_id, u64 volatile_file_id);
 extern int SMB2_query_info(const unsigned int xid, struct cifs_tcon *tcon,
                           u64 persistent_file_id, u64 volatile_file_id,
                           struct smb2_file_all_info *data);