diff options
Diffstat (limited to 'fs/9p/vfs_super.c')
| -rw-r--r-- | fs/9p/vfs_super.c | 109 | 
1 files changed, 87 insertions, 22 deletions
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index c55c614500a..0afd0382822 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c @@ -86,12 +86,15 @@ v9fs_fill_super(struct super_block *sb, struct v9fs_session_info *v9ses,  	} else  		sb->s_op = &v9fs_super_ops;  	sb->s_bdi = &v9ses->bdi; +	if (v9ses->cache) +		sb->s_bdi->ra_pages = (VM_MAX_READAHEAD * 1024)/PAGE_CACHE_SIZE; -	sb->s_flags = flags | MS_ACTIVE | MS_SYNCHRONOUS | MS_DIRSYNC | -	    MS_NOATIME; +	sb->s_flags |= MS_ACTIVE | MS_DIRSYNC | MS_NOATIME; +	if (!v9ses->cache) +		sb->s_flags |= MS_SYNCHRONOUS;  #ifdef CONFIG_9P_FS_POSIX_ACL -	if ((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_CLIENT) +	if ((v9ses->flags & V9FS_ACL_MASK) == V9FS_POSIX_ACL)  		sb->s_flags |= MS_POSIXACL;  #endif @@ -114,11 +117,11 @@ static struct dentry *v9fs_mount(struct file_system_type *fs_type, int flags,  	struct inode *inode = NULL;  	struct dentry *root = NULL;  	struct v9fs_session_info *v9ses = NULL; -	int mode = S_IRWXUGO | S_ISVTX; +	umode_t mode = S_IRWXUGO | S_ISVTX;  	struct p9_fid *fid;  	int retval = 0; -	P9_DPRINTK(P9_DEBUG_VFS, " \n"); +	p9_debug(P9_DEBUG_VFS, "\n");  	v9ses = kzalloc(sizeof(struct v9fs_session_info), GFP_KERNEL);  	if (!v9ses) @@ -134,22 +137,26 @@ static struct dentry *v9fs_mount(struct file_system_type *fs_type, int flags,  		goto close_session;  	} -	sb = sget(fs_type, NULL, v9fs_set_super, v9ses); +	sb = sget(fs_type, NULL, v9fs_set_super, flags, v9ses);  	if (IS_ERR(sb)) {  		retval = PTR_ERR(sb);  		goto clunk_fid;  	}  	v9fs_fill_super(sb, v9ses, flags, data); -	inode = v9fs_get_inode(sb, S_IFDIR | mode); +	if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) +		sb->s_d_op = &v9fs_cached_dentry_operations; +	else +		sb->s_d_op = &v9fs_dentry_operations; + +	inode = v9fs_get_inode(sb, S_IFDIR | mode, 0);  	if (IS_ERR(inode)) {  		retval = PTR_ERR(inode);  		goto release_sb;  	} -	root = d_alloc_root(inode); +	root = d_make_root(inode);  	if (!root) { -		iput(inode);  		retval = -ENOMEM;  		goto release_sb;  	} @@ -161,7 +168,7 @@ static struct dentry *v9fs_mount(struct file_system_type *fs_type, int flags,  			retval = PTR_ERR(st);  			goto release_sb;  		} - +		root->d_inode->i_ino = v9fs_qid2ino(&st->qid);  		v9fs_stat2inode_dotl(st, root->d_inode);  		kfree(st);  	} else { @@ -183,7 +190,7 @@ static struct dentry *v9fs_mount(struct file_system_type *fs_type, int flags,  		goto release_sb;  	v9fs_fid_add(root, fid); -	P9_DPRINTK(P9_DEBUG_VFS, " simple set mount, return 0\n"); +	p9_debug(P9_DEBUG_VFS, " simple set mount, return 0\n");  	return dget(sb->s_root);  clunk_fid: @@ -215,10 +222,7 @@ static void v9fs_kill_super(struct super_block *s)  {  	struct v9fs_session_info *v9ses = s->s_fs_info; -	P9_DPRINTK(P9_DEBUG_VFS, " %p\n", s); - -	if (s->s_root) -		v9fs_dentry_release(s->s_root);	/* clunk root */ +	p9_debug(P9_DEBUG_VFS, " %p\n", s);  	kill_anon_super(s); @@ -226,7 +230,7 @@ static void v9fs_kill_super(struct super_block *s)  	v9fs_session_close(v9ses);  	kfree(v9ses);  	s->s_fs_info = NULL; -	P9_DPRINTK(P9_DEBUG_VFS, "exiting kill_super\n"); +	p9_debug(P9_DEBUG_VFS, "exiting kill_super\n");  }  static void @@ -251,11 +255,11 @@ static int v9fs_statfs(struct dentry *dentry, struct kstatfs *buf)  		goto done;  	} -	v9ses = v9fs_inode2v9ses(dentry->d_inode); +	v9ses = v9fs_dentry2v9ses(dentry);  	if (v9fs_proto_dotl(v9ses)) {  		res = p9_client_statfs(fid, &rs);  		if (res == 0) { -			buf->f_type = V9FS_MAGIC; +			buf->f_type = rs.type;  			buf->f_bsize = rs.bsize;  			buf->f_blocks = rs.blocks;  			buf->f_bfree = rs.bfree; @@ -274,26 +278,86 @@ done:  	return res;  } +static int v9fs_drop_inode(struct inode *inode) +{ +	struct v9fs_session_info *v9ses; +	v9ses = v9fs_inode2v9ses(inode); +	if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) +		return generic_drop_inode(inode); +	/* +	 * in case of non cached mode always drop the +	 * the inode because we want the inode attribute +	 * to always match that on the server. +	 */ +	return 1; +} + +static int v9fs_write_inode(struct inode *inode, +			    struct writeback_control *wbc) +{ +	int ret; +	struct p9_wstat wstat; +	struct v9fs_inode *v9inode; +	/* +	 * send an fsync request to server irrespective of +	 * wbc->sync_mode. +	 */ +	p9_debug(P9_DEBUG_VFS, "%s: inode %p\n", __func__, inode); +	v9inode = V9FS_I(inode); +	if (!v9inode->writeback_fid) +		return 0; +	v9fs_blank_wstat(&wstat); + +	ret = p9_client_wstat(v9inode->writeback_fid, &wstat); +	if (ret < 0) { +		__mark_inode_dirty(inode, I_DIRTY_DATASYNC); +		return ret; +	} +	return 0; +} + +static int v9fs_write_inode_dotl(struct inode *inode, +				 struct writeback_control *wbc) +{ +	int ret; +	struct v9fs_inode *v9inode; +	/* +	 * send an fsync request to server irrespective of +	 * wbc->sync_mode. +	 */ +	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) +		return 0; + +	ret = p9_client_fsync(v9inode->writeback_fid, 0); +	if (ret < 0) { +		__mark_inode_dirty(inode, I_DIRTY_DATASYNC); +		return ret; +	} +	return 0; +} +  static const struct super_operations v9fs_super_ops = { -#ifdef CONFIG_9P_FSCACHE  	.alloc_inode = v9fs_alloc_inode,  	.destroy_inode = v9fs_destroy_inode, -#endif  	.statfs = simple_statfs,  	.evict_inode = v9fs_evict_inode,  	.show_options = generic_show_options,  	.umount_begin = v9fs_umount_begin, +	.write_inode = v9fs_write_inode,  };  static const struct super_operations v9fs_super_ops_dotl = { -#ifdef CONFIG_9P_FSCACHE  	.alloc_inode = v9fs_alloc_inode,  	.destroy_inode = v9fs_destroy_inode, -#endif  	.statfs = v9fs_statfs, +	.drop_inode = v9fs_drop_inode,  	.evict_inode = v9fs_evict_inode,  	.show_options = generic_show_options,  	.umount_begin = v9fs_umount_begin, +	.write_inode = v9fs_write_inode_dotl,  };  struct file_system_type v9fs_fs_type = { @@ -303,3 +367,4 @@ struct file_system_type v9fs_fs_type = {  	.owner = THIS_MODULE,  	.fs_flags = FS_RENAME_DOES_D_MOVE,  }; +MODULE_ALIAS_FS("9p");  | 
