aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorSteve French <stfrench@microsoft.com>2019-08-28 00:58:54 -0400
committerSteve French <stfrench@microsoft.com>2019-09-16 12:43:37 -0400
commit83bbfa706dda668deb60e96df20327fc79e1716f (patch)
treed9682e25e2b3219df510e4f3002c105adf5f36f1 /fs/cifs
parentac6ad7a8c9f6f1fd43262b2273a45ec1fdd3a981 (diff)
smb3: add mount option to allow forced caching of read only share
If a share is immutable (at least for the period that it will be mounted) it would be helpful to not have to revalidate dentries repeatedly that we know can not be changed remotely. Add "cache=" option (cache=ro) for mounting read only shares in order to improve performance in cases in which we know that the share will not be changing while it is in use. Signed-off-by: Steve French <stfrench@microsoft.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/cifs_fs_sb.h1
-rw-r--r--fs/cifs/cifsfs.c2
-rw-r--r--fs/cifs/cifsglob.h6
-rw-r--r--fs/cifs/connect.c14
4 files changed, 21 insertions, 2 deletions
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index b326d2ca3765..286a104c4761 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -53,6 +53,7 @@
53#define CIFS_MOUNT_NO_HANDLE_CACHE 0x4000000 /* disable caching dir handles */ 53#define CIFS_MOUNT_NO_HANDLE_CACHE 0x4000000 /* disable caching dir handles */
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 57
57struct cifs_sb_info { 58struct cifs_sb_info {
58 struct rb_root tlink_tree; 59 struct rb_root tlink_tree;
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 3289b566463f..970251bc0661 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_RO_CACHE)
404 seq_puts(s, "ro"); /* read only caching assumed */
403 else 405 else
404 seq_puts(s, "loose"); 406 seq_puts(s, "loose");
405} 407}
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index fe610e7e3670..3f12da7f2f7f 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -559,6 +559,7 @@ struct smb_vol {
559 bool server_ino:1; /* use inode numbers from server ie UniqueId */ 559 bool server_ino:1; /* use inode numbers from server ie UniqueId */
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 remap:1; /* set to remap seven reserved chars in filenames */ 563 bool remap:1; /* set to remap seven reserved chars in filenames */
563 bool sfu_remap:1; /* remap seven reserved chars ala SFU */ 564 bool sfu_remap:1; /* remap seven reserved chars ala SFU */
564 bool posix_paths:1; /* unset to not ask for posix pathnames. */ 565 bool posix_paths:1; /* unset to not ask for posix pathnames. */
@@ -620,7 +621,8 @@ struct smb_vol {
620 CIFS_MOUNT_MULTIUSER | CIFS_MOUNT_STRICT_IO | \ 621 CIFS_MOUNT_MULTIUSER | CIFS_MOUNT_STRICT_IO | \
621 CIFS_MOUNT_CIFS_BACKUPUID | CIFS_MOUNT_CIFS_BACKUPGID | \ 622 CIFS_MOUNT_CIFS_BACKUPUID | CIFS_MOUNT_CIFS_BACKUPGID | \
622 CIFS_MOUNT_UID_FROM_ACL | CIFS_MOUNT_NO_HANDLE_CACHE | \ 623 CIFS_MOUNT_UID_FROM_ACL | CIFS_MOUNT_NO_HANDLE_CACHE | \
623 CIFS_MOUNT_NO_DFS | CIFS_MOUNT_MODE_FROM_SID) 624 CIFS_MOUNT_NO_DFS | CIFS_MOUNT_MODE_FROM_SID | \
625 CIFS_MOUNT_RO_CACHE)
624 626
625/** 627/**
626 * Generic VFS superblock mount flags (s_flags) to consider when 628 * Generic VFS superblock mount flags (s_flags) to consider when
@@ -1366,7 +1368,7 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file);
1366#define CIFS_CACHE_RW_FLG (CIFS_CACHE_READ_FLG | CIFS_CACHE_WRITE_FLG) 1368#define CIFS_CACHE_RW_FLG (CIFS_CACHE_READ_FLG | CIFS_CACHE_WRITE_FLG)
1367#define CIFS_CACHE_RHW_FLG (CIFS_CACHE_RW_FLG | CIFS_CACHE_HANDLE_FLG) 1369#define CIFS_CACHE_RHW_FLG (CIFS_CACHE_RW_FLG | CIFS_CACHE_HANDLE_FLG)
1368 1370
1369#define CIFS_CACHE_READ(cinode) (cinode->oplock & CIFS_CACHE_READ_FLG) 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))
1370#define CIFS_CACHE_HANDLE(cinode) (cinode->oplock & CIFS_CACHE_HANDLE_FLG) 1372#define CIFS_CACHE_HANDLE(cinode) (cinode->oplock & CIFS_CACHE_HANDLE_FLG)
1371#define CIFS_CACHE_WRITE(cinode) (cinode->oplock & CIFS_CACHE_WRITE_FLG) 1373#define CIFS_CACHE_WRITE(cinode) (cinode->oplock & CIFS_CACHE_WRITE_FLG)
1372 1374
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 1efbbfffddba..4e622953dd5a 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -298,6 +298,7 @@ enum {
298 Opt_cache_loose, 298 Opt_cache_loose,
299 Opt_cache_strict, 299 Opt_cache_strict,
300 Opt_cache_none, 300 Opt_cache_none,
301 Opt_cache_ro,
301 Opt_cache_err 302 Opt_cache_err
302}; 303};
303 304
@@ -305,6 +306,7 @@ static const match_table_t cifs_cacheflavor_tokens = {
305 { Opt_cache_loose, "loose" }, 306 { Opt_cache_loose, "loose" },
306 { Opt_cache_strict, "strict" }, 307 { Opt_cache_strict, "strict" },
307 { Opt_cache_none, "none" }, 308 { Opt_cache_none, "none" },
309 { Opt_cache_ro, "ro" },
308 { Opt_cache_err, NULL } 310 { Opt_cache_err, NULL }
309}; 311};
310 312
@@ -1418,14 +1420,22 @@ cifs_parse_cache_flavor(char *value, struct smb_vol *vol)
1418 case Opt_cache_loose: 1420 case Opt_cache_loose:
1419 vol->direct_io = false; 1421 vol->direct_io = false;
1420 vol->strict_io = false; 1422 vol->strict_io = false;
1423 vol->cache_ro = false;
1421 break; 1424 break;
1422 case Opt_cache_strict: 1425 case Opt_cache_strict:
1423 vol->direct_io = false; 1426 vol->direct_io = false;
1424 vol->strict_io = true; 1427 vol->strict_io = true;
1428 vol->cache_ro = false;
1425 break; 1429 break;
1426 case Opt_cache_none: 1430 case Opt_cache_none:
1427 vol->direct_io = true; 1431 vol->direct_io = true;
1428 vol->strict_io = false; 1432 vol->strict_io = false;
1433 vol->cache_ro = false;
1434 break;
1435 case Opt_cache_ro:
1436 vol->direct_io = false;
1437 vol->strict_io = false;
1438 vol->cache_ro = true;
1429 break; 1439 break;
1430 default: 1440 default:
1431 cifs_dbg(VFS, "bad cache= option: %s\n", value); 1441 cifs_dbg(VFS, "bad cache= option: %s\n", value);
@@ -4041,6 +4051,10 @@ int cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
4041 cifs_dbg(FYI, "mounting share using direct i/o\n"); 4051 cifs_dbg(FYI, "mounting share using direct i/o\n");
4042 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO; 4052 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
4043 } 4053 }
4054 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");
4056 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RO_CACHE;
4057 }
4044 if (pvolume_info->mfsymlinks) { 4058 if (pvolume_info->mfsymlinks) {
4045 if (pvolume_info->sfu_emul) { 4059 if (pvolume_info->sfu_emul) {
4046 /* 4060 /*