Skip to content

Commit d9bc0d1

Browse files
committed
fs/9p: Consolidate file operations and add readahead and writeback
We had 3 different sets of file operations across 2 different protocol variants differentiated by cache which really only changed 3 functions. But the real problem is that certain file modes, mount options, and other factors weren't being considered when we decided whether or not to use caches. This consolidates all the operations and switches to conditionals within a common set to decide whether or not to do different aspects of caching. Signed-off-by: Eric Van Hensbergen <ericvh@kernel.org> Reviewed-by: Dominique Martinet <asmadeus@codewreck.org>
1 parent fe15c26 commit d9bc0d1

7 files changed

Lines changed: 89 additions & 162 deletions

File tree

fs/9p/v9fs.c

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,6 @@ enum {
3939
Opt_uname, Opt_remotename, Opt_cache, Opt_cachetag,
4040
/* Options that take no arguments */
4141
Opt_nodevmap,
42-
/* Cache options */
43-
Opt_cache_loose, Opt_fscache, Opt_mmap,
4442
/* Access options */
4543
Opt_access, Opt_posixacl,
4644
/* Lock timeout option */
@@ -58,9 +56,6 @@ static const match_table_t tokens = {
5856
{Opt_remotename, "aname=%s"},
5957
{Opt_nodevmap, "nodevmap"},
6058
{Opt_cache, "cache=%s"},
61-
{Opt_cache_loose, "loose"},
62-
{Opt_fscache, "fscache"},
63-
{Opt_mmap, "mmap"},
6459
{Opt_cachetag, "cachetag=%s"},
6560
{Opt_access, "access=%s"},
6661
{Opt_posixacl, "posixacl"},
@@ -69,10 +64,12 @@ static const match_table_t tokens = {
6964
};
7065

7166
static const char *const v9fs_cache_modes[nr__p9_cache_modes] = {
72-
[CACHE_NONE] = "none",
73-
[CACHE_MMAP] = "mmap",
74-
[CACHE_LOOSE] = "loose",
75-
[CACHE_FSCACHE] = "fscache",
67+
[CACHE_NONE] = "none",
68+
[CACHE_READAHEAD] = "readahead",
69+
[CACHE_WRITEBACK] = "writeback",
70+
[CACHE_MMAP] = "mmap",
71+
[CACHE_LOOSE] = "loose",
72+
[CACHE_FSCACHE] = "fscache",
7673
};
7774

7875
/* Interpret mount options for cache mode */
@@ -89,6 +86,12 @@ static int get_cache_mode(char *s)
8986
} else if (!strcmp(s, "mmap")) {
9087
version = CACHE_MMAP;
9188
p9_debug(P9_DEBUG_9P, "Cache mode: mmap\n");
89+
} else if (!strcmp(s, "writeback")) {
90+
version = CACHE_WRITEBACK;
91+
p9_debug(P9_DEBUG_9P, "Cache mode: writeback\n");
92+
} else if (!strcmp(s, "readahead")) {
93+
version = CACHE_READAHEAD;
94+
p9_debug(P9_DEBUG_9P, "Cache mode: readahead\n");
9295
} else if (!strcmp(s, "none")) {
9396
version = CACHE_NONE;
9497
p9_debug(P9_DEBUG_9P, "Cache mode: none\n");
@@ -266,15 +269,6 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)
266269
case Opt_nodevmap:
267270
v9ses->nodev = 1;
268271
break;
269-
case Opt_cache_loose:
270-
v9ses->cache = CACHE_LOOSE;
271-
break;
272-
case Opt_fscache:
273-
v9ses->cache = CACHE_FSCACHE;
274-
break;
275-
case Opt_mmap:
276-
v9ses->cache = CACHE_MMAP;
277-
break;
278272
case Opt_cachetag:
279273
#ifdef CONFIG_9P_FSCACHE
280274
kfree(v9ses->cachetag);

fs/9p/v9fs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ enum p9_session_flags {
5050

5151
enum p9_cache_modes {
5252
CACHE_NONE,
53+
CACHE_READAHEAD,
54+
CACHE_WRITEBACK,
5355
CACHE_MMAP,
5456
CACHE_LOOSE,
5557
CACHE_FSCACHE,

fs/9p/v9fs_vfs.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,6 @@ extern const struct file_operations v9fs_dir_operations;
3636
extern const struct file_operations v9fs_dir_operations_dotl;
3737
extern const struct dentry_operations v9fs_dentry_operations;
3838
extern const struct dentry_operations v9fs_cached_dentry_operations;
39-
extern const struct file_operations v9fs_cached_file_operations;
40-
extern const struct file_operations v9fs_cached_file_operations_dotl;
41-
extern const struct file_operations v9fs_mmap_file_operations;
42-
extern const struct file_operations v9fs_mmap_file_operations_dotl;
4339
extern struct kmem_cache *v9fs_inode_cache;
4440

4541
struct inode *v9fs_alloc_inode(struct super_block *sb);

fs/9p/vfs_dir.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -197,9 +197,9 @@ static int v9fs_dir_readdir_dotl(struct file *file, struct dir_context *ctx)
197197

198198

199199
/**
200-
* v9fs_dir_release - called on a close of a file or directory
201-
* @inode: inode of the directory
202-
* @filp: file pointer to a directory
200+
* v9fs_dir_release - close a directory or a file
201+
* @inode: inode of the directory or file
202+
* @filp: file pointer to a directory or file
203203
*
204204
*/
205205

@@ -214,7 +214,11 @@ int v9fs_dir_release(struct inode *inode, struct file *filp)
214214
fid = filp->private_data;
215215
p9_debug(P9_DEBUG_VFS, "inode: %p filp: %p fid: %d\n",
216216
inode, filp, fid ? fid->fid : -1);
217+
217218
if (fid) {
219+
if ((S_ISREG(inode->i_mode)) && (filp->f_mode & FMODE_WRITE))
220+
retval = filemap_fdatawrite(inode->i_mapping);
221+
218222
spin_lock(&inode->i_lock);
219223
hlist_del(&fid->ilist);
220224
spin_unlock(&inode->i_lock);

fs/9p/vfs_file.c

Lines changed: 20 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
#include "fid.h"
3030
#include "cache.h"
3131

32-
static const struct vm_operations_struct v9fs_file_vm_ops;
3332
static const struct vm_operations_struct v9fs_mmap_file_vm_ops;
3433

3534
/**
@@ -74,7 +73,7 @@ int v9fs_file_open(struct inode *inode, struct file *file)
7473
}
7574

7675
mutex_lock(&v9inode->v_mutex);
77-
if ((v9ses->cache) && !v9inode->writeback_fid &&
76+
if ((v9ses->cache >= CACHE_WRITEBACK) && !v9inode->writeback_fid &&
7877
((file->f_flags & O_ACCMODE) != O_RDONLY)) {
7978
/*
8079
* clone a fid and add it to writeback_fid
@@ -368,10 +367,15 @@ v9fs_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
368367
{
369368
struct p9_fid *fid = iocb->ki_filp->private_data;
370369
int ret, err = 0;
370+
struct inode *inode = file_inode(iocb->ki_filp);
371+
struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
371372

372373
p9_debug(P9_DEBUG_VFS, "count %zu offset %lld\n",
373374
iov_iter_count(to), iocb->ki_pos);
374375

376+
if (v9ses->cache > CACHE_MMAP)
377+
return generic_file_read_iter(iocb, to);
378+
375379
if (iocb->ki_filp->f_flags & O_NONBLOCK)
376380
ret = p9_client_read_once(fid, iocb->ki_pos, to, &err);
377381
else
@@ -396,6 +400,11 @@ v9fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
396400
ssize_t retval;
397401
loff_t origin;
398402
int err = 0;
403+
struct inode *inode = file_inode(iocb->ki_filp);
404+
struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
405+
406+
if (v9ses->cache >= CACHE_WRITEBACK)
407+
return generic_file_write_iter(iocb, from);
399408

400409
retval = generic_write_checks(iocb, from);
401410
if (retval <= 0)
@@ -478,25 +487,16 @@ static int
478487
v9fs_file_mmap(struct file *filp, struct vm_area_struct *vma)
479488
{
480489
int retval;
481-
482-
483-
retval = generic_file_mmap(filp, vma);
484-
if (!retval)
485-
vma->vm_ops = &v9fs_file_vm_ops;
486-
487-
return retval;
488-
}
489-
490-
static int
491-
v9fs_mmap_file_mmap(struct file *filp, struct vm_area_struct *vma)
492-
{
493-
int retval;
494-
struct inode *inode;
495-
struct v9fs_inode *v9inode;
490+
struct inode *inode = file_inode(filp);
491+
struct v9fs_inode *v9inode = V9FS_I(inode);
492+
struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
496493
struct p9_fid *fid;
497494

498-
inode = file_inode(filp);
499-
v9inode = V9FS_I(inode);
495+
if (v9ses->cache < CACHE_MMAP) {
496+
invalidate_inode_pages2(filp->f_mapping);
497+
return generic_file_readonly_mmap(filp, vma);
498+
}
499+
500500
mutex_lock(&v9inode->v_mutex);
501501
if (!v9inode->writeback_fid &&
502502
(vma->vm_flags & VM_SHARED) &&
@@ -564,35 +564,6 @@ v9fs_vm_page_mkwrite(struct vm_fault *vmf)
564564
return VM_FAULT_NOPAGE;
565565
}
566566

567-
/**
568-
* v9fs_mmap_file_read_iter - read from a file
569-
* @iocb: The operation parameters
570-
* @to: The buffer to read into
571-
*
572-
*/
573-
static ssize_t
574-
v9fs_mmap_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
575-
{
576-
/* TODO: Check if there are dirty pages */
577-
return v9fs_file_read_iter(iocb, to);
578-
}
579-
580-
/**
581-
* v9fs_mmap_file_write_iter - write to a file
582-
* @iocb: The operation parameters
583-
* @from: The data to write
584-
*
585-
*/
586-
static ssize_t
587-
v9fs_mmap_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
588-
{
589-
/*
590-
* TODO: invalidate mmaps on filp's inode between
591-
* offset and offset+count
592-
*/
593-
return v9fs_file_write_iter(iocb, from);
594-
}
595-
596567
static void v9fs_mmap_vm_close(struct vm_area_struct *vma)
597568
{
598569
struct inode *inode;
@@ -615,48 +586,13 @@ static void v9fs_mmap_vm_close(struct vm_area_struct *vma)
615586
filemap_fdatawrite_wbc(inode->i_mapping, &wbc);
616587
}
617588

618-
619-
static const struct vm_operations_struct v9fs_file_vm_ops = {
620-
.fault = filemap_fault,
621-
.map_pages = filemap_map_pages,
622-
.page_mkwrite = v9fs_vm_page_mkwrite,
623-
};
624-
625589
static const struct vm_operations_struct v9fs_mmap_file_vm_ops = {
626590
.close = v9fs_mmap_vm_close,
627591
.fault = filemap_fault,
628592
.map_pages = filemap_map_pages,
629593
.page_mkwrite = v9fs_vm_page_mkwrite,
630594
};
631595

632-
633-
const struct file_operations v9fs_cached_file_operations = {
634-
.llseek = generic_file_llseek,
635-
.read_iter = generic_file_read_iter,
636-
.write_iter = generic_file_write_iter,
637-
.open = v9fs_file_open,
638-
.release = v9fs_dir_release,
639-
.lock = v9fs_file_lock,
640-
.mmap = v9fs_file_mmap,
641-
.splice_read = generic_file_splice_read,
642-
.splice_write = iter_file_splice_write,
643-
.fsync = v9fs_file_fsync,
644-
};
645-
646-
const struct file_operations v9fs_cached_file_operations_dotl = {
647-
.llseek = generic_file_llseek,
648-
.read_iter = generic_file_read_iter,
649-
.write_iter = generic_file_write_iter,
650-
.open = v9fs_file_open,
651-
.release = v9fs_dir_release,
652-
.lock = v9fs_file_lock_dotl,
653-
.flock = v9fs_file_flock_dotl,
654-
.mmap = v9fs_file_mmap,
655-
.splice_read = generic_file_splice_read,
656-
.splice_write = iter_file_splice_write,
657-
.fsync = v9fs_file_fsync_dotl,
658-
};
659-
660596
const struct file_operations v9fs_file_operations = {
661597
.llseek = generic_file_llseek,
662598
.read_iter = v9fs_file_read_iter,
@@ -678,34 +614,7 @@ const struct file_operations v9fs_file_operations_dotl = {
678614
.release = v9fs_dir_release,
679615
.lock = v9fs_file_lock_dotl,
680616
.flock = v9fs_file_flock_dotl,
681-
.mmap = generic_file_readonly_mmap,
682-
.splice_read = generic_file_splice_read,
683-
.splice_write = iter_file_splice_write,
684-
.fsync = v9fs_file_fsync_dotl,
685-
};
686-
687-
const struct file_operations v9fs_mmap_file_operations = {
688-
.llseek = generic_file_llseek,
689-
.read_iter = v9fs_mmap_file_read_iter,
690-
.write_iter = v9fs_mmap_file_write_iter,
691-
.open = v9fs_file_open,
692-
.release = v9fs_dir_release,
693-
.lock = v9fs_file_lock,
694-
.mmap = v9fs_mmap_file_mmap,
695-
.splice_read = generic_file_splice_read,
696-
.splice_write = iter_file_splice_write,
697-
.fsync = v9fs_file_fsync,
698-
};
699-
700-
const struct file_operations v9fs_mmap_file_operations_dotl = {
701-
.llseek = generic_file_llseek,
702-
.read_iter = v9fs_mmap_file_read_iter,
703-
.write_iter = v9fs_mmap_file_write_iter,
704-
.open = v9fs_file_open,
705-
.release = v9fs_dir_release,
706-
.lock = v9fs_file_lock_dotl,
707-
.flock = v9fs_file_flock_dotl,
708-
.mmap = v9fs_mmap_file_mmap,
617+
.mmap = v9fs_file_mmap,
709618
.splice_read = generic_file_splice_read,
710619
.splice_write = iter_file_splice_write,
711620
.fsync = v9fs_file_fsync_dotl,

fs/9p/vfs_inode.c

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -287,24 +287,10 @@ int v9fs_init_inode(struct v9fs_session_info *v9ses,
287287
case S_IFREG:
288288
if (v9fs_proto_dotl(v9ses)) {
289289
inode->i_op = &v9fs_file_inode_operations_dotl;
290-
if (v9ses->cache == CACHE_LOOSE ||
291-
v9ses->cache == CACHE_FSCACHE)
292-
inode->i_fop =
293-
&v9fs_cached_file_operations_dotl;
294-
else if (v9ses->cache == CACHE_MMAP)
295-
inode->i_fop = &v9fs_mmap_file_operations_dotl;
296-
else
297-
inode->i_fop = &v9fs_file_operations_dotl;
290+
inode->i_fop = &v9fs_file_operations_dotl;
298291
} else {
299292
inode->i_op = &v9fs_file_inode_operations;
300-
if (v9ses->cache == CACHE_LOOSE ||
301-
v9ses->cache == CACHE_FSCACHE)
302-
inode->i_fop =
303-
&v9fs_cached_file_operations;
304-
else if (v9ses->cache == CACHE_MMAP)
305-
inode->i_fop = &v9fs_mmap_file_operations;
306-
else
307-
inode->i_fop = &v9fs_file_operations;
293+
inode->i_fop = &v9fs_file_operations;
308294
}
309295

310296
break;
@@ -843,7 +829,7 @@ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry,
843829
inode = d_inode(dentry);
844830
v9inode = V9FS_I(inode);
845831
mutex_lock(&v9inode->v_mutex);
846-
if ((v9ses->cache) && !v9inode->writeback_fid &&
832+
if ((v9ses->cache >= CACHE_WRITEBACK) && !v9inode->writeback_fid &&
847833
((flags & O_ACCMODE) != O_RDONLY)) {
848834
/*
849835
* clone a fid and add it to writeback_fid
@@ -1030,6 +1016,7 @@ v9fs_vfs_getattr(struct mnt_idmap *idmap, const struct path *path,
10301016
struct kstat *stat, u32 request_mask, unsigned int flags)
10311017
{
10321018
struct dentry *dentry = path->dentry;
1019+
struct inode *inode = d_inode(dentry);
10331020
struct v9fs_session_info *v9ses;
10341021
struct p9_fid *fid;
10351022
struct p9_wstat *st;
@@ -1039,6 +1026,14 @@ v9fs_vfs_getattr(struct mnt_idmap *idmap, const struct path *path,
10391026
if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
10401027
generic_fillattr(&nop_mnt_idmap, d_inode(dentry), stat);
10411028
return 0;
1029+
} else if (v9ses->cache >= CACHE_WRITEBACK) {
1030+
if (S_ISREG(inode->i_mode)) {
1031+
int retval = filemap_fdatawrite(inode->i_mapping);
1032+
1033+
if (retval)
1034+
p9_debug(P9_DEBUG_ERROR,
1035+
"flushing writeback during getattr returned %d\n", retval);
1036+
}
10421037
}
10431038
fid = v9fs_fid_lookup(dentry);
10441039
if (IS_ERR(fid))
@@ -1115,8 +1110,12 @@ static int v9fs_vfs_setattr(struct mnt_idmap *idmap,
11151110
}
11161111

11171112
/* Write all dirty data */
1118-
if (d_is_reg(dentry))
1119-
filemap_write_and_wait(inode->i_mapping);
1113+
if (d_is_reg(dentry)) {
1114+
retval = filemap_fdatawrite(inode->i_mapping);
1115+
if (retval)
1116+
p9_debug(P9_DEBUG_ERROR,
1117+
"flushing writeback during setattr returned %d\n", retval);
1118+
}
11201119

11211120
retval = p9_client_wstat(fid, &wstat);
11221121

@@ -1127,9 +1126,12 @@ static int v9fs_vfs_setattr(struct mnt_idmap *idmap,
11271126
return retval;
11281127

11291128
if ((iattr->ia_valid & ATTR_SIZE) &&
1130-
iattr->ia_size != i_size_read(inode)) {
1129+
iattr->ia_size != i_size_read(inode)) {
11311130
truncate_setsize(inode, iattr->ia_size);
1132-
fscache_resize_cookie(v9fs_inode_cookie(v9inode), iattr->ia_size);
1131+
if (v9ses->cache == CACHE_FSCACHE)
1132+
fscache_resize_cookie(v9fs_inode_cookie(v9inode), iattr->ia_size);
1133+
else
1134+
invalidate_mapping_pages(&inode->i_data, 0, -1);
11331135
}
11341136

11351137
v9fs_invalidate_inode_attr(inode);

0 commit comments

Comments
 (0)