Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+25 -3
+1
fs/cifs/cifs_fs_sb.h
··· 54 54 #define CIFS_MOUNT_NO_DFS 0x8000000 /* disable DFS resolving */ 55 55 #define CIFS_MOUNT_MODE_FROM_SID 0x10000000 /* retrieve mode from special ACE */ 56 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 59 struct cifs_sb_info { 59 60 struct rb_root tlink_tree;
+2
fs/cifs/cifsfs.c
··· 400 400 seq_puts(s, "strict"); 401 401 else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) 402 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 405 else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RO_CACHE) 404 406 seq_puts(s, "ro"); /* read only caching assumed */ 405 407 else
+3 -2
fs/cifs/cifsglob.h
··· 560 560 bool direct_io:1; 561 561 bool strict_io:1; /* strict cache behavior */ 562 562 bool cache_ro:1; 563 + bool cache_rw:1; 563 564 bool remap:1; /* set to remap seven reserved chars in filenames */ 564 565 bool sfu_remap:1; /* remap seven reserved chars ala SFU */ 565 566 bool posix_paths:1; /* unset to not ask for posix pathnames. */ ··· 623 622 CIFS_MOUNT_CIFS_BACKUPUID | CIFS_MOUNT_CIFS_BACKUPGID | \ 624 623 CIFS_MOUNT_UID_FROM_ACL | CIFS_MOUNT_NO_HANDLE_CACHE | \ 625 624 CIFS_MOUNT_NO_DFS | CIFS_MOUNT_MODE_FROM_SID | \ 626 - CIFS_MOUNT_RO_CACHE) 625 + CIFS_MOUNT_RO_CACHE | CIFS_MOUNT_RW_CACHE) 627 626 628 627 /** 629 628 * Generic VFS superblock mount flags (s_flags) to consider when ··· 1371 1370 1372 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)) 1373 1372 #define CIFS_CACHE_HANDLE(cinode) (cinode->oplock & CIFS_CACHE_HANDLE_FLG) 1374 - #define CIFS_CACHE_WRITE(cinode) (cinode->oplock & CIFS_CACHE_WRITE_FLG) 1373 + #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)) 1375 1374 1376 1375 /* 1377 1376 * One of these for each file inode
+19 -1
fs/cifs/connect.c
··· 299 299 Opt_cache_strict, 300 300 Opt_cache_none, 301 301 Opt_cache_ro, 302 + Opt_cache_rw, 302 303 Opt_cache_err 303 304 }; 304 305 ··· 308 307 { Opt_cache_strict, "strict" }, 309 308 { Opt_cache_none, "none" }, 310 309 { Opt_cache_ro, "ro" }, 310 + { Opt_cache_rw, "singleclient" }, 311 311 { Opt_cache_err, NULL } 312 312 }; 313 313 ··· 1423 1421 vol->direct_io = false; 1424 1422 vol->strict_io = false; 1425 1423 vol->cache_ro = false; 1424 + vol->cache_rw = false; 1426 1425 break; 1427 1426 case Opt_cache_strict: 1428 1427 vol->direct_io = false; 1429 1428 vol->strict_io = true; 1430 1429 vol->cache_ro = false; 1430 + vol->cache_rw = false; 1431 1431 break; 1432 1432 case Opt_cache_none: 1433 1433 vol->direct_io = true; 1434 1434 vol->strict_io = false; 1435 1435 vol->cache_ro = false; 1436 + vol->cache_rw = false; 1436 1437 break; 1437 1438 case Opt_cache_ro: 1438 1439 vol->direct_io = false; 1439 1440 vol->strict_io = false; 1440 1441 vol->cache_ro = true; 1442 + vol->cache_rw = false; 1443 + break; 1444 + case Opt_cache_rw: 1445 + vol->direct_io = false; 1446 + vol->strict_io = false; 1447 + vol->cache_ro = false; 1448 + vol->cache_rw = true; 1441 1449 break; 1442 1450 default: 1443 1451 cifs_dbg(VFS, "bad cache= option: %s\n", value); ··· 4066 4054 if (pvolume_info->cache_ro) { 4067 4055 cifs_dbg(VFS, "mounting share with read only caching. Ensure that the share will not be modified while in use.\n"); 4068 4056 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RO_CACHE; 4057 + } else if (pvolume_info->cache_rw) { 4058 + cifs_dbg(VFS, "mounting share in single client RW caching mode. Ensure that no other systems will be accessing the share.\n"); 4059 + cifs_sb->mnt_cifs_flags |= (CIFS_MOUNT_RO_CACHE | 4060 + CIFS_MOUNT_RW_CACHE); 4069 4061 } 4070 4062 if (pvolume_info->mfsymlinks) { 4071 4063 if (pvolume_info->sfu_emul) { ··· 4219 4203 if (tcon->fsDevInfo.DeviceCharacteristics & 4220 4204 FILE_READ_ONLY_DEVICE) 4221 4205 cifs_dbg(VFS, "mounted to read only share\n"); 4222 - else 4206 + else if ((cifs_sb->mnt_cifs_flags & 4207 + CIFS_MOUNT_RW_CACHE) == 0) 4223 4208 cifs_dbg(VFS, "read only mount of RW share\n"); 4209 + /* no need to log a RW mount of a typical RW share */ 4224 4210 } 4225 4211 } 4226 4212