diff options
-rw-r--r-- | fs/9p/v9fs.c | 30 | ||||
-rw-r--r-- | fs/9p/v9fs.h | 2 | ||||
-rw-r--r-- | fs/9p/v9fs_vfs.h | 4 | ||||
-rw-r--r-- | fs/9p/vfs_dir.c | 10 | ||||
-rw-r--r-- | fs/9p/vfs_file.c | 131 | ||||
-rw-r--r-- | fs/9p/vfs_inode.c | 44 | ||||
-rw-r--r-- | fs/9p/vfs_inode_dotl.c | 30 |
7 files changed, 89 insertions, 162 deletions
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index 61a51b90600d..a46bf9121f11 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c @@ -39,8 +39,6 @@ enum { Opt_uname, Opt_remotename, Opt_cache, Opt_cachetag, /* Options that take no arguments */ Opt_nodevmap, - /* Cache options */ - Opt_cache_loose, Opt_fscache, Opt_mmap, /* Access options */ Opt_access, Opt_posixacl, /* Lock timeout option */ @@ -58,9 +56,6 @@ static const match_table_t tokens = { {Opt_remotename, "aname=%s"}, {Opt_nodevmap, "nodevmap"}, {Opt_cache, "cache=%s"}, - {Opt_cache_loose, "loose"}, - {Opt_fscache, "fscache"}, - {Opt_mmap, "mmap"}, {Opt_cachetag, "cachetag=%s"}, {Opt_access, "access=%s"}, {Opt_posixacl, "posixacl"}, @@ -69,10 +64,12 @@ static const match_table_t tokens = { }; static const char *const v9fs_cache_modes[nr__p9_cache_modes] = { - [CACHE_NONE] = "none", - [CACHE_MMAP] = "mmap", - [CACHE_LOOSE] = "loose", - [CACHE_FSCACHE] = "fscache", + [CACHE_NONE] = "none", + [CACHE_READAHEAD] = "readahead", + [CACHE_WRITEBACK] = "writeback", + [CACHE_MMAP] = "mmap", + [CACHE_LOOSE] = "loose", + [CACHE_FSCACHE] = "fscache", }; /* Interpret mount options for cache mode */ @@ -89,6 +86,12 @@ static int get_cache_mode(char *s) } else if (!strcmp(s, "mmap")) { version = CACHE_MMAP; 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")) { + version = CACHE_READAHEAD; + p9_debug(P9_DEBUG_9P, "Cache mode: readahead\n"); } else if (!strcmp(s, "none")) { version = CACHE_NONE; 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) case Opt_nodevmap: v9ses->nodev = 1; break; - case Opt_cache_loose: - v9ses->cache = CACHE_LOOSE; - break; - case Opt_fscache: - v9ses->cache = CACHE_FSCACHE; - break; - case Opt_mmap: - v9ses->cache = CACHE_MMAP; - break; case Opt_cachetag: #ifdef CONFIG_9P_FSCACHE kfree(v9ses->cachetag); diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h index f3f74d197b5d..e5d41804b3cd 100644 --- a/fs/9p/v9fs.h +++ b/fs/9p/v9fs.h @@ -50,6 +50,8 @@ enum p9_session_flags { enum p9_cache_modes { CACHE_NONE, + CACHE_READAHEAD, + CACHE_WRITEBACK, CACHE_MMAP, CACHE_LOOSE, CACHE_FSCACHE, diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h index 75106b9f293d..cdf441f22e07 100644 --- a/fs/9p/v9fs_vfs.h +++ b/fs/9p/v9fs_vfs.h @@ -36,10 +36,6 @@ extern const struct file_operations v9fs_dir_operations; extern const struct file_operations v9fs_dir_operations_dotl; extern const struct dentry_operations v9fs_dentry_operations; extern const struct dentry_operations v9fs_cached_dentry_operations; -extern const struct file_operations v9fs_cached_file_operations; -extern const struct file_operations v9fs_cached_file_operations_dotl; -extern const struct file_operations v9fs_mmap_file_operations; -extern const struct file_operations v9fs_mmap_file_operations_dotl; extern struct kmem_cache *v9fs_inode_cache; struct inode *v9fs_alloc_inode(struct super_block *sb); diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c index 3d74b04fe0de..289b58cb896e 100644 --- a/fs/9p/vfs_dir.c +++ b/fs/9p/vfs_dir.c @@ -197,9 +197,9 @@ static int v9fs_dir_readdir_dotl(struct file *file, struct dir_context *ctx) /** - * v9fs_dir_release - called on a close of a file or directory - * @inode: inode of the directory - * @filp: file pointer to a directory + * v9fs_dir_release - close a directory or a file + * @inode: inode of the directory or file + * @filp: file pointer to a directory or file * */ @@ -214,7 +214,11 @@ int v9fs_dir_release(struct inode *inode, struct file *filp) fid = filp->private_data; p9_debug(P9_DEBUG_VFS, "inode: %p filp: %p fid: %d\n", inode, filp, fid ? fid->fid : -1); + if (fid) { + if ((S_ISREG(inode->i_mode)) && (filp->f_mode & FMODE_WRITE)) + retval = filemap_fdatawrite(inode->i_mapping); + spin_lock(&inode->i_lock); hlist_del(&fid->ilist); spin_unlock(&inode->i_lock); diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index 44c15eb2b908..cd1f3f4079d7 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c @@ -29,7 +29,6 @@ #include "fid.h" #include "cache.h" -static const struct vm_operations_struct v9fs_file_vm_ops; static const struct vm_operations_struct v9fs_mmap_file_vm_ops; /** @@ -74,7 +73,7 @@ int v9fs_file_open(struct inode *inode, struct file *file) } mutex_lock(&v9inode->v_mutex); - if ((v9ses->cache) && !v9inode->writeback_fid && + if ((v9ses->cache >= CACHE_WRITEBACK) && !v9inode->writeback_fid && ((file->f_flags & O_ACCMODE) != O_RDONLY)) { /* * clone a fid and add it to writeback_fid @@ -368,10 +367,15 @@ v9fs_file_read_iter(struct kiocb *iocb, struct iov_iter *to) { struct p9_fid *fid = iocb->ki_filp->private_data; int ret, err = 0; + struct inode *inode = file_inode(iocb->ki_filp); + struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); p9_debug(P9_DEBUG_VFS, "count %zu offset %lld\n", iov_iter_count(to), iocb->ki_pos); + if (v9ses->cache > CACHE_MMAP) + return generic_file_read_iter(iocb, to); + if (iocb->ki_filp->f_flags & O_NONBLOCK) ret = p9_client_read_once(fid, iocb->ki_pos, to, &err); else @@ -396,6 +400,11 @@ v9fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) ssize_t retval; loff_t origin; int err = 0; + struct inode *inode = file_inode(iocb->ki_filp); + struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); + + if (v9ses->cache >= CACHE_WRITEBACK) + return generic_file_write_iter(iocb, from); retval = generic_write_checks(iocb, from); if (retval <= 0) @@ -478,25 +487,16 @@ static int v9fs_file_mmap(struct file *filp, struct vm_area_struct *vma) { int retval; - - - retval = generic_file_mmap(filp, vma); - if (!retval) - vma->vm_ops = &v9fs_file_vm_ops; - - return retval; -} - -static int -v9fs_mmap_file_mmap(struct file *filp, struct vm_area_struct *vma) -{ - int retval; - struct inode *inode; - struct v9fs_inode *v9inode; + struct inode *inode = file_inode(filp); + struct v9fs_inode *v9inode = V9FS_I(inode); + struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); struct p9_fid *fid; - inode = file_inode(filp); - v9inode = V9FS_I(inode); + if (v9ses->cache < CACHE_MMAP) { + invalidate_inode_pages2(filp->f_mapping); + return generic_file_readonly_mmap(filp, vma); + } + mutex_lock(&v9inode->v_mutex); if (!v9inode->writeback_fid && (vma->vm_flags & VM_SHARED) && @@ -564,35 +564,6 @@ out_unlock: return VM_FAULT_NOPAGE; } -/** - * v9fs_mmap_file_read_iter - read from a file - * @iocb: The operation parameters - * @to: The buffer to read into - * - */ -static ssize_t -v9fs_mmap_file_read_iter(struct kiocb *iocb, struct iov_iter *to) -{ - /* TODO: Check if there are dirty pages */ - return v9fs_file_read_iter(iocb, to); -} - -/** - * v9fs_mmap_file_write_iter - write to a file - * @iocb: The operation parameters - * @from: The data to write - * - */ -static ssize_t -v9fs_mmap_file_write_iter(struct kiocb *iocb, struct iov_iter *from) -{ - /* - * TODO: invalidate mmaps on filp's inode between - * offset and offset+count - */ - return v9fs_file_write_iter(iocb, from); -} - static void v9fs_mmap_vm_close(struct vm_area_struct *vma) { struct inode *inode; @@ -615,13 +586,6 @@ static void v9fs_mmap_vm_close(struct vm_area_struct *vma) filemap_fdatawrite_wbc(inode->i_mapping, &wbc); } - -static const struct vm_operations_struct v9fs_file_vm_ops = { - .fault = filemap_fault, - .map_pages = filemap_map_pages, - .page_mkwrite = v9fs_vm_page_mkwrite, -}; - static const struct vm_operations_struct v9fs_mmap_file_vm_ops = { .close = v9fs_mmap_vm_close, .fault = filemap_fault, @@ -629,34 +593,6 @@ static const struct vm_operations_struct v9fs_mmap_file_vm_ops = { .page_mkwrite = v9fs_vm_page_mkwrite, }; - -const struct file_operations v9fs_cached_file_operations = { - .llseek = generic_file_llseek, - .read_iter = generic_file_read_iter, - .write_iter = generic_file_write_iter, - .open = v9fs_file_open, - .release = v9fs_dir_release, - .lock = v9fs_file_lock, - .mmap = v9fs_file_mmap, - .splice_read = generic_file_splice_read, - .splice_write = iter_file_splice_write, - .fsync = v9fs_file_fsync, -}; - -const struct file_operations v9fs_cached_file_operations_dotl = { - .llseek = generic_file_llseek, - .read_iter = generic_file_read_iter, - .write_iter = generic_file_write_iter, - .open = v9fs_file_open, - .release = v9fs_dir_release, - .lock = v9fs_file_lock_dotl, - .flock = v9fs_file_flock_dotl, - .mmap = v9fs_file_mmap, - .splice_read = generic_file_splice_read, - .splice_write = iter_file_splice_write, - .fsync = v9fs_file_fsync_dotl, -}; - const struct file_operations v9fs_file_operations = { .llseek = generic_file_llseek, .read_iter = v9fs_file_read_iter, @@ -678,34 +614,7 @@ const struct file_operations v9fs_file_operations_dotl = { .release = v9fs_dir_release, .lock = v9fs_file_lock_dotl, .flock = v9fs_file_flock_dotl, - .mmap = generic_file_readonly_mmap, - .splice_read = generic_file_splice_read, - .splice_write = iter_file_splice_write, - .fsync = v9fs_file_fsync_dotl, -}; - -const struct file_operations v9fs_mmap_file_operations = { - .llseek = generic_file_llseek, - .read_iter = v9fs_mmap_file_read_iter, - .write_iter = v9fs_mmap_file_write_iter, - .open = v9fs_file_open, - .release = v9fs_dir_release, - .lock = v9fs_file_lock, - .mmap = v9fs_mmap_file_mmap, - .splice_read = generic_file_splice_read, - .splice_write = iter_file_splice_write, - .fsync = v9fs_file_fsync, -}; - -const struct file_operations v9fs_mmap_file_operations_dotl = { - .llseek = generic_file_llseek, - .read_iter = v9fs_mmap_file_read_iter, - .write_iter = v9fs_mmap_file_write_iter, - .open = v9fs_file_open, - .release = v9fs_dir_release, - .lock = v9fs_file_lock_dotl, - .flock = v9fs_file_flock_dotl, - .mmap = v9fs_mmap_file_mmap, + .mmap = v9fs_file_mmap, .splice_read = generic_file_splice_read, .splice_write = iter_file_splice_write, .fsync = v9fs_file_fsync_dotl, diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 1d523bec0a94..63590f55363b 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -287,24 +287,10 @@ int v9fs_init_inode(struct v9fs_session_info *v9ses, case S_IFREG: if (v9fs_proto_dotl(v9ses)) { inode->i_op = &v9fs_file_inode_operations_dotl; - if (v9ses->cache == CACHE_LOOSE || - v9ses->cache == CACHE_FSCACHE) - inode->i_fop = - &v9fs_cached_file_operations_dotl; - else if (v9ses->cache == CACHE_MMAP) - inode->i_fop = &v9fs_mmap_file_operations_dotl; - else - inode->i_fop = &v9fs_file_operations_dotl; + inode->i_fop = &v9fs_file_operations_dotl; } else { inode->i_op = &v9fs_file_inode_operations; - if (v9ses->cache == CACHE_LOOSE || - v9ses->cache == CACHE_FSCACHE) - inode->i_fop = - &v9fs_cached_file_operations; - else if (v9ses->cache == CACHE_MMAP) - inode->i_fop = &v9fs_mmap_file_operations; - else - inode->i_fop = &v9fs_file_operations; + inode->i_fop = &v9fs_file_operations; } break; @@ -843,7 +829,7 @@ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry, inode = d_inode(dentry); v9inode = V9FS_I(inode); mutex_lock(&v9inode->v_mutex); - if ((v9ses->cache) && !v9inode->writeback_fid && + if ((v9ses->cache >= CACHE_WRITEBACK) && !v9inode->writeback_fid && ((flags & O_ACCMODE) != O_RDONLY)) { /* * clone a fid and add it to writeback_fid @@ -1030,6 +1016,7 @@ v9fs_vfs_getattr(struct mnt_idmap *idmap, const struct path *path, struct kstat *stat, u32 request_mask, unsigned int flags) { struct dentry *dentry = path->dentry; + struct inode *inode = d_inode(dentry); struct v9fs_session_info *v9ses; struct p9_fid *fid; struct p9_wstat *st; @@ -1039,6 +1026,14 @@ v9fs_vfs_getattr(struct mnt_idmap *idmap, const struct path *path, if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) { generic_fillattr(&nop_mnt_idmap, d_inode(dentry), stat); return 0; + } else if (v9ses->cache >= CACHE_WRITEBACK) { + if (S_ISREG(inode->i_mode)) { + int retval = filemap_fdatawrite(inode->i_mapping); + + if (retval) + p9_debug(P9_DEBUG_ERROR, + "flushing writeback during getattr returned %d\n", retval); + } } fid = v9fs_fid_lookup(dentry); if (IS_ERR(fid)) @@ -1115,8 +1110,12 @@ static int v9fs_vfs_setattr(struct mnt_idmap *idmap, } /* Write all dirty data */ - if (d_is_reg(dentry)) - filemap_write_and_wait(inode->i_mapping); + if (d_is_reg(dentry)) { + retval = filemap_fdatawrite(inode->i_mapping); + if (retval) + p9_debug(P9_DEBUG_ERROR, + "flushing writeback during setattr returned %d\n", retval); + } retval = p9_client_wstat(fid, &wstat); @@ -1127,9 +1126,12 @@ static int v9fs_vfs_setattr(struct mnt_idmap *idmap, return retval; if ((iattr->ia_valid & ATTR_SIZE) && - iattr->ia_size != i_size_read(inode)) { + iattr->ia_size != i_size_read(inode)) { truncate_setsize(inode, iattr->ia_size); - fscache_resize_cookie(v9fs_inode_cookie(v9inode), iattr->ia_size); + if (v9ses->cache == CACHE_FSCACHE) + fscache_resize_cookie(v9fs_inode_cookie(v9inode), iattr->ia_size); + else + invalidate_mapping_pages(&inode->i_data, 0, -1); } v9fs_invalidate_inode_attr(inode); diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c index 331ed60d8fcb..a28eb3aeab29 100644 --- a/fs/9p/vfs_inode_dotl.c +++ b/fs/9p/vfs_inode_dotl.c @@ -458,6 +458,7 @@ v9fs_vfs_getattr_dotl(struct mnt_idmap *idmap, struct dentry *dentry = path->dentry; struct v9fs_session_info *v9ses; struct p9_fid *fid; + struct inode *inode = d_inode(dentry); struct p9_stat_dotl *st; p9_debug(P9_DEBUG_VFS, "dentry: %p\n", dentry); @@ -465,6 +466,14 @@ v9fs_vfs_getattr_dotl(struct mnt_idmap *idmap, if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) { generic_fillattr(&nop_mnt_idmap, d_inode(dentry), stat); return 0; + } else if (v9ses->cache >= CACHE_WRITEBACK) { + if (S_ISREG(inode->i_mode)) { + int retval = filemap_fdatawrite(inode->i_mapping); + + if (retval) + p9_debug(P9_DEBUG_ERROR, + "flushing writeback during getattr returned %d\n", retval); + } } fid = v9fs_fid_lookup(dentry); if (IS_ERR(fid)) @@ -540,12 +549,14 @@ int v9fs_vfs_setattr_dotl(struct mnt_idmap *idmap, struct dentry *dentry, struct iattr *iattr) { int retval, use_dentry = 0; + struct inode *inode = d_inode(dentry); + struct v9fs_inode *v9inode = V9FS_I(inode); + struct v9fs_session_info *v9ses; struct p9_fid *fid = NULL; struct p9_iattr_dotl p9attr = { .uid = INVALID_UID, .gid = INVALID_GID, }; - struct inode *inode = d_inode(dentry); p9_debug(P9_DEBUG_VFS, "\n"); @@ -553,6 +564,8 @@ int v9fs_vfs_setattr_dotl(struct mnt_idmap *idmap, if (retval) return retval; + v9ses = v9fs_dentry2v9ses(dentry); + p9attr.valid = v9fs_mapped_iattr_valid(iattr->ia_valid); if (iattr->ia_valid & ATTR_MODE) p9attr.mode = iattr->ia_mode; @@ -583,8 +596,12 @@ int v9fs_vfs_setattr_dotl(struct mnt_idmap *idmap, return PTR_ERR(fid); /* Write all dirty data */ - if (S_ISREG(inode->i_mode)) - filemap_write_and_wait(inode->i_mapping); + if (S_ISREG(inode->i_mode)) { + retval = filemap_fdatawrite(inode->i_mapping); + if (retval < 0) + p9_debug(P9_DEBUG_ERROR, + "Flushing file prior to setattr failed: %d\n", retval); + } retval = p9_client_setattr(fid, &p9attr); if (retval < 0) { @@ -593,9 +610,12 @@ int v9fs_vfs_setattr_dotl(struct mnt_idmap *idmap, return retval; } - if ((iattr->ia_valid & ATTR_SIZE) && - iattr->ia_size != i_size_read(inode)) + if ((iattr->ia_valid & ATTR_SIZE) && iattr->ia_size != + i_size_read(inode)) { truncate_setsize(inode, iattr->ia_size); + if (v9ses->cache == CACHE_FSCACHE) + fscache_resize_cookie(v9fs_inode_cookie(v9inode), iattr->ia_size); + } v9fs_invalidate_inode_attr(inode); setattr_copy(&nop_mnt_idmap, inode, iattr); |