summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve French <stfrench@microsoft.com>2019-08-30 03:12:41 -0400
committerSteve French <stfrench@microsoft.com>2019-09-16 12:43:38 -0400
commit41e033fecdc891da629113c4f8ee80500b7656d6 (patch)
tree4a5814b5751e18229462828564d644b9b724d5fc
parent1981ebaabd88a9b3e550b6163c570a498c32a1f5 (diff)
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>
-rw-r--r--fs/cifs/cifs_fs_sb.h1
-rw-r--r--fs/cifs/cifsfs.c2
-rw-r--r--fs/cifs/cifsglob.h5
-rw-r--r--fs/cifs/connect.c20
4 files changed, 25 insertions, 3 deletions
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index 286a104c4761..6e7c4427369d 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -54,6 +54,7 @@
54#define CIFS_MOUNT_NO_DFS 0x8000000 /* disable DFS resolving */ 54#define CIFS_MOUNT_NO_DFS 0x8000000 /* disable DFS resolving */
55#define CIFS_MOUNT_MODE_FROM_SID 0x10000000 /* retrieve mode from special ACE */ 55#define CIFS_MOUNT_MODE_FROM_SID 0x10000000 /* retrieve mode from special ACE */
56#define CIFS_MOUNT_RO_CACHE 0x20000000 /* assumes share will not change */ 56#define CIFS_MOUNT_RO_CACHE 0x20000000 /* assumes share will not change */
57#define CIFS_MOUNT_RW_CACHE 0x40000000 /* assumes only client accessing */
57 58
58struct cifs_sb_info { 59struct cifs_sb_info {
59 struct rb_root tlink_tree; 60 struct rb_root tlink_tree;
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 970251bc0661..de90e665ef11 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -400,6 +400,8 @@ cifs_show_cache_flavor(struct seq_file *s, struct cifs_sb_info *cifs_sb)
400 seq_puts(s, "strict"); 400 seq_puts(s, "strict");
401 else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) 401 else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
402 seq_puts(s, "none"); 402 seq_puts(s, "none");
403 else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RW_CACHE)
404 seq_puts(s, "singleclient"); /* assume only one client access */
403 else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RO_CACHE) 405 else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RO_CACHE)
404 seq_puts(s, "ro"); /* read only caching assumed */ 406 seq_puts(s, "ro"); /* read only caching assumed */
405 else 407 else
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 3f12da7f2f7f..fa5abe3a8514 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -560,6 +560,7 @@ struct smb_vol {
560 bool direct_io:1; 560 bool direct_io:1;
561 bool strict_io:1; /* strict cache behavior */ 561 bool strict_io:1; /* strict cache behavior */
562 bool cache_ro:1; 562 bool cache_ro:1;
563 bool cache_rw:1;
563 bool remap:1; /* set to remap seven reserved chars in filenames */ 564 bool remap:1; /* set to remap seven reserved chars in filenames */
564 bool sfu_remap:1; /* remap seven reserved chars ala SFU */ 565 bool sfu_remap:1; /* remap seven reserved chars ala SFU */
565 bool posix_paths:1; /* unset to not ask for posix pathnames. */ 566 bool posix_paths:1; /* unset to not ask for posix pathnames. */
@@ -622,7 +623,7 @@ struct smb_vol {
622 CIFS_MOUNT_CIFS_BACKUPUID | CIFS_MOUNT_CIFS_BACKUPGID | \ 623 CIFS_MOUNT_CIFS_BACKUPUID | CIFS_MOUNT_CIFS_BACKUPGID | \
623 CIFS_MOUNT_UID_FROM_ACL | CIFS_MOUNT_NO_HANDLE_CACHE | \ 624 CIFS_MOUNT_UID_FROM_ACL | CIFS_MOUNT_NO_HANDLE_CACHE | \
624 CIFS_MOUNT_NO_DFS | CIFS_MOUNT_MODE_FROM_SID | \ 625 CIFS_MOUNT_NO_DFS | CIFS_MOUNT_MODE_FROM_SID | \
625 CIFS_MOUNT_RO_CACHE) 626 CIFS_MOUNT_RO_CACHE | CIFS_MOUNT_RW_CACHE)
626 627
627/** 628/**
628 * Generic VFS superblock mount flags (s_flags) to consider when 629 * Generic VFS superblock mount flags (s_flags) to consider when
@@ -1370,7 +1371,7 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file);
1370 1371
1371#define CIFS_CACHE_READ(cinode) ((cinode->oplock & CIFS_CACHE_READ_FLG) || (CIFS_SB(cinode->vfs_inode.i_sb)->mnt_cifs_flags & CIFS_MOUNT_RO_CACHE)) 1372#define CIFS_CACHE_READ(cinode) ((cinode->oplock & CIFS_CACHE_READ_FLG) || (CIFS_SB(cinode->vfs_inode.i_sb)->mnt_cifs_flags & CIFS_MOUNT_RO_CACHE))
1372#define CIFS_CACHE_HANDLE(cinode) (cinode->oplock & CIFS_CACHE_HANDLE_FLG) 1373#define CIFS_CACHE_HANDLE(cinode) (cinode->oplock & CIFS_CACHE_HANDLE_FLG)
1373#define CIFS_CACHE_WRITE(cinode) (cinode->oplock & CIFS_CACHE_WRITE_FLG) 1374#define CIFS_CACHE_WRITE(cinode) ((cinode->oplock & CIFS_CACHE_WRITE_FLG) || (CIFS_SB(cinode->vfs_inode.i_sb)->mnt_cifs_flags & CIFS_MOUNT_RW_CACHE))
1374 1375
1375/* 1376/*
1376 * One of these for each file inode 1377 * One of these for each file inode
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 {
299 Opt_cache_strict, 299 Opt_cache_strict,
300 Opt_cache_none, 300 Opt_cache_none,
301 Opt_cache_ro, 301 Opt_cache_ro,
302 Opt_cache_rw,
302 Opt_cache_err 303 Opt_cache_err
303}; 304};
304 305
@@ -307,6 +308,7 @@ static const match_table_t cifs_cacheflavor_tokens = {
307 { Opt_cache_strict, "strict" }, 308 { Opt_cache_strict, "strict" },
308 { Opt_cache_none, "none" }, 309 { Opt_cache_none, "none" },
309 { Opt_cache_ro, "ro" }, 310 { Opt_cache_ro, "ro" },
311 { Opt_cache_rw, "singleclient" },
310 { Opt_cache_err, NULL } 312 { Opt_cache_err, NULL }
311}; 313};
312 314
@@ -1421,21 +1423,31 @@ cifs_parse_cache_flavor(char *value, struct smb_vol *vol)
1421 vol->direct_io = false; 1423 vol->direct_io = false;
1422 vol->strict_io = false; 1424 vol->strict_io = false;
1423 vol->cache_ro = false; 1425 vol->cache_ro = false;
1426 vol->cache_rw = false;
1424 break; 1427 break;
1425 case Opt_cache_strict: 1428 case Opt_cache_strict:
1426 vol->direct_io = false; 1429 vol->direct_io = false;
1427 vol->strict_io = true; 1430 vol->strict_io = true;
1428 vol->cache_ro = false; 1431 vol->cache_ro = false;
1432 vol->cache_rw = false;
1429 break; 1433 break;
1430 case Opt_cache_none: 1434 case Opt_cache_none:
1431 vol->direct_io = true; 1435 vol->direct_io = true;
1432 vol->strict_io = false; 1436 vol->strict_io = false;
1433 vol->cache_ro = false; 1437 vol->cache_ro = false;
1438 vol->cache_rw = false;
1434 break; 1439 break;
1435 case Opt_cache_ro: 1440 case Opt_cache_ro:
1436 vol->direct_io = false; 1441 vol->direct_io = false;
1437 vol->strict_io = false; 1442 vol->strict_io = false;
1438 vol->cache_ro = true; 1443 vol->cache_ro = true;
1444 vol->cache_rw = false;
1445 break;
1446 case Opt_cache_rw:
1447 vol->direct_io = false;
1448 vol->strict_io = false;
1449 vol->cache_ro = false;
1450 vol->cache_rw = true;
1439 break; 1451 break;
1440 default: 1452 default:
1441 cifs_dbg(VFS, "bad cache= option: %s\n", value); 1453 cifs_dbg(VFS, "bad cache= option: %s\n", value);
@@ -4054,6 +4066,10 @@ int cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
4054 if (pvolume_info->cache_ro) { 4066 if (pvolume_info->cache_ro) {
4055 cifs_dbg(VFS, "mounting share with read only caching. Ensure that the share will not be modified while in use.\n"); 4067 cifs_dbg(VFS, "mounting share with read only caching. Ensure that the share will not be modified while in use.\n");
4056 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RO_CACHE; 4068 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RO_CACHE;
4069 } else if (pvolume_info->cache_rw) {
4070 cifs_dbg(VFS, "mounting share in single client RW caching mode. Ensure that no other systems will be accessing the share.\n");
4071 cifs_sb->mnt_cifs_flags |= (CIFS_MOUNT_RO_CACHE |
4072 CIFS_MOUNT_RW_CACHE);
4057 } 4073 }
4058 if (pvolume_info->mfsymlinks) { 4074 if (pvolume_info->mfsymlinks) {
4059 if (pvolume_info->sfu_emul) { 4075 if (pvolume_info->sfu_emul) {
@@ -4203,8 +4219,10 @@ static int mount_get_conns(struct smb_vol *vol, struct cifs_sb_info *cifs_sb,
4203 if (tcon->fsDevInfo.DeviceCharacteristics & 4219 if (tcon->fsDevInfo.DeviceCharacteristics &
4204 FILE_READ_ONLY_DEVICE) 4220 FILE_READ_ONLY_DEVICE)
4205 cifs_dbg(VFS, "mounted to read only share\n"); 4221 cifs_dbg(VFS, "mounted to read only share\n");
4206 else 4222 else if ((cifs_sb->mnt_cifs_flags &
4223 CIFS_MOUNT_RW_CACHE) == 0)
4207 cifs_dbg(VFS, "read only mount of RW share\n"); 4224 cifs_dbg(VFS, "read only mount of RW share\n");
4225 /* no need to log a RW mount of a typical RW share */
4208 } 4226 }
4209 } 4227 }
4210 4228