fs/9p: Rework cache modes and add new options to Documentation

Switch cache modes to a bit-mask and use legacy
cache names as shortcuts.  Update documentation to
include information on both shortcuts and bitmasks.

This patch also fixes missing guards related to fscache.

Update the documentation for new mount flags
and cache modes.

Signed-off-by: Eric Van Hensbergen <ericvh@kernel.org>
This commit is contained in:
Eric Van Hensbergen 2023-03-27 01:53:10 +00:00
parent 1543b4c507
commit 4eb3117888
No known key found for this signature in database
GPG Key ID: 88FFD5FB4A5FFF98
10 changed files with 152 additions and 106 deletions

View File

@ -78,19 +78,39 @@ Options
offering several exported file systems. offering several exported file systems.
cache=mode specifies a caching policy. By default, no caches are used. cache=mode specifies a caching policy. By default, no caches are used.
The mode can be specified as a bitmask or by using one of the
prexisting common 'shortcuts'.
The bitmask is described below: (unspecified bits are reserved)
none ========== ====================================================
default no cache policy, metadata and data 0b00000000 all caches disabled, mmap disabled
alike are synchronous. 0b00000001 file caches enabled
loose 0b00000010 meta-data caches enabled
no attempts are made at consistency, 0b00000100 writeback behavior (as opposed to writethrough)
intended for exclusive, read-only mounts 0b00001000 loose caches (no explicit consistency with server)
fscache 0b10000000 fscache enabled for persistent caching
use FS-Cache for a persistent, read-only ========== ====================================================
cache backend.
mmap The current shortcuts and their associated bitmask are:
minimal cache that is only used for read-write
mmap. Northing else is cached, like cache=none ========= ====================================================
none 0b00000000 (no caching)
readahead 0b00000001 (only read-ahead file caching)
mmap 0b00000101 (read-ahead + writeback file cache)
loose 0b00001111 (non-coherent file and meta-data caches)
fscache 0b10001111 (persistent loose cache)
========= ====================================================
NOTE: only these shortcuts are tested modes of operation at the
moment, so using other combinations of bit-patterns is not
known to work. Work on better cache support is in progress.
IMPORTANT: loose caches (and by extension at the moment fscache)
do not necessarily validate cached values on the server. In other
words changes on the server are not guaranteed to be reflected
on the client system. Only use this mode of operation if you
have an exclusive mount and the server will modify the filesystem
underneath you.
debug=n specifies debug level. The debug level is a bitmask. debug=n specifies debug level. The debug level is a bitmask.
@ -137,6 +157,10 @@ Options
This can be used to share devices/named pipes/sockets between This can be used to share devices/named pipes/sockets between
hosts. This functionality will be expanded in later versions. hosts. This functionality will be expanded in later versions.
directio bypass page cache on all read/write operations
ignoreqv ignore qid.version==0 as a marker to ignore cache
noxattr do not offer xattr functions on this mount. noxattr do not offer xattr functions on this mount.
access there are four access modes. access there are four access modes.

View File

@ -8,9 +8,8 @@
#ifndef _9P_CACHE_H #ifndef _9P_CACHE_H
#define _9P_CACHE_H #define _9P_CACHE_H
#include <linux/fscache.h>
#ifdef CONFIG_9P_FSCACHE #ifdef CONFIG_9P_FSCACHE
#include <linux/fscache.h>
extern int v9fs_cache_session_get_cookie(struct v9fs_session_info *v9ses, extern int v9fs_cache_session_get_cookie(struct v9fs_session_info *v9ses,
const char *dev_name); const char *dev_name);

View File

@ -56,11 +56,9 @@ static inline void v9fs_fid_add_modes(struct p9_fid *fid, int s_flags,
((fid->qid.version == 0) && !(s_flags & V9FS_IGNORE_QV)) || ((fid->qid.version == 0) && !(s_flags & V9FS_IGNORE_QV)) ||
(s_flags & V9FS_DIRECT_IO) || (f_flags & O_DIRECT)) { (s_flags & V9FS_DIRECT_IO) || (f_flags & O_DIRECT)) {
fid->mode |= P9L_DIRECT; /* no read or write cache */ fid->mode |= P9L_DIRECT; /* no read or write cache */
} else if ((s_cache < CACHE_WRITEBACK) || } else if ((!(s_cache & CACHE_WRITEBACK)) ||
(f_flags & O_DSYNC) | (s_flags & V9FS_SYNC)) { (f_flags & O_DSYNC) | (s_flags & V9FS_SYNC)) {
fid->mode |= P9L_NOWRITECACHE; fid->mode |= P9L_NOWRITECACHE;
} else if (s_cache == CACHE_LOOSE) {
fid->mode |= P9L_LOOSE; /* noncoherent cache */
} }
} }
#endif #endif

View File

@ -66,40 +66,30 @@ static const match_table_t tokens = {
{Opt_err, NULL} {Opt_err, NULL}
}; };
static const char *const v9fs_cache_modes[nr__p9_cache_modes] = {
[CACHE_NONE] = "none",
[CACHE_READAHEAD] = "readahead",
[CACHE_WRITEBACK] = "writeback",
[CACHE_MMAP] = "mmap",
[CACHE_LOOSE] = "loose",
[CACHE_FSCACHE] = "fscache",
};
/* Interpret mount options for cache mode */ /* Interpret mount options for cache mode */
static int get_cache_mode(char *s) static int get_cache_mode(char *s)
{ {
int version = -EINVAL; int version = -EINVAL;
if (!strcmp(s, "loose")) { if (!strcmp(s, "loose")) {
version = CACHE_LOOSE; version = CACHE_SC_LOOSE;
p9_debug(P9_DEBUG_9P, "Cache mode: loose\n"); p9_debug(P9_DEBUG_9P, "Cache mode: loose\n");
} else if (!strcmp(s, "fscache")) { } else if (!strcmp(s, "fscache")) {
version = CACHE_FSCACHE; version = CACHE_SC_FSCACHE;
p9_debug(P9_DEBUG_9P, "Cache mode: fscache\n"); p9_debug(P9_DEBUG_9P, "Cache mode: fscache\n");
} else if (!strcmp(s, "mmap")) { } else if (!strcmp(s, "mmap")) {
version = CACHE_MMAP; version = CACHE_SC_MMAP;
p9_debug(P9_DEBUG_9P, "Cache mode: mmap\n"); p9_debug(P9_DEBUG_9P, "Cache mode: mmap\n");
} else if (!strcmp(s, "writeback")) {
version = CACHE_WRITEBACK;
p9_debug(P9_DEBUG_9P, "Cache mode: writeback\n");
} else if (!strcmp(s, "readahead")) { } else if (!strcmp(s, "readahead")) {
version = CACHE_READAHEAD; version = CACHE_SC_READAHEAD;
p9_debug(P9_DEBUG_9P, "Cache mode: readahead\n"); p9_debug(P9_DEBUG_9P, "Cache mode: readahead\n");
} else if (!strcmp(s, "none")) { } else if (!strcmp(s, "none")) {
version = CACHE_NONE; version = CACHE_SC_NONE;
p9_debug(P9_DEBUG_9P, "Cache mode: none\n"); p9_debug(P9_DEBUG_9P, "Cache mode: none\n");
} else } else if (kstrtoint(s, 0, &version) != 0) {
pr_info("Unknown Cache mode %s\n", s); version = -EINVAL;
pr_info("Unknown Cache mode or invalid value %s\n", s);
}
return version; return version;
} }
@ -127,9 +117,9 @@ int v9fs_show_options(struct seq_file *m, struct dentry *root)
if (v9ses->nodev) if (v9ses->nodev)
seq_puts(m, ",nodevmap"); seq_puts(m, ",nodevmap");
if (v9ses->cache) if (v9ses->cache)
seq_printf(m, ",cache=%s", v9fs_cache_modes[v9ses->cache]); seq_printf(m, ",cache=%x", v9ses->cache);
#ifdef CONFIG_9P_FSCACHE #ifdef CONFIG_9P_FSCACHE
if (v9ses->cachetag && v9ses->cache == CACHE_FSCACHE) if (v9ses->cachetag && (v9ses->cache & CACHE_FSCACHE))
seq_printf(m, ",cachetag=%s", v9ses->cachetag); seq_printf(m, ",cachetag=%s", v9ses->cachetag);
#endif #endif
@ -481,7 +471,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
#ifdef CONFIG_9P_FSCACHE #ifdef CONFIG_9P_FSCACHE
/* register the session for caching */ /* register the session for caching */
if (v9ses->cache == CACHE_FSCACHE) { if (v9ses->cache & CACHE_FSCACHE) {
rc = v9fs_cache_session_get_cookie(v9ses, dev_name); rc = v9fs_cache_session_get_cookie(v9ses, dev_name);
if (rc < 0) if (rc < 0)
goto err_clnt; goto err_clnt;

View File

@ -31,35 +31,54 @@
#define V9FS_ACL_MASK V9FS_POSIX_ACL #define V9FS_ACL_MASK V9FS_POSIX_ACL
enum p9_session_flags { enum p9_session_flags {
V9FS_PROTO_2000U = 0x01, V9FS_PROTO_2000U = 0x01,
V9FS_PROTO_2000L = 0x02, V9FS_PROTO_2000L = 0x02,
V9FS_ACCESS_SINGLE = 0x04, V9FS_ACCESS_SINGLE = 0x04,
V9FS_ACCESS_USER = 0x08, V9FS_ACCESS_USER = 0x08,
V9FS_ACCESS_CLIENT = 0x10, V9FS_ACCESS_CLIENT = 0x10,
V9FS_POSIX_ACL = 0x20, V9FS_POSIX_ACL = 0x20,
V9FS_NO_XATTR = 0x40, V9FS_NO_XATTR = 0x40,
V9FS_IGNORE_QV = 0x80, /* ignore qid.version for cache hints */ V9FS_IGNORE_QV = 0x80, /* ignore qid.version for cache hints */
V9FS_DIRECT_IO = 0x100, V9FS_DIRECT_IO = 0x100,
V9FS_SYNC = 0x200 V9FS_SYNC = 0x200
}; };
/* possible values of ->cache */
/** /**
* enum p9_cache_modes - user specified cache preferences * enum p9_cache_shortcuts - human readable cache preferences
* @CACHE_NONE: do not cache data, dentries, or directory contents (default) * @CACHE_SC_NONE: disable all caches
* @CACHE_LOOSE: cache data, dentries, and directory contents w/no consistency * @CACHE_SC_READAHEAD: only provide caching for readahead
* @CACHE_SC_MMAP: provide caching to enable mmap
* @CACHE_SC_LOOSE: non-coherent caching for files and meta data
* @CACHE_SC_FSCACHE: persistent non-coherent caching for files and meta-data
* *
* eventually support loose, tight, time, session, default always none
*/ */
enum p9_cache_modes { enum p9_cache_shortcuts {
CACHE_NONE, CACHE_SC_NONE = 0b00000000,
CACHE_READAHEAD, CACHE_SC_READAHEAD = 0b00000001,
CACHE_WRITEBACK, CACHE_SC_MMAP = 0b00000101,
CACHE_MMAP, CACHE_SC_LOOSE = 0b00001111,
CACHE_LOOSE, CACHE_SC_FSCACHE = 0b10001111,
CACHE_FSCACHE, };
nr__p9_cache_modes
/**
* enum p9_cache_bits - possible values of ->cache
* @CACHE_NONE: caches disabled
* @CACHE_FILE: file caching (open to close)
* @CACHE_META: meta-data and directory caching
* @CACHE_WRITEBACK: write-back caching for files
* @CACHE_LOOSE: don't check cache consistency
* @CACHE_FSCACHE: local persistent caches
*
*/
enum p9_cache_bits {
CACHE_NONE = 0b00000000,
CACHE_FILE = 0b00000001,
CACHE_META = 0b00000010,
CACHE_WRITEBACK = 0b00000100,
CACHE_LOOSE = 0b00001000,
CACHE_FSCACHE = 0b10000000,
}; };
/** /**
@ -68,7 +87,7 @@ enum p9_cache_modes {
* @nodev: set to 1 to disable device mapping * @nodev: set to 1 to disable device mapping
* @debug: debug level * @debug: debug level
* @afid: authentication handle * @afid: authentication handle
* @cache: cache mode of type &p9_cache_modes * @cache: cache mode of type &p9_cache_bits
* @cachetag: the tag of the cache associated with this session * @cachetag: the tag of the cache associated with this session
* @fscache: session cookie associated with FS-Cache * @fscache: session cookie associated with FS-Cache
* @uname: string user name to mount hierarchy as * @uname: string user name to mount hierarchy as

View File

@ -115,8 +115,6 @@ const struct netfs_request_ops v9fs_req_ops = {
static bool v9fs_release_folio(struct folio *folio, gfp_t gfp) static bool v9fs_release_folio(struct folio *folio, gfp_t gfp)
{ {
struct inode *inode = folio_inode(folio);
if (folio_test_private(folio)) if (folio_test_private(folio))
return false; return false;
#ifdef CONFIG_9P_FSCACHE #ifdef CONFIG_9P_FSCACHE
@ -125,8 +123,8 @@ static bool v9fs_release_folio(struct folio *folio, gfp_t gfp)
return false; return false;
folio_wait_fscache(folio); folio_wait_fscache(folio);
} }
fscache_note_page_release(v9fs_inode_cookie(V9FS_I(folio_inode(folio))));
#endif #endif
fscache_note_page_release(v9fs_inode_cookie(V9FS_I(inode)));
return true; return true;
} }
@ -136,6 +134,7 @@ static void v9fs_invalidate_folio(struct folio *folio, size_t offset,
folio_wait_fscache(folio); folio_wait_fscache(folio);
} }
#ifdef CONFIG_9P_FSCACHE
static void v9fs_write_to_cache_done(void *priv, ssize_t transferred_or_error, static void v9fs_write_to_cache_done(void *priv, ssize_t transferred_or_error,
bool was_async) bool was_async)
{ {
@ -149,18 +148,19 @@ static void v9fs_write_to_cache_done(void *priv, ssize_t transferred_or_error,
i_size_read(&v9inode->netfs.inode), 0); i_size_read(&v9inode->netfs.inode), 0);
} }
} }
#endif
static int v9fs_vfs_write_folio_locked(struct folio *folio) static int v9fs_vfs_write_folio_locked(struct folio *folio)
{ {
struct inode *inode = folio_inode(folio); struct inode *inode = folio_inode(folio);
struct v9fs_inode *v9inode = V9FS_I(inode);
struct fscache_cookie *cookie = v9fs_inode_cookie(v9inode);
loff_t start = folio_pos(folio); loff_t start = folio_pos(folio);
loff_t i_size = i_size_read(inode); loff_t i_size = i_size_read(inode);
struct iov_iter from; struct iov_iter from;
size_t len = folio_size(folio); size_t len = folio_size(folio);
struct p9_fid *writeback_fid; struct p9_fid *writeback_fid;
int err; int err;
struct v9fs_inode __maybe_unused *v9inode = V9FS_I(inode);
struct fscache_cookie __maybe_unused *cookie = v9fs_inode_cookie(v9inode);
if (start >= i_size) if (start >= i_size)
return 0; /* Simultaneous truncation occurred */ return 0; /* Simultaneous truncation occurred */
@ -181,15 +181,17 @@ static int v9fs_vfs_write_folio_locked(struct folio *folio)
p9_client_write(writeback_fid, start, &from, &err); p9_client_write(writeback_fid, start, &from, &err);
#ifdef CONFIG_9P_FSCACHE
if (err == 0 && if (err == 0 &&
fscache_cookie_enabled(cookie) && fscache_cookie_enabled(cookie) &&
test_bit(FSCACHE_COOKIE_IS_CACHING, &cookie->flags)) { test_bit(FSCACHE_COOKIE_IS_CACHING, &cookie->flags)) {
folio_start_fscache(folio); folio_start_fscache(folio);
fscache_write_to_cache(v9fs_inode_cookie(v9inode), fscache_write_to_cache(v9fs_inode_cookie(v9inode),
folio_mapping(folio), start, len, i_size, folio_mapping(folio), start, len, i_size,
v9fs_write_to_cache_done, v9inode, v9fs_write_to_cache_done, v9inode,
true); true);
} }
#endif
folio_end_writeback(folio); folio_end_writeback(folio);
p9_fid_put(writeback_fid); p9_fid_put(writeback_fid);
@ -300,7 +302,6 @@ static int v9fs_write_end(struct file *filp, struct address_space *mapping,
loff_t last_pos = pos + copied; loff_t last_pos = pos + copied;
struct folio *folio = page_folio(subpage); struct folio *folio = page_folio(subpage);
struct inode *inode = mapping->host; struct inode *inode = mapping->host;
struct v9fs_inode *v9inode = V9FS_I(inode);
p9_debug(P9_DEBUG_VFS, "filp %p, mapping %p\n", filp, mapping); p9_debug(P9_DEBUG_VFS, "filp %p, mapping %p\n", filp, mapping);
@ -320,7 +321,10 @@ static int v9fs_write_end(struct file *filp, struct address_space *mapping,
if (last_pos > inode->i_size) { if (last_pos > inode->i_size) {
inode_add_bytes(inode, last_pos - inode->i_size); inode_add_bytes(inode, last_pos - inode->i_size);
i_size_write(inode, last_pos); i_size_write(inode, last_pos);
fscache_update_cookie(v9fs_inode_cookie(v9inode), NULL, &last_pos); #ifdef CONFIG_9P_FSCACHE
fscache_update_cookie(v9fs_inode_cookie(V9FS_I(inode)), NULL,
&last_pos);
#endif
} }
folio_mark_dirty(folio); folio_mark_dirty(folio);
out: out:

View File

@ -41,13 +41,11 @@ static const struct vm_operations_struct v9fs_mmap_file_vm_ops;
int v9fs_file_open(struct inode *inode, struct file *file) int v9fs_file_open(struct inode *inode, struct file *file)
{ {
int err; int err;
struct v9fs_inode *v9inode;
struct v9fs_session_info *v9ses; struct v9fs_session_info *v9ses;
struct p9_fid *fid; struct p9_fid *fid;
int omode; int omode;
p9_debug(P9_DEBUG_VFS, "inode: %p file: %p\n", inode, file); p9_debug(P9_DEBUG_VFS, "inode: %p file: %p\n", inode, file);
v9inode = V9FS_I(inode);
v9ses = v9fs_inode2v9ses(inode); v9ses = v9fs_inode2v9ses(inode);
if (v9fs_proto_dotl(v9ses)) if (v9fs_proto_dotl(v9ses))
omode = v9fs_open_to_dotl_flags(file->f_flags); omode = v9fs_open_to_dotl_flags(file->f_flags);
@ -60,7 +58,7 @@ int v9fs_file_open(struct inode *inode, struct file *file)
if (IS_ERR(fid)) if (IS_ERR(fid))
return PTR_ERR(fid); return PTR_ERR(fid);
if ((v9ses->cache >= CACHE_WRITEBACK) && (omode & P9_OWRITE)) { if ((v9ses->cache & CACHE_WRITEBACK) && (omode & P9_OWRITE)) {
int writeback_omode = (omode & ~P9_OWRITE) | P9_ORDWR; int writeback_omode = (omode & ~P9_OWRITE) | P9_ORDWR;
p9_debug(P9_DEBUG_CACHE, "write-only file with writeback enabled, try opening O_RDWR\n"); p9_debug(P9_DEBUG_CACHE, "write-only file with writeback enabled, try opening O_RDWR\n");
@ -85,8 +83,8 @@ int v9fs_file_open(struct inode *inode, struct file *file)
} }
#ifdef CONFIG_9P_FSCACHE #ifdef CONFIG_9P_FSCACHE
if (v9ses->cache == CACHE_FSCACHE) if (v9ses->cache & CACHE_FSCACHE)
fscache_use_cookie(v9fs_inode_cookie(v9inode), fscache_use_cookie(v9fs_inode_cookie(V9FS_I(inode)),
file->f_mode & FMODE_WRITE); file->f_mode & FMODE_WRITE);
#endif #endif
v9fs_fid_add_modes(fid, v9ses->flags, v9ses->cache, file->f_flags); v9fs_fid_add_modes(fid, v9ses->flags, v9ses->cache, file->f_flags);
@ -485,7 +483,7 @@ v9fs_file_mmap(struct file *filp, struct vm_area_struct *vma)
p9_debug(P9_DEBUG_MMAP, "filp :%p\n", filp); p9_debug(P9_DEBUG_MMAP, "filp :%p\n", filp);
if (v9ses->cache < CACHE_MMAP) { if (!(v9ses->cache & CACHE_WRITEBACK)) {
p9_debug(P9_DEBUG_CACHE, "(no mmap mode)"); p9_debug(P9_DEBUG_CACHE, "(no mmap mode)");
if (vma->vm_flags & VM_MAYSHARE) if (vma->vm_flags & VM_MAYSHARE)
return -ENODEV; return -ENODEV;

View File

@ -371,17 +371,23 @@ struct inode *v9fs_get_inode(struct super_block *sb, umode_t mode, dev_t rdev)
*/ */
void v9fs_evict_inode(struct inode *inode) void v9fs_evict_inode(struct inode *inode)
{ {
struct v9fs_inode *v9inode = V9FS_I(inode); struct v9fs_inode __maybe_unused *v9inode = V9FS_I(inode);
__le32 version; __le32 __maybe_unused version;
truncate_inode_pages_final(&inode->i_data); truncate_inode_pages_final(&inode->i_data);
#ifdef CONFIG_9P_FSCACHE
version = cpu_to_le32(v9inode->qid.version); version = cpu_to_le32(v9inode->qid.version);
fscache_clear_inode_writeback(v9fs_inode_cookie(v9inode), inode, fscache_clear_inode_writeback(v9fs_inode_cookie(v9inode), inode,
&version); &version);
#endif
clear_inode(inode); clear_inode(inode);
filemap_fdatawrite(&inode->i_data); filemap_fdatawrite(&inode->i_data);
#ifdef CONFIG_9P_FSCACHE
fscache_relinquish_cookie(v9fs_inode_cookie(v9inode), false); fscache_relinquish_cookie(v9fs_inode_cookie(v9inode), false);
#endif
} }
static int v9fs_test_inode(struct inode *inode, void *data) static int v9fs_test_inode(struct inode *inode, void *data)
@ -761,7 +767,7 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
inode = NULL; inode = NULL;
else if (IS_ERR(fid)) else if (IS_ERR(fid))
inode = ERR_CAST(fid); inode = ERR_CAST(fid);
else if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) else if (v9ses->cache & (CACHE_META|CACHE_LOOSE))
inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb); inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
else else
inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb); inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
@ -790,7 +796,7 @@ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry,
{ {
int err; int err;
u32 perm; u32 perm;
struct v9fs_inode *v9inode; struct v9fs_inode __maybe_unused *v9inode;
struct v9fs_session_info *v9ses; struct v9fs_session_info *v9ses;
struct p9_fid *fid; struct p9_fid *fid;
struct dentry *res = NULL; struct dentry *res = NULL;
@ -816,7 +822,7 @@ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry,
perm = unixmode2p9mode(v9ses, mode); perm = unixmode2p9mode(v9ses, mode);
p9_omode = v9fs_uflags2omode(flags, v9fs_proto_dotu(v9ses)); p9_omode = v9fs_uflags2omode(flags, v9fs_proto_dotu(v9ses));
if ((v9ses->cache >= CACHE_WRITEBACK) && (p9_omode & P9_OWRITE)) { if ((v9ses->cache & CACHE_WRITEBACK) && (p9_omode & P9_OWRITE)) {
p9_omode = (p9_omode & !P9_OWRITE) | P9_ORDWR; p9_omode = (p9_omode & !P9_OWRITE) | P9_ORDWR;
p9_debug(P9_DEBUG_CACHE, p9_debug(P9_DEBUG_CACHE,
"write-only file with writeback enabled, creating w/ O_RDWR\n"); "write-only file with writeback enabled, creating w/ O_RDWR\n");
@ -835,9 +841,11 @@ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry,
goto error; goto error;
file->private_data = fid; file->private_data = fid;
if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) #ifdef CONFIG_9P_FSCACHE
if (v9ses->cache & CACHE_FSCACHE)
fscache_use_cookie(v9fs_inode_cookie(v9inode), fscache_use_cookie(v9fs_inode_cookie(v9inode),
file->f_mode & FMODE_WRITE); file->f_mode & FMODE_WRITE);
#endif
v9fs_fid_add_modes(fid, v9ses->flags, v9ses->cache, file->f_flags); v9fs_fid_add_modes(fid, v9ses->flags, v9ses->cache, file->f_flags);
v9fs_open_fid_add(inode, &fid); v9fs_open_fid_add(inode, &fid);
@ -1008,10 +1016,10 @@ v9fs_vfs_getattr(struct mnt_idmap *idmap, const struct path *path,
p9_debug(P9_DEBUG_VFS, "dentry: %p\n", dentry); p9_debug(P9_DEBUG_VFS, "dentry: %p\n", dentry);
v9ses = v9fs_dentry2v9ses(dentry); v9ses = v9fs_dentry2v9ses(dentry);
if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) { if (v9ses->cache & (CACHE_META|CACHE_LOOSE)) {
generic_fillattr(&nop_mnt_idmap, inode, stat); generic_fillattr(&nop_mnt_idmap, inode, stat);
return 0; return 0;
} else if (v9ses->cache >= CACHE_WRITEBACK) { } else if (v9ses->cache & CACHE_WRITEBACK) {
if (S_ISREG(inode->i_mode)) { if (S_ISREG(inode->i_mode)) {
int retval = filemap_fdatawrite(inode->i_mapping); int retval = filemap_fdatawrite(inode->i_mapping);
@ -1050,7 +1058,6 @@ static int v9fs_vfs_setattr(struct mnt_idmap *idmap,
{ {
int retval, use_dentry = 0; int retval, use_dentry = 0;
struct inode *inode = d_inode(dentry); struct inode *inode = d_inode(dentry);
struct v9fs_inode *v9inode = V9FS_I(inode);
struct v9fs_session_info *v9ses; struct v9fs_session_info *v9ses;
struct p9_fid *fid = NULL; struct p9_fid *fid = NULL;
struct p9_wstat wstat; struct p9_wstat wstat;
@ -1115,8 +1122,13 @@ static int v9fs_vfs_setattr(struct mnt_idmap *idmap,
truncate_setsize(inode, iattr->ia_size); truncate_setsize(inode, iattr->ia_size);
truncate_pagecache(inode, iattr->ia_size); truncate_pagecache(inode, iattr->ia_size);
if (v9ses->cache == CACHE_FSCACHE) #ifdef CONFIG_9P_FSCACHE
if (v9ses->cache & CACHE_FSCACHE) {
struct v9fs_inode *v9inode = V9FS_I(inode);
fscache_resize_cookie(v9fs_inode_cookie(v9inode), iattr->ia_size); fscache_resize_cookie(v9fs_inode_cookie(v9inode), iattr->ia_size);
}
#endif
} }
v9fs_invalidate_inode_attr(inode); v9fs_invalidate_inode_attr(inode);
@ -1400,7 +1412,7 @@ int v9fs_refresh_inode(struct p9_fid *fid, struct inode *inode)
* We don't want to refresh inode->i_size, * We don't want to refresh inode->i_size,
* because we may have cached data * because we may have cached data
*/ */
flags = (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) ? flags = (v9ses->cache & CACHE_LOOSE) ?
V9FS_STAT2INODE_KEEP_ISIZE : 0; V9FS_STAT2INODE_KEEP_ISIZE : 0;
v9fs_stat2inode(st, inode, inode->i_sb, flags); v9fs_stat2inode(st, inode, inode->i_sb, flags);
out: out:

View File

@ -287,7 +287,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
goto out; goto out;
} }
if ((v9ses->cache >= CACHE_WRITEBACK) && (p9_omode & P9_OWRITE)) { if ((v9ses->cache & CACHE_WRITEBACK) && (p9_omode & P9_OWRITE)) {
p9_omode = (p9_omode & !P9_OWRITE) | P9_ORDWR; p9_omode = (p9_omode & !P9_OWRITE) | P9_ORDWR;
p9_debug(P9_DEBUG_CACHE, p9_debug(P9_DEBUG_CACHE,
"write-only file with writeback enabled, creating w/ O_RDWR\n"); "write-only file with writeback enabled, creating w/ O_RDWR\n");
@ -325,7 +325,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
goto out; goto out;
file->private_data = ofid; file->private_data = ofid;
#ifdef CONFIG_9P_FSCACHE #ifdef CONFIG_9P_FSCACHE
if (v9ses->cache == CACHE_FSCACHE) { if (v9ses->cache & CACHE_FSCACHE) {
struct v9fs_inode *v9inode = V9FS_I(inode); struct v9fs_inode *v9inode = V9FS_I(inode);
fscache_use_cookie(v9fs_inode_cookie(v9inode), fscache_use_cookie(v9fs_inode_cookie(v9inode),
file->f_mode & FMODE_WRITE); file->f_mode & FMODE_WRITE);
@ -403,7 +403,7 @@ static int v9fs_vfs_mkdir_dotl(struct mnt_idmap *idmap,
} }
/* instantiate inode and assign the unopened fid to the dentry */ /* instantiate inode and assign the unopened fid to the dentry */
if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) { if (v9ses->cache & (CACHE_META|CACHE_LOOSE)) {
inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb); inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
if (IS_ERR(inode)) { if (IS_ERR(inode)) {
err = PTR_ERR(inode); err = PTR_ERR(inode);
@ -451,7 +451,7 @@ v9fs_vfs_getattr_dotl(struct mnt_idmap *idmap,
p9_debug(P9_DEBUG_VFS, "dentry: %p\n", dentry); p9_debug(P9_DEBUG_VFS, "dentry: %p\n", dentry);
v9ses = v9fs_dentry2v9ses(dentry); v9ses = v9fs_dentry2v9ses(dentry);
if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) { if (v9ses->cache & (CACHE_META|CACHE_LOOSE)) {
generic_fillattr(&nop_mnt_idmap, inode, stat); generic_fillattr(&nop_mnt_idmap, inode, stat);
return 0; return 0;
} else if (v9ses->cache) { } else if (v9ses->cache) {
@ -538,8 +538,7 @@ int v9fs_vfs_setattr_dotl(struct mnt_idmap *idmap,
{ {
int retval, use_dentry = 0; int retval, use_dentry = 0;
struct inode *inode = d_inode(dentry); struct inode *inode = d_inode(dentry);
struct v9fs_inode *v9inode = V9FS_I(inode); struct v9fs_session_info __maybe_unused *v9ses;
struct v9fs_session_info *v9ses;
struct p9_fid *fid = NULL; struct p9_fid *fid = NULL;
struct p9_iattr_dotl p9attr = { struct p9_iattr_dotl p9attr = {
.uid = INVALID_UID, .uid = INVALID_UID,
@ -603,8 +602,11 @@ int v9fs_vfs_setattr_dotl(struct mnt_idmap *idmap,
truncate_setsize(inode, iattr->ia_size); truncate_setsize(inode, iattr->ia_size);
truncate_pagecache(inode, iattr->ia_size); truncate_pagecache(inode, iattr->ia_size);
if (v9ses->cache == CACHE_FSCACHE) #ifdef CONFIG_9P_FSCACHE
fscache_resize_cookie(v9fs_inode_cookie(v9inode), iattr->ia_size); if (v9ses->cache & CACHE_FSCACHE)
fscache_resize_cookie(v9fs_inode_cookie(V9FS_I(inode)),
iattr->ia_size);
#endif
} }
v9fs_invalidate_inode_attr(inode); v9fs_invalidate_inode_attr(inode);
@ -732,7 +734,7 @@ v9fs_vfs_symlink_dotl(struct mnt_idmap *idmap, struct inode *dir,
} }
v9fs_invalidate_inode_attr(dir); v9fs_invalidate_inode_attr(dir);
if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) { if (v9ses->cache & (CACHE_META|CACHE_LOOSE)) {
/* Now walk from the parent so we can get an unopened fid. */ /* Now walk from the parent so we can get an unopened fid. */
fid = p9_client_walk(dfid, 1, &name, 1); fid = p9_client_walk(dfid, 1, &name, 1);
if (IS_ERR(fid)) { if (IS_ERR(fid)) {
@ -809,7 +811,7 @@ v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir,
} }
v9fs_invalidate_inode_attr(dir); v9fs_invalidate_inode_attr(dir);
if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) { if (v9ses->cache & (CACHE_META|CACHE_LOOSE)) {
/* Get the latest stat info from server. */ /* Get the latest stat info from server. */
struct p9_fid *fid; struct p9_fid *fid;
@ -886,7 +888,7 @@ v9fs_vfs_mknod_dotl(struct mnt_idmap *idmap, struct inode *dir,
} }
/* instantiate inode and assign the unopened fid to the dentry */ /* instantiate inode and assign the unopened fid to the dentry */
if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) { if (v9ses->cache & (CACHE_META|CACHE_LOOSE)) {
inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb); inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
if (IS_ERR(inode)) { if (IS_ERR(inode)) {
err = PTR_ERR(inode); err = PTR_ERR(inode);
@ -971,7 +973,7 @@ int v9fs_refresh_inode_dotl(struct p9_fid *fid, struct inode *inode)
* We don't want to refresh inode->i_size, * We don't want to refresh inode->i_size,
* because we may have cached data * because we may have cached data
*/ */
flags = (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) ? flags = (v9ses->cache & CACHE_LOOSE) ?
V9FS_STAT2INODE_KEEP_ISIZE : 0; V9FS_STAT2INODE_KEEP_ISIZE : 0;
v9fs_stat2inode_dotl(st, inode, flags); v9fs_stat2inode_dotl(st, inode, flags);
out: out:

View File

@ -136,7 +136,7 @@ static struct dentry *v9fs_mount(struct file_system_type *fs_type, int flags,
if (retval) if (retval)
goto release_sb; goto release_sb;
if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) if (v9ses->cache & (CACHE_META|CACHE_LOOSE))
sb->s_d_op = &v9fs_cached_dentry_operations; sb->s_d_op = &v9fs_cached_dentry_operations;
else else
sb->s_d_op = &v9fs_dentry_operations; sb->s_d_op = &v9fs_dentry_operations;
@ -277,7 +277,7 @@ static int v9fs_drop_inode(struct inode *inode)
struct v9fs_session_info *v9ses; struct v9fs_session_info *v9ses;
v9ses = v9fs_inode2v9ses(inode); v9ses = v9fs_inode2v9ses(inode);
if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) if (v9ses->cache & (CACHE_META|CACHE_LOOSE))
return generic_drop_inode(inode); return generic_drop_inode(inode);
/* /*
* in case of non cached mode always drop the * in case of non cached mode always drop the