fs/9p: remove writeback fid and fix per-file modes
[linux-2.6-microblaze.git] / fs / 9p / vfs_inode.c
index 63590f5..fb5e5c0 100644 (file)
@@ -230,7 +230,6 @@ struct inode *v9fs_alloc_inode(struct super_block *sb)
        v9inode = alloc_inode_sb(sb, v9fs_inode_cache, GFP_KERNEL);
        if (!v9inode)
                return NULL;
-       v9inode->writeback_fid = NULL;
        v9inode->cache_validity = 0;
        mutex_init(&v9inode->v_mutex);
        return &v9inode->netfs.inode;
@@ -383,9 +382,6 @@ void v9fs_evict_inode(struct inode *inode)
        filemap_fdatawrite(&inode->i_data);
 
        fscache_relinquish_cookie(v9fs_inode_cookie(v9inode), false);
-       /* clunk the fid stashed in writeback_fid */
-       p9_fid_put(v9inode->writeback_fid);
-       v9inode->writeback_fid = NULL;
 }
 
 static int v9fs_test_inode(struct inode *inode, void *data)
@@ -796,9 +792,10 @@ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry,
        u32 perm;
        struct v9fs_inode *v9inode;
        struct v9fs_session_info *v9ses;
-       struct p9_fid *fid, *inode_fid;
+       struct p9_fid *fid;
        struct dentry *res = NULL;
        struct inode *inode;
+       int p9_omode;
 
        if (d_in_lookup(dentry)) {
                res = v9fs_vfs_lookup(dir, dentry, 0);
@@ -817,9 +814,14 @@ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry,
 
        v9ses = v9fs_inode2v9ses(dir);
        perm = unixmode2p9mode(v9ses, mode);
-       fid = v9fs_create(v9ses, dir, dentry, NULL, perm,
-                               v9fs_uflags2omode(flags,
-                                               v9fs_proto_dotu(v9ses)));
+       p9_omode = v9fs_uflags2omode(flags, v9fs_proto_dotu(v9ses));
+
+       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");
+       }
+       fid = v9fs_create(v9ses, dir, dentry, NULL, perm, p9_omode);
        if (IS_ERR(fid)) {
                err = PTR_ERR(fid);
                goto error;
@@ -828,25 +830,6 @@ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry,
        v9fs_invalidate_inode_attr(dir);
        inode = d_inode(dentry);
        v9inode = V9FS_I(inode);
-       mutex_lock(&v9inode->v_mutex);
-       if ((v9ses->cache >= CACHE_WRITEBACK) && !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 error;
-               }
-               v9inode->writeback_fid = (void *) inode_fid;
-       }
-       mutex_unlock(&v9inode->v_mutex);
        err = finish_open(file, dentry, generic_file_open);
        if (err)
                goto error;
@@ -855,6 +838,8 @@ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry,
        if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
                fscache_use_cookie(v9fs_inode_cookie(v9inode),
                                   file->f_mode & FMODE_WRITE);
+
+       v9fs_fid_add_modes(fid, v9ses->flags, v9ses->cache, file->f_flags);
        v9fs_open_fid_add(inode, &fid);
 
        file->f_mode |= FMODE_CREATED;
@@ -1024,7 +1009,7 @@ v9fs_vfs_getattr(struct mnt_idmap *idmap, const struct path *path,
        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) {
                if (S_ISREG(inode->i_mode)) {
@@ -1128,10 +1113,10 @@ static int v9fs_vfs_setattr(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);
-               else
-                       invalidate_mapping_pages(&inode->i_data, 0, -1);
        }
 
        v9fs_invalidate_inode_attr(inode);