Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b298f223 authored by Steve French's avatar Steve French
Browse files

[CIFS] Send SMB flush in cifs_fsync



In contrast to the now-obsolete smbfs, cifs does not send SMB_COM_FLUSH
in response to an explicit fsync(2) to guarantee that all volatile data
is written to stable storage on the server side, provided the server
honors the request (which, to my knowledge, is true for Windows and
Samba with 'strict sync' enabled).
This patch modifies the cifs_fsync implementation to restore the
fsync-behavior of smbfs by triggering SMB_COM_FLUSH after sending
outstanding data on the client side to the server.

Signed-off-by: default avatarHorst Reiterer <horst.reiterer@gmail.com>
Acked-by: default avatarJeff Layton <jlayton@redhat.com>
Signed-off-by: default avatarSteve French <sfrench@us.ibm.com>
parent ebdcc81c
Loading
Loading
Loading
Loading
+3 −1
Original line number Original line Diff line number Diff line
@@ -6,7 +6,9 @@ the server to treat subsequent connections, especially those that
are authenticated as guest, as reconnections, invalidating the earlier
are authenticated as guest, as reconnections, invalidating the earlier
user's smb session.  This fix allows cifs to mount multiple times to the
user's smb session.  This fix allows cifs to mount multiple times to the
same server with different userids without risking invalidating earlier
same server with different userids without risking invalidating earlier
established security contexts.
established security contexts.  fsync now sends SMB Flush operation
to better ensure that we wait for server to write all of the data to
server disk (not just write it over the network).


Version 1.56
Version 1.56
------------
------------
+2 −0
Original line number Original line Diff line number Diff line
@@ -340,6 +340,8 @@ static int cifs_stats_proc_show(struct seq_file *m, void *v)
				seq_printf(m, "\nWrites: %d Bytes: %lld",
				seq_printf(m, "\nWrites: %d Bytes: %lld",
					atomic_read(&tcon->num_writes),
					atomic_read(&tcon->num_writes),
					(long long)(tcon->bytes_written));
					(long long)(tcon->bytes_written));
				seq_printf(m, "\nFlushes: %d",
					atomic_read(&tcon->num_flushes));
				seq_printf(m, "\nLocks: %d HardLinks: %d "
				seq_printf(m, "\nLocks: %d HardLinks: %d "
					      "Symlinks: %d",
					      "Symlinks: %d",
					atomic_read(&tcon->num_locks),
					atomic_read(&tcon->num_locks),
+1 −0
Original line number Original line Diff line number Diff line
@@ -254,6 +254,7 @@ struct cifsTconInfo {
	atomic_t num_smbs_sent;
	atomic_t num_smbs_sent;
	atomic_t num_writes;
	atomic_t num_writes;
	atomic_t num_reads;
	atomic_t num_reads;
	atomic_t num_flushes;
	atomic_t num_oplock_brks;
	atomic_t num_oplock_brks;
	atomic_t num_opens;
	atomic_t num_opens;
	atomic_t num_closes;
	atomic_t num_closes;
+7 −0
Original line number Original line Diff line number Diff line
@@ -43,6 +43,7 @@
#define SMB_COM_CREATE_DIRECTORY      0x00 /* trivial response */
#define SMB_COM_CREATE_DIRECTORY      0x00 /* trivial response */
#define SMB_COM_DELETE_DIRECTORY      0x01 /* trivial response */
#define SMB_COM_DELETE_DIRECTORY      0x01 /* trivial response */
#define SMB_COM_CLOSE                 0x04 /* triv req/rsp, timestamp ignored */
#define SMB_COM_CLOSE                 0x04 /* triv req/rsp, timestamp ignored */
#define SMB_COM_FLUSH                 0x05 /* triv req/rsp */
#define SMB_COM_DELETE                0x06 /* trivial response */
#define SMB_COM_DELETE                0x06 /* trivial response */
#define SMB_COM_RENAME                0x07 /* trivial response */
#define SMB_COM_RENAME                0x07 /* trivial response */
#define SMB_COM_QUERY_INFORMATION     0x08 /* aka getattr */
#define SMB_COM_QUERY_INFORMATION     0x08 /* aka getattr */
@@ -790,6 +791,12 @@ typedef struct smb_com_close_rsp {
	__u16 ByteCount;	/* bct = 0 */
	__u16 ByteCount;	/* bct = 0 */
} __attribute__((packed)) CLOSE_RSP;
} __attribute__((packed)) CLOSE_RSP;


typedef struct smb_com_flush_req {
	struct smb_hdr hdr;	/* wct = 1 */
	__u16 FileID;
	__u16 ByteCount;	/* 0 */
} __attribute__((packed)) FLUSH_REQ;

typedef struct smb_com_findclose_req {
typedef struct smb_com_findclose_req {
	struct smb_hdr hdr; /* wct = 1 */
	struct smb_hdr hdr; /* wct = 1 */
	__u16 FileID;
	__u16 FileID;
+3 −0
Original line number Original line Diff line number Diff line
@@ -281,6 +281,9 @@ extern int CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon,
extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon,
extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon,
			const int smb_file_id);
			const int smb_file_id);


extern int CIFSSMBFlush(const int xid, struct cifsTconInfo *tcon,
			const int smb_file_id);

extern int CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
extern int CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
			const int netfid, unsigned int count,
			const int netfid, unsigned int count,
			const __u64 lseek, unsigned int *nbytes, char **buf,
			const __u64 lseek, unsigned int *nbytes, char **buf,
Loading