diff options
author | Steve French <stfrench@microsoft.com> | 2019-08-30 03:12:41 -0400 |
---|---|---|
committer | Steve French <stfrench@microsoft.com> | 2019-09-16 12:43:38 -0400 |
commit | 41e033fecdc891da629113c4f8ee80500b7656d6 (patch) | |
tree | 4a5814b5751e18229462828564d644b9b724d5fc | |
parent | 1981ebaabd88a9b3e550b6163c570a498c32a1f5 (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.h | 1 | ||||
-rw-r--r-- | fs/cifs/cifsfs.c | 2 | ||||
-rw-r--r-- | fs/cifs/cifsglob.h | 5 | ||||
-rw-r--r-- | fs/cifs/connect.c | 20 |
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 | ||
58 | struct cifs_sb_info { | 59 | struct 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 | ||