[CIFS] Add new nostrictsync cifs mount option to avoid slow SMB flush
authorSteve French <sfrench@us.ibm.com>
Mon, 23 Feb 2009 15:21:59 +0000 (15:21 +0000)
committerSteve French <sfrench@us.ibm.com>
Thu, 12 Mar 2009 01:36:20 +0000 (01:36 +0000)
If this mount option is set, when an application does an
fsync call then the cifs client does not send an SMB Flush
to the server (to force the server to write all dirty data
for this file immediately to disk), although cifs still sends
all dirty (cached) file data to the server and waits for the
server to respond to the write write.  Since SMB Flush can be
very slow, and some servers may be reliable enough (to risk
delaying slightly flushing the data to disk on the server),
turning on this option may be useful to improve performance for
applications that fsync too much, at a small risk of server
crash.  If this mount option is not set, by default cifs will
send an SMB flush request (and wait for a response) on every
fsync call.

Signed-off-by: Steve French <sfrench@us.ibm.com>
fs/cifs/CHANGES
fs/cifs/README
fs/cifs/cifs_fs_sb.h
fs/cifs/connect.c
fs/cifs/file.c

index d43e0fe333980646ebf0338d1646f4578ec567f5..b33c8412e2c821ba8ad47ed4c4b37f59b0d325d6 100644 (file)
@@ -8,7 +8,9 @@ user's smb session.  This fix allows cifs to mount multiple times to the
 same server with different userids without risking invalidating earlier
 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).
+server disk (not just write it over the network).  Add new mount
+parameter to allow user to disable sending the (slow) SMB flush on
+fsync if desired (fsync still flushes all cached write data to the server).
 
 Version 1.56
 ------------
index da4515e3be20b7d918ed8369b7bcde64d522e034..07434181623bbde6856570827646bb48155d1144 100644 (file)
@@ -472,6 +472,19 @@ A partial list of the supported mount options follows:
                even if the cifs server would support posix advisory locks.
                "forcemand" is accepted as a shorter form of this mount
                option.
+ nostrictsync   If this mount option is set, when an application does an
+               fsync call then the cifs client does not send an SMB Flush
+               to the server (to force the server to write all dirty data
+               for this file immediately to disk), although cifs still sends
+               all dirty (cached) file data to the server and waits for the
+               server to respond to the write.  Since SMB Flush can be
+               very slow, and some servers may be reliable enough (to risk
+               delaying slightly flushing the data to disk on the server),
+               turning on this option may be useful to improve performance for
+               applications that fsync too much, at a small risk of server
+               crash.  If this mount option is not set, by default cifs will
+               send an SMB flush request (and wait for a response) on every
+               fsync call.
  nodfs          Disable DFS (global name space support) even if the
                server claims to support it.  This can help work around
                a problem with parsing of DFS paths with Samba server
@@ -692,13 +705,14 @@ require this helper. Note that NTLMv2 security (which does not require the
 cifs.upcall helper program), instead of using Kerberos, is sufficient for
 some use cases.
 
-Enabling DFS support (used to access shares transparently in an MS-DFS
-global name space) requires that CONFIG_CIFS_EXPERIMENTAL be enabled.  In
-addition, DFS support for target shares which are specified as UNC
+DFS support allows transparent redirection to shares in an MS-DFS name space.
+In addition, DFS support for target shares which are specified as UNC
 names which begin with host names (rather than IP addresses) requires
 a user space helper (such as cifs.upcall) to be present in order to
 translate host names to ip address, and the user space helper must also
-be configured in the file /etc/request-key.conf
+be configured in the file /etc/request-key.conf.  Samba, Windows servers and
+many NAS appliances support DFS as a way of constructing a global name
+space to ease network configuration and improve reliability.
 
 To use cifs Kerberos and DFS support, the Linux keyutils package should be
 installed and something like the following lines should be added to the
index c4c306f7b06fca1056a2d5325bf99541a82b8d5c..e9f177bb06585f3b91788f54ba91fce117922931 100644 (file)
@@ -32,6 +32,7 @@
 #define CIFS_MOUNT_OVERR_GID    0x800 /* override gid returned from server    */
 #define CIFS_MOUNT_DYNPERM      0x1000 /* allow in-memory only mode setting   */
 #define CIFS_MOUNT_NOPOSIXBRL   0x2000 /* mandatory not posix byte range lock */
+#define CIFS_MOUNT_NO_SSYNC     0x4000 /* don't do slow SMBflush on every sync*/
 
 struct cifs_sb_info {
        struct cifsTconInfo *tcon;      /* primary mount */
index da0f4ffa06132f725570a79f7e0b5fb0b65d1eb6..18e84a4e0504d5695586e5aec4f23e3bf89862ee 100644 (file)
@@ -95,6 +95,7 @@ struct smb_vol {
        bool local_lease:1; /* check leases only on local system, not remote */
        bool noblocksnd:1;
        bool noautotune:1;
+       bool nostrictsync:1; /* do not force expensive SMBflush on every sync */
        unsigned int rsize;
        unsigned int wsize;
        unsigned int sockopt;
@@ -1274,6 +1275,10 @@ cifs_parse_mount_options(char *options, const char *devname,
                        vol->intr = 0;
                } else if (strnicmp(data, "intr", 4) == 0) {
                        vol->intr = 1;
+               } else if (strnicmp(data, "nostrictsync", 12) == 0) {
+                       vol->nostrictsync = 1;
+               } else if (strnicmp(data, "strictsync", 10) == 0) {
+                       vol->nostrictsync = 0;
                } else if (strnicmp(data, "serverino", 7) == 0) {
                        vol->server_ino = 1;
                } else if (strnicmp(data, "noserverino", 9) == 0) {
@@ -2160,6 +2165,8 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
                cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
        if (pvolume_info->nobrl)
                cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
+       if (pvolume_info->nostrictsync)
+               cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_SSYNC;
        if (pvolume_info->mand_lock)
                cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOPOSIXBRL;
        if (pvolume_info->cifs_acl)
index 83b4741b6ad0f1c3719737dcbd470ed2636aa644..6411f5f65d72626977307bb4186196bd3b340ef1 100644 (file)
@@ -1538,7 +1538,8 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync)
                rc = CIFS_I(inode)->write_behind_rc;
                CIFS_I(inode)->write_behind_rc = 0;
                tcon = CIFS_SB(inode->i_sb)->tcon;
-               if (!rc && tcon && smbfile)
+               if (!rc && tcon && smbfile &&
+                  !(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_SSYNC))
                        rc = CIFSSMBFlush(xid, tcon, smbfile->netfid);
        }