summaryrefslogtreecommitdiff
path: root/fs/cifs/connect.c
diff options
context:
space:
mode:
authorSteve French <stfrench@microsoft.com>2019-08-30 10:12:41 +0300
committerSteve French <stfrench@microsoft.com>2019-09-16 19:43:38 +0300
commit41e033fecdc891da629113c4f8ee80500b7656d6 (patch)
tree4a5814b5751e18229462828564d644b9b724d5fc /fs/cifs/connect.c
parent1981ebaabd88a9b3e550b6163c570a498c32a1f5 (diff)
downloadlinux-41e033fecdc891da629113c4f8ee80500b7656d6.tar.xz
smb3: add mount option to allow RW caching of share accessed by only 1 client
If a share is known to be only to be accessed by one client, we can aggressively cache writes not just reads to it. Add "cache=" option (cache=singleclient) for mounting read write shares (that will not be read or written to from other clients while we have it mounted) in order to improve performance. Signed-off-by: Steve French <stfrench@microsoft.com>
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r--fs/cifs/connect.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 072c01f4e9c1..d9a995588c74 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -299,6 +299,7 @@ enum {
Opt_cache_strict,
Opt_cache_none,
Opt_cache_ro,
+ Opt_cache_rw,
Opt_cache_err
};
@@ -307,6 +308,7 @@ static const match_table_t cifs_cacheflavor_tokens = {
{ Opt_cache_strict, "strict" },
{ Opt_cache_none, "none" },
{ Opt_cache_ro, "ro" },
+ { Opt_cache_rw, "singleclient" },
{ Opt_cache_err, NULL }
};
@@ -1421,21 +1423,31 @@ cifs_parse_cache_flavor(char *value, struct smb_vol *vol)
vol->direct_io = false;
vol->strict_io = false;
vol->cache_ro = false;
+ vol->cache_rw = false;
break;
case Opt_cache_strict:
vol->direct_io = false;
vol->strict_io = true;
vol->cache_ro = false;
+ vol->cache_rw = false;
break;
case Opt_cache_none:
vol->direct_io = true;
vol->strict_io = false;
vol->cache_ro = false;
+ vol->cache_rw = false;
break;
case Opt_cache_ro:
vol->direct_io = false;
vol->strict_io = false;
vol->cache_ro = true;
+ vol->cache_rw = false;
+ break;
+ case Opt_cache_rw:
+ vol->direct_io = false;
+ vol->strict_io = false;
+ vol->cache_ro = false;
+ vol->cache_rw = true;
break;
default:
cifs_dbg(VFS, "bad cache= option: %s\n", value);
@@ -4054,6 +4066,10 @@ int cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
if (pvolume_info->cache_ro) {
cifs_dbg(VFS, "mounting share with read only caching. Ensure that the share will not be modified while in use.\n");
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RO_CACHE;
+ } else if (pvolume_info->cache_rw) {
+ cifs_dbg(VFS, "mounting share in single client RW caching mode. Ensure that no other systems will be accessing the share.\n");
+ cifs_sb->mnt_cifs_flags |= (CIFS_MOUNT_RO_CACHE |
+ CIFS_MOUNT_RW_CACHE);
}
if (pvolume_info->mfsymlinks) {
if (pvolume_info->sfu_emul) {
@@ -4203,8 +4219,10 @@ static int mount_get_conns(struct smb_vol *vol, struct cifs_sb_info *cifs_sb,
if (tcon->fsDevInfo.DeviceCharacteristics &
FILE_READ_ONLY_DEVICE)
cifs_dbg(VFS, "mounted to read only share\n");
- else
+ else if ((cifs_sb->mnt_cifs_flags &
+ CIFS_MOUNT_RW_CACHE) == 0)
cifs_dbg(VFS, "read only mount of RW share\n");
+ /* no need to log a RW mount of a typical RW share */
}
}