mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	9P: introduction of a new cache=mmap model.
- Add cache=mmap option - Make mmap read-write while keeping it as synchronous as possible - Build writeback fid on mmap creation if it is writable Signed-off-by: Dominique Martinet <dominique.martinet@cea.fr> Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
This commit is contained in:
		
							parent
							
								
									f94741fd28
								
							
						
					
					
						commit
						fb89b45cdf
					
				
					 8 changed files with 179 additions and 19 deletions
				
			
		| 
						 | 
					@ -56,7 +56,7 @@ enum {
 | 
				
			||||||
	/* Options that take no arguments */
 | 
						/* Options that take no arguments */
 | 
				
			||||||
	Opt_nodevmap,
 | 
						Opt_nodevmap,
 | 
				
			||||||
	/* Cache options */
 | 
						/* Cache options */
 | 
				
			||||||
	Opt_cache_loose, Opt_fscache,
 | 
						Opt_cache_loose, Opt_fscache, Opt_mmap,
 | 
				
			||||||
	/* Access options */
 | 
						/* Access options */
 | 
				
			||||||
	Opt_access, Opt_posixacl,
 | 
						Opt_access, Opt_posixacl,
 | 
				
			||||||
	/* Error token */
 | 
						/* Error token */
 | 
				
			||||||
| 
						 | 
					@ -74,6 +74,7 @@ static const match_table_t tokens = {
 | 
				
			||||||
	{Opt_cache, "cache=%s"},
 | 
						{Opt_cache, "cache=%s"},
 | 
				
			||||||
	{Opt_cache_loose, "loose"},
 | 
						{Opt_cache_loose, "loose"},
 | 
				
			||||||
	{Opt_fscache, "fscache"},
 | 
						{Opt_fscache, "fscache"},
 | 
				
			||||||
 | 
						{Opt_mmap, "mmap"},
 | 
				
			||||||
	{Opt_cachetag, "cachetag=%s"},
 | 
						{Opt_cachetag, "cachetag=%s"},
 | 
				
			||||||
	{Opt_access, "access=%s"},
 | 
						{Opt_access, "access=%s"},
 | 
				
			||||||
	{Opt_posixacl, "posixacl"},
 | 
						{Opt_posixacl, "posixacl"},
 | 
				
			||||||
| 
						 | 
					@ -91,6 +92,9 @@ static int get_cache_mode(char *s)
 | 
				
			||||||
	} else if (!strcmp(s, "fscache")) {
 | 
						} else if (!strcmp(s, "fscache")) {
 | 
				
			||||||
		version = CACHE_FSCACHE;
 | 
							version = CACHE_FSCACHE;
 | 
				
			||||||
		p9_debug(P9_DEBUG_9P, "Cache mode: fscache\n");
 | 
							p9_debug(P9_DEBUG_9P, "Cache mode: fscache\n");
 | 
				
			||||||
 | 
						} else if (!strcmp(s, "mmap")) {
 | 
				
			||||||
 | 
							version = CACHE_MMAP;
 | 
				
			||||||
 | 
							p9_debug(P9_DEBUG_9P, "Cache mode: mmap\n");
 | 
				
			||||||
	} else if (!strcmp(s, "none")) {
 | 
						} else if (!strcmp(s, "none")) {
 | 
				
			||||||
		version = CACHE_NONE;
 | 
							version = CACHE_NONE;
 | 
				
			||||||
		p9_debug(P9_DEBUG_9P, "Cache mode: none\n");
 | 
							p9_debug(P9_DEBUG_9P, "Cache mode: none\n");
 | 
				
			||||||
| 
						 | 
					@ -220,6 +224,9 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)
 | 
				
			||||||
		case Opt_fscache:
 | 
							case Opt_fscache:
 | 
				
			||||||
			v9ses->cache = CACHE_FSCACHE;
 | 
								v9ses->cache = CACHE_FSCACHE;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
							case Opt_mmap:
 | 
				
			||||||
 | 
								v9ses->cache = CACHE_MMAP;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
		case Opt_cachetag:
 | 
							case Opt_cachetag:
 | 
				
			||||||
#ifdef CONFIG_9P_FSCACHE
 | 
					#ifdef CONFIG_9P_FSCACHE
 | 
				
			||||||
			v9ses->cachetag = match_strdup(&args[0]);
 | 
								v9ses->cachetag = match_strdup(&args[0]);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -64,6 +64,7 @@ enum p9_session_flags {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum p9_cache_modes {
 | 
					enum p9_cache_modes {
 | 
				
			||||||
	CACHE_NONE,
 | 
						CACHE_NONE,
 | 
				
			||||||
 | 
						CACHE_MMAP,
 | 
				
			||||||
	CACHE_LOOSE,
 | 
						CACHE_LOOSE,
 | 
				
			||||||
	CACHE_FSCACHE,
 | 
						CACHE_FSCACHE,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -50,6 +50,8 @@ extern const struct dentry_operations v9fs_dentry_operations;
 | 
				
			||||||
extern const struct dentry_operations v9fs_cached_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;
 | 
				
			||||||
extern const struct file_operations v9fs_cached_file_operations_dotl;
 | 
					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;
 | 
					extern struct kmem_cache *v9fs_inode_cache;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct inode *v9fs_alloc_inode(struct super_block *sb);
 | 
					struct inode *v9fs_alloc_inode(struct super_block *sb);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -202,6 +202,8 @@ static int v9fs_vfs_writepage(struct page *page, struct writeback_control *wbc)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int retval;
 | 
						int retval;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p9_debug(P9_DEBUG_VFS, "page %p\n", page);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	retval = v9fs_vfs_writepage_locked(page);
 | 
						retval = v9fs_vfs_writepage_locked(page);
 | 
				
			||||||
	if (retval < 0) {
 | 
						if (retval < 0) {
 | 
				
			||||||
		if (retval == -EAGAIN) {
 | 
							if (retval == -EAGAIN) {
 | 
				
			||||||
| 
						 | 
					@ -282,6 +284,9 @@ static int v9fs_write_begin(struct file *filp, struct address_space *mapping,
 | 
				
			||||||
	pgoff_t index = pos >> PAGE_CACHE_SHIFT;
 | 
						pgoff_t index = pos >> PAGE_CACHE_SHIFT;
 | 
				
			||||||
	struct inode *inode = mapping->host;
 | 
						struct inode *inode = mapping->host;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p9_debug(P9_DEBUG_VFS, "filp %p, mapping %p\n", filp, mapping);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	v9inode = V9FS_I(inode);
 | 
						v9inode = V9FS_I(inode);
 | 
				
			||||||
start:
 | 
					start:
 | 
				
			||||||
	page = grab_cache_page_write_begin(mapping, index, flags);
 | 
						page = grab_cache_page_write_begin(mapping, index, flags);
 | 
				
			||||||
| 
						 | 
					@ -312,6 +317,8 @@ 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 inode *inode = page->mapping->host;
 | 
						struct inode *inode = page->mapping->host;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p9_debug(P9_DEBUG_VFS, "filp %p, mapping %p\n", filp, mapping);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (unlikely(copied < len)) {
 | 
						if (unlikely(copied < len)) {
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 * zero out the rest of the area
 | 
							 * zero out the rest of the area
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										140
									
								
								fs/9p/vfs_file.c
									
									
									
									
									
								
							
							
						
						
									
										140
									
								
								fs/9p/vfs_file.c
									
									
									
									
									
								
							| 
						 | 
					@ -45,6 +45,7 @@
 | 
				
			||||||
#include "cache.h"
 | 
					#include "cache.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct vm_operations_struct v9fs_file_vm_ops;
 | 
					static const struct vm_operations_struct v9fs_file_vm_ops;
 | 
				
			||||||
 | 
					static const struct vm_operations_struct v9fs_mmap_file_vm_ops;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * v9fs_file_open - open a file (or directory)
 | 
					 * v9fs_file_open - open a file (or directory)
 | 
				
			||||||
| 
						 | 
					@ -87,7 +88,8 @@ int v9fs_file_open(struct inode *inode, struct file *file)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	file->private_data = fid;
 | 
						file->private_data = fid;
 | 
				
			||||||
	mutex_lock(&v9inode->v_mutex);
 | 
						mutex_lock(&v9inode->v_mutex);
 | 
				
			||||||
	if (v9ses->cache && !v9inode->writeback_fid &&
 | 
						if ((v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) &&
 | 
				
			||||||
 | 
						    !v9inode->writeback_fid &&
 | 
				
			||||||
	    ((file->f_flags & O_ACCMODE) != O_RDONLY)) {
 | 
						    ((file->f_flags & O_ACCMODE) != O_RDONLY)) {
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 * clone a fid and add it to writeback_fid
 | 
							 * clone a fid and add it to writeback_fid
 | 
				
			||||||
| 
						 | 
					@ -105,7 +107,7 @@ int v9fs_file_open(struct inode *inode, struct file *file)
 | 
				
			||||||
		v9inode->writeback_fid = (void *) fid;
 | 
							v9inode->writeback_fid = (void *) fid;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	mutex_unlock(&v9inode->v_mutex);
 | 
						mutex_unlock(&v9inode->v_mutex);
 | 
				
			||||||
	if (v9ses->cache)
 | 
						if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
 | 
				
			||||||
		v9fs_cache_inode_set_cookie(inode, file);
 | 
							v9fs_cache_inode_set_cookie(inode, file);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
out_error:
 | 
					out_error:
 | 
				
			||||||
| 
						 | 
					@ -579,17 +581,55 @@ int v9fs_file_fsync_dotl(struct file *filp, loff_t start, loff_t end,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
v9fs_file_mmap(struct file *file, struct vm_area_struct *vma)
 | 
					v9fs_file_mmap(struct file *filp, struct vm_area_struct *vma)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int retval;
 | 
						int retval;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	retval = generic_file_mmap(file, vma);
 | 
					
 | 
				
			||||||
 | 
						retval = generic_file_mmap(filp, vma);
 | 
				
			||||||
	if (!retval)
 | 
						if (!retval)
 | 
				
			||||||
		vma->vm_ops = &v9fs_file_vm_ops;
 | 
							vma->vm_ops = &v9fs_file_vm_ops;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return retval;
 | 
						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 p9_fid *fid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						inode = file_inode(filp);
 | 
				
			||||||
 | 
						v9inode = V9FS_I(inode);
 | 
				
			||||||
 | 
						mutex_lock(&v9inode->v_mutex);
 | 
				
			||||||
 | 
						if (!v9inode->writeback_fid &&
 | 
				
			||||||
 | 
						    (vma->vm_flags & VM_WRITE)) {
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * clone a fid and add it to writeback_fid
 | 
				
			||||||
 | 
							 * we do it during mmap instead of
 | 
				
			||||||
 | 
							 * page dirty time via write_begin/page_mkwrite
 | 
				
			||||||
 | 
							 * because we want write after unlink usecase
 | 
				
			||||||
 | 
							 * to work.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							fid = v9fs_writeback_fid(filp->f_path.dentry);
 | 
				
			||||||
 | 
							if (IS_ERR(fid)) {
 | 
				
			||||||
 | 
								retval = PTR_ERR(fid);
 | 
				
			||||||
 | 
								mutex_unlock(&v9inode->v_mutex);
 | 
				
			||||||
 | 
								return retval;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							v9inode->writeback_fid = (void *) fid;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						mutex_unlock(&v9inode->v_mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						retval = generic_file_mmap(filp, vma);
 | 
				
			||||||
 | 
						if (!retval)
 | 
				
			||||||
 | 
							vma->vm_ops = &v9fs_mmap_file_vm_ops;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return retval;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
v9fs_vm_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
 | 
					v9fs_vm_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -658,6 +698,22 @@ v9fs_cached_file_read(struct file *filp, char __user *data, size_t count,
 | 
				
			||||||
	return do_sync_read(filp, data, count, offset);
 | 
						return do_sync_read(filp, data, count, offset);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * v9fs_mmap_file_read - read from a file
 | 
				
			||||||
 | 
					 * @filp: file pointer to read
 | 
				
			||||||
 | 
					 * @udata: user data buffer to read data into
 | 
				
			||||||
 | 
					 * @count: size of buffer
 | 
				
			||||||
 | 
					 * @offset: offset at which to read data
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static ssize_t
 | 
				
			||||||
 | 
					v9fs_mmap_file_read(struct file *filp, char __user *data, size_t count,
 | 
				
			||||||
 | 
							      loff_t *offset)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* TODO: Check if there are dirty pages */
 | 
				
			||||||
 | 
						return v9fs_file_read(filp, data, count, offset);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static ssize_t
 | 
					static ssize_t
 | 
				
			||||||
v9fs_direct_write(struct file *filp, const char __user * data,
 | 
					v9fs_direct_write(struct file *filp, const char __user * data,
 | 
				
			||||||
		  size_t count, loff_t *offsetp)
 | 
							  size_t count, loff_t *offsetp)
 | 
				
			||||||
| 
						 | 
					@ -728,12 +784,65 @@ v9fs_cached_file_write(struct file *filp, const char __user * data,
 | 
				
			||||||
	return do_sync_write(filp, data, count, offset);
 | 
						return do_sync_write(filp, data, count, offset);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * v9fs_mmap_file_write - write to a file
 | 
				
			||||||
 | 
					 * @filp: file pointer to write
 | 
				
			||||||
 | 
					 * @data: data buffer to write data from
 | 
				
			||||||
 | 
					 * @count: size of buffer
 | 
				
			||||||
 | 
					 * @offset: offset at which to write data
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static ssize_t
 | 
				
			||||||
 | 
					v9fs_mmap_file_write(struct file *filp, const char __user *data,
 | 
				
			||||||
 | 
							       size_t count, loff_t *offset)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * TODO: invalidate mmaps on filp's inode between
 | 
				
			||||||
 | 
						 * offset and offset+count
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						return v9fs_file_write(filp, data, count, offset);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void v9fs_mmap_vm_close(struct vm_area_struct *vma)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct inode *inode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct writeback_control wbc = {
 | 
				
			||||||
 | 
							.nr_to_write = LONG_MAX,
 | 
				
			||||||
 | 
							.sync_mode = WB_SYNC_ALL,
 | 
				
			||||||
 | 
							.range_start = vma->vm_pgoff * PAGE_SIZE,
 | 
				
			||||||
 | 
							 /* absolute end, byte at end included */
 | 
				
			||||||
 | 
							.range_end = vma->vm_pgoff * PAGE_SIZE +
 | 
				
			||||||
 | 
								(vma->vm_end - vma->vm_start - 1),
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p9_debug(P9_DEBUG_VFS, "9p VMA close, %p, flushing", vma);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						inode = file_inode(vma->vm_file);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!mapping_cap_writeback_dirty(inode->i_mapping))
 | 
				
			||||||
 | 
							wbc.nr_to_write = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						might_sleep();
 | 
				
			||||||
 | 
						sync_inode(inode, &wbc);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct vm_operations_struct v9fs_file_vm_ops = {
 | 
					static const struct vm_operations_struct v9fs_file_vm_ops = {
 | 
				
			||||||
	.fault = filemap_fault,
 | 
						.fault = filemap_fault,
 | 
				
			||||||
	.page_mkwrite = v9fs_vm_page_mkwrite,
 | 
						.page_mkwrite = v9fs_vm_page_mkwrite,
 | 
				
			||||||
	.remap_pages = generic_file_remap_pages,
 | 
						.remap_pages = generic_file_remap_pages,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct vm_operations_struct v9fs_mmap_file_vm_ops = {
 | 
				
			||||||
 | 
						.close = v9fs_mmap_vm_close,
 | 
				
			||||||
 | 
						.fault = filemap_fault,
 | 
				
			||||||
 | 
						.page_mkwrite = v9fs_vm_page_mkwrite,
 | 
				
			||||||
 | 
						.remap_pages = generic_file_remap_pages,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const struct file_operations v9fs_cached_file_operations = {
 | 
					const struct file_operations v9fs_cached_file_operations = {
 | 
				
			||||||
	.llseek = generic_file_llseek,
 | 
						.llseek = generic_file_llseek,
 | 
				
			||||||
| 
						 | 
					@ -784,3 +893,26 @@ const struct file_operations v9fs_file_operations_dotl = {
 | 
				
			||||||
	.mmap = generic_file_readonly_mmap,
 | 
						.mmap = generic_file_readonly_mmap,
 | 
				
			||||||
	.fsync = v9fs_file_fsync_dotl,
 | 
						.fsync = v9fs_file_fsync_dotl,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct file_operations v9fs_mmap_file_operations = {
 | 
				
			||||||
 | 
						.llseek = generic_file_llseek,
 | 
				
			||||||
 | 
						.read = v9fs_mmap_file_read,
 | 
				
			||||||
 | 
						.write = v9fs_mmap_file_write,
 | 
				
			||||||
 | 
						.open = v9fs_file_open,
 | 
				
			||||||
 | 
						.release = v9fs_dir_release,
 | 
				
			||||||
 | 
						.lock = v9fs_file_lock,
 | 
				
			||||||
 | 
						.mmap = v9fs_mmap_file_mmap,
 | 
				
			||||||
 | 
						.fsync = v9fs_file_fsync,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct file_operations v9fs_mmap_file_operations_dotl = {
 | 
				
			||||||
 | 
						.llseek = generic_file_llseek,
 | 
				
			||||||
 | 
						.read = v9fs_mmap_file_read,
 | 
				
			||||||
 | 
						.write = v9fs_mmap_file_write,
 | 
				
			||||||
 | 
						.open = v9fs_file_open,
 | 
				
			||||||
 | 
						.release = v9fs_dir_release,
 | 
				
			||||||
 | 
						.lock = v9fs_file_lock_dotl,
 | 
				
			||||||
 | 
						.flock = v9fs_file_flock_dotl,
 | 
				
			||||||
 | 
						.mmap = v9fs_mmap_file_mmap,
 | 
				
			||||||
 | 
						.fsync = v9fs_file_fsync_dotl,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -299,15 +299,22 @@ int v9fs_init_inode(struct v9fs_session_info *v9ses,
 | 
				
			||||||
	case S_IFREG:
 | 
						case S_IFREG:
 | 
				
			||||||
		if (v9fs_proto_dotl(v9ses)) {
 | 
							if (v9fs_proto_dotl(v9ses)) {
 | 
				
			||||||
			inode->i_op = &v9fs_file_inode_operations_dotl;
 | 
								inode->i_op = &v9fs_file_inode_operations_dotl;
 | 
				
			||||||
			if (v9ses->cache)
 | 
								if (v9ses->cache == CACHE_LOOSE ||
 | 
				
			||||||
 | 
								    v9ses->cache == CACHE_FSCACHE)
 | 
				
			||||||
				inode->i_fop =
 | 
									inode->i_fop =
 | 
				
			||||||
					&v9fs_cached_file_operations_dotl;
 | 
										&v9fs_cached_file_operations_dotl;
 | 
				
			||||||
 | 
								else if (v9ses->cache == CACHE_MMAP)
 | 
				
			||||||
 | 
									inode->i_fop = &v9fs_mmap_file_operations_dotl;
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
				inode->i_fop = &v9fs_file_operations_dotl;
 | 
									inode->i_fop = &v9fs_file_operations_dotl;
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			inode->i_op = &v9fs_file_inode_operations;
 | 
								inode->i_op = &v9fs_file_inode_operations;
 | 
				
			||||||
			if (v9ses->cache)
 | 
								if (v9ses->cache == CACHE_LOOSE ||
 | 
				
			||||||
				inode->i_fop = &v9fs_cached_file_operations;
 | 
								    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
 | 
								else
 | 
				
			||||||
				inode->i_fop = &v9fs_file_operations;
 | 
									inode->i_fop = &v9fs_file_operations;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -810,7 +817,7 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
 | 
				
			||||||
	 * unlink. For cached mode create calls request for new
 | 
						 * unlink. For cached mode create calls request for new
 | 
				
			||||||
	 * inode. But with cache disabled, lookup should do this.
 | 
						 * inode. But with cache disabled, lookup should do this.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (v9ses->cache)
 | 
						if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
 | 
				
			||||||
		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);
 | 
				
			||||||
| 
						 | 
					@ -876,7 +883,8 @@ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry,
 | 
				
			||||||
	v9fs_invalidate_inode_attr(dir);
 | 
						v9fs_invalidate_inode_attr(dir);
 | 
				
			||||||
	v9inode = V9FS_I(dentry->d_inode);
 | 
						v9inode = V9FS_I(dentry->d_inode);
 | 
				
			||||||
	mutex_lock(&v9inode->v_mutex);
 | 
						mutex_lock(&v9inode->v_mutex);
 | 
				
			||||||
	if (v9ses->cache && !v9inode->writeback_fid &&
 | 
						if ((v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) &&
 | 
				
			||||||
 | 
						    !v9inode->writeback_fid &&
 | 
				
			||||||
	    ((flags & O_ACCMODE) != O_RDONLY)) {
 | 
						    ((flags & O_ACCMODE) != O_RDONLY)) {
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 * clone a fid and add it to writeback_fid
 | 
							 * clone a fid and add it to writeback_fid
 | 
				
			||||||
| 
						 | 
					@ -899,7 +907,7 @@ 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)
 | 
						if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
 | 
				
			||||||
		v9fs_cache_inode_set_cookie(dentry->d_inode, file);
 | 
							v9fs_cache_inode_set_cookie(dentry->d_inode, file);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	*opened |= FILE_CREATED;
 | 
						*opened |= FILE_CREATED;
 | 
				
			||||||
| 
						 | 
					@ -1477,7 +1485,7 @@ int v9fs_refresh_inode(struct p9_fid *fid, struct inode *inode)
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	i_size = inode->i_size;
 | 
						i_size = inode->i_size;
 | 
				
			||||||
	v9fs_stat2inode(st, inode, inode->i_sb);
 | 
						v9fs_stat2inode(st, inode, inode->i_sb);
 | 
				
			||||||
	if (v9ses->cache)
 | 
						if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
 | 
				
			||||||
		inode->i_size = i_size;
 | 
							inode->i_size = i_size;
 | 
				
			||||||
	spin_unlock(&inode->i_lock);
 | 
						spin_unlock(&inode->i_lock);
 | 
				
			||||||
out:
 | 
					out:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -330,7 +330,8 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	v9inode = V9FS_I(inode);
 | 
						v9inode = V9FS_I(inode);
 | 
				
			||||||
	mutex_lock(&v9inode->v_mutex);
 | 
						mutex_lock(&v9inode->v_mutex);
 | 
				
			||||||
	if (v9ses->cache && !v9inode->writeback_fid &&
 | 
						if ((v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) &&
 | 
				
			||||||
 | 
						    !v9inode->writeback_fid &&
 | 
				
			||||||
	    ((flags & O_ACCMODE) != O_RDONLY)) {
 | 
						    ((flags & O_ACCMODE) != O_RDONLY)) {
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 * clone a fid and add it to writeback_fid
 | 
							 * clone a fid and add it to writeback_fid
 | 
				
			||||||
| 
						 | 
					@ -353,7 +354,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
 | 
				
			||||||
	if (err)
 | 
						if (err)
 | 
				
			||||||
		goto err_clunk_old_fid;
 | 
							goto err_clunk_old_fid;
 | 
				
			||||||
	file->private_data = ofid;
 | 
						file->private_data = ofid;
 | 
				
			||||||
	if (v9ses->cache)
 | 
						if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
 | 
				
			||||||
		v9fs_cache_inode_set_cookie(inode, file);
 | 
							v9fs_cache_inode_set_cookie(inode, file);
 | 
				
			||||||
	*opened |= FILE_CREATED;
 | 
						*opened |= FILE_CREATED;
 | 
				
			||||||
out:
 | 
					out:
 | 
				
			||||||
| 
						 | 
					@ -710,7 +711,7 @@ v9fs_vfs_symlink_dotl(struct inode *dir, struct dentry *dentry,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	v9fs_invalidate_inode_attr(dir);
 | 
						v9fs_invalidate_inode_attr(dir);
 | 
				
			||||||
	if (v9ses->cache) {
 | 
						if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
 | 
				
			||||||
		/* 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)) {
 | 
				
			||||||
| 
						 | 
					@ -965,7 +966,7 @@ int v9fs_refresh_inode_dotl(struct p9_fid *fid, struct inode *inode)
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	i_size = inode->i_size;
 | 
						i_size = inode->i_size;
 | 
				
			||||||
	v9fs_stat2inode_dotl(st, inode);
 | 
						v9fs_stat2inode_dotl(st, inode);
 | 
				
			||||||
	if (v9ses->cache)
 | 
						if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
 | 
				
			||||||
		inode->i_size = i_size;
 | 
							inode->i_size = i_size;
 | 
				
			||||||
	spin_unlock(&inode->i_lock);
 | 
						spin_unlock(&inode->i_lock);
 | 
				
			||||||
out:
 | 
					out:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -144,7 +144,7 @@ static struct dentry *v9fs_mount(struct file_system_type *fs_type, int flags,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	v9fs_fill_super(sb, v9ses, flags, data);
 | 
						v9fs_fill_super(sb, v9ses, flags, data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (v9ses->cache)
 | 
						if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
 | 
				
			||||||
		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;
 | 
				
			||||||
| 
						 | 
					@ -282,7 +282,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)
 | 
						if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
 | 
				
			||||||
		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
 | 
				
			||||||
| 
						 | 
					@ -325,10 +325,12 @@ static int v9fs_write_inode_dotl(struct inode *inode,
 | 
				
			||||||
	 * send an fsync request to server irrespective of
 | 
						 * send an fsync request to server irrespective of
 | 
				
			||||||
	 * wbc->sync_mode.
 | 
						 * wbc->sync_mode.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	p9_debug(P9_DEBUG_VFS, "%s: inode %p\n", __func__, inode);
 | 
					 | 
				
			||||||
	v9inode = V9FS_I(inode);
 | 
						v9inode = V9FS_I(inode);
 | 
				
			||||||
 | 
						p9_debug(P9_DEBUG_VFS, "%s: inode %p, writeback_fid %p\n",
 | 
				
			||||||
 | 
							 __func__, inode, v9inode->writeback_fid);
 | 
				
			||||||
	if (!v9inode->writeback_fid)
 | 
						if (!v9inode->writeback_fid)
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = p9_client_fsync(v9inode->writeback_fid, 0);
 | 
						ret = p9_client_fsync(v9inode->writeback_fid, 0);
 | 
				
			||||||
	if (ret < 0) {
 | 
						if (ret < 0) {
 | 
				
			||||||
		__mark_inode_dirty(inode, I_DIRTY_DATASYNC);
 | 
							__mark_inode_dirty(inode, I_DIRTY_DATASYNC);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue