diff options
Diffstat (limited to 'fs/9p/vfs_inode_dotl.c')
-rw-r--r-- | fs/9p/vfs_inode_dotl.c | 48 |
1 files changed, 19 insertions, 29 deletions
diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c index a28eb3aeab29..4b9488cb7a56 100644 --- a/fs/9p/vfs_inode_dotl.c +++ b/fs/9p/vfs_inode_dotl.c @@ -232,12 +232,12 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry, int err = 0; kgid_t gid; umode_t mode; + int p9_omode = v9fs_open_to_dotl_flags(flags); const unsigned char *name = NULL; struct p9_qid qid; struct inode *inode; struct p9_fid *fid = NULL; - struct v9fs_inode *v9inode; - struct p9_fid *dfid = NULL, *ofid = NULL, *inode_fid = NULL; + struct p9_fid *dfid = NULL, *ofid = NULL; struct v9fs_session_info *v9ses; struct posix_acl *pacl = NULL, *dacl = NULL; struct dentry *res = NULL; @@ -282,14 +282,19 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry, /* Update mode based on ACL value */ err = v9fs_acl_mode(dir, &mode, &dacl, &pacl); if (err) { - p9_debug(P9_DEBUG_VFS, "Failed to get acl values in creat %d\n", + p9_debug(P9_DEBUG_VFS, "Failed to get acl values in create %d\n", err); goto out; } - err = p9_client_create_dotl(ofid, name, v9fs_open_to_dotl_flags(flags), - mode, gid, &qid); + + if ((v9ses->cache >= CACHE_WRITEBACK) && (p9_omode & P9_OWRITE)) { + p9_omode = (p9_omode & !P9_OWRITE) | P9_ORDWR; + p9_debug(P9_DEBUG_CACHE, + "write-only file with writeback enabled, creating w/ O_RDWR\n"); + } + err = p9_client_create_dotl(ofid, name, p9_omode, mode, gid, &qid); if (err < 0) { - p9_debug(P9_DEBUG_VFS, "p9_client_open_dotl failed in creat %d\n", + p9_debug(P9_DEBUG_VFS, "p9_client_open_dotl failed in create %d\n", err); goto out; } @@ -314,36 +319,19 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry, v9fs_fid_add(dentry, &fid); d_instantiate(dentry, inode); - v9inode = V9FS_I(inode); - mutex_lock(&v9inode->v_mutex); - if ((v9ses->cache) && !v9inode->writeback_fid && - ((flags & O_ACCMODE) != O_RDONLY)) { - /* - * clone a fid and add it to writeback_fid - * we do it during open time instead of - * page dirty time via write_begin/page_mkwrite - * because we want write after unlink usecase - * to work. - */ - inode_fid = v9fs_writeback_fid(dentry); - if (IS_ERR(inode_fid)) { - err = PTR_ERR(inode_fid); - mutex_unlock(&v9inode->v_mutex); - goto out; - } - v9inode->writeback_fid = (void *) inode_fid; - } - mutex_unlock(&v9inode->v_mutex); /* Since we are opening a file, assign the open fid to the file */ err = finish_open(file, dentry, generic_file_open); if (err) goto out; file->private_data = ofid; #ifdef CONFIG_9P_FSCACHE - if (v9ses->cache == CACHE_FSCACHE) + if (v9ses->cache == CACHE_FSCACHE) { + struct v9fs_inode *v9inode = V9FS_I(inode); fscache_use_cookie(v9fs_inode_cookie(v9inode), file->f_mode & FMODE_WRITE); + } #endif + v9fs_fid_add_modes(ofid, v9ses->flags, v9ses->cache, flags); v9fs_open_fid_add(inode, &ofid); file->f_mode |= FMODE_CREATED; out: @@ -464,9 +452,9 @@ v9fs_vfs_getattr_dotl(struct mnt_idmap *idmap, p9_debug(P9_DEBUG_VFS, "dentry: %p\n", dentry); v9ses = v9fs_dentry2v9ses(dentry); if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) { - generic_fillattr(&nop_mnt_idmap, d_inode(dentry), stat); + generic_fillattr(&nop_mnt_idmap, inode, stat); return 0; - } else if (v9ses->cache >= CACHE_WRITEBACK) { + } else if (v9ses->cache) { if (S_ISREG(inode->i_mode)) { int retval = filemap_fdatawrite(inode->i_mapping); @@ -613,6 +601,8 @@ int v9fs_vfs_setattr_dotl(struct mnt_idmap *idmap, if ((iattr->ia_valid & ATTR_SIZE) && iattr->ia_size != i_size_read(inode)) { truncate_setsize(inode, iattr->ia_size); + truncate_pagecache(inode, iattr->ia_size); + if (v9ses->cache == CACHE_FSCACHE) fscache_resize_cookie(v9fs_inode_cookie(v9inode), iattr->ia_size); } |