diff options
Diffstat (limited to 'fs/9p/vfs_inode.c')
-rw-r--r-- | fs/9p/vfs_inode.c | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 8a2c232f708a..7f6c67703195 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
@@ -221,6 +221,7 @@ struct inode *v9fs_alloc_inode(struct super_block *sb) | |||
221 | #endif | 221 | #endif |
222 | v9inode->writeback_fid = NULL; | 222 | v9inode->writeback_fid = NULL; |
223 | v9inode->cache_validity = 0; | 223 | v9inode->cache_validity = 0; |
224 | mutex_init(&v9inode->v_mutex); | ||
224 | return &v9inode->vfs_inode; | 225 | return &v9inode->vfs_inode; |
225 | } | 226 | } |
226 | 227 | ||
@@ -650,7 +651,9 @@ v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode, | |||
650 | /* if we are opening a file, assign the open fid to the file */ | 651 | /* if we are opening a file, assign the open fid to the file */ |
651 | if (nd && nd->flags & LOOKUP_OPEN) { | 652 | if (nd && nd->flags & LOOKUP_OPEN) { |
652 | v9inode = V9FS_I(dentry->d_inode); | 653 | v9inode = V9FS_I(dentry->d_inode); |
653 | if (v9ses->cache && !v9inode->writeback_fid) { | 654 | mutex_lock(&v9inode->v_mutex); |
655 | if (v9ses->cache && !v9inode->writeback_fid && | ||
656 | ((flags & O_ACCMODE) != O_RDONLY)) { | ||
654 | /* | 657 | /* |
655 | * clone a fid and add it to writeback_fid | 658 | * clone a fid and add it to writeback_fid |
656 | * we do it during open time instead of | 659 | * we do it during open time instead of |
@@ -661,10 +664,12 @@ v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode, | |||
661 | inode_fid = v9fs_writeback_fid(dentry); | 664 | inode_fid = v9fs_writeback_fid(dentry); |
662 | if (IS_ERR(inode_fid)) { | 665 | if (IS_ERR(inode_fid)) { |
663 | err = PTR_ERR(inode_fid); | 666 | err = PTR_ERR(inode_fid); |
667 | mutex_unlock(&v9inode->v_mutex); | ||
664 | goto error; | 668 | goto error; |
665 | } | 669 | } |
666 | v9inode->writeback_fid = (void *) inode_fid; | 670 | v9inode->writeback_fid = (void *) inode_fid; |
667 | } | 671 | } |
672 | mutex_unlock(&v9inode->v_mutex); | ||
668 | filp = lookup_instantiate_filp(nd, dentry, generic_file_open); | 673 | filp = lookup_instantiate_filp(nd, dentry, generic_file_open); |
669 | if (IS_ERR(filp)) { | 674 | if (IS_ERR(filp)) { |
670 | err = PTR_ERR(filp); | 675 | err = PTR_ERR(filp); |
@@ -931,7 +936,7 @@ v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, | |||
931 | 936 | ||
932 | P9_DPRINTK(P9_DEBUG_VFS, "dentry: %p\n", dentry); | 937 | P9_DPRINTK(P9_DEBUG_VFS, "dentry: %p\n", dentry); |
933 | err = -EPERM; | 938 | err = -EPERM; |
934 | v9ses = v9fs_inode2v9ses(dentry->d_inode); | 939 | v9ses = v9fs_dentry2v9ses(dentry); |
935 | if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) { | 940 | if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) { |
936 | generic_fillattr(dentry->d_inode, stat); | 941 | generic_fillattr(dentry->d_inode, stat); |
937 | return 0; | 942 | return 0; |
@@ -967,8 +972,12 @@ static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr) | |||
967 | struct p9_wstat wstat; | 972 | struct p9_wstat wstat; |
968 | 973 | ||
969 | P9_DPRINTK(P9_DEBUG_VFS, "\n"); | 974 | P9_DPRINTK(P9_DEBUG_VFS, "\n"); |
975 | retval = inode_change_ok(dentry->d_inode, iattr); | ||
976 | if (retval) | ||
977 | return retval; | ||
978 | |||
970 | retval = -EPERM; | 979 | retval = -EPERM; |
971 | v9ses = v9fs_inode2v9ses(dentry->d_inode); | 980 | v9ses = v9fs_dentry2v9ses(dentry); |
972 | fid = v9fs_fid_lookup(dentry); | 981 | fid = v9fs_fid_lookup(dentry); |
973 | if(IS_ERR(fid)) | 982 | if(IS_ERR(fid)) |
974 | return PTR_ERR(fid); | 983 | return PTR_ERR(fid); |
@@ -993,12 +1002,7 @@ static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr) | |||
993 | if (iattr->ia_valid & ATTR_GID) | 1002 | if (iattr->ia_valid & ATTR_GID) |
994 | wstat.n_gid = iattr->ia_gid; | 1003 | wstat.n_gid = iattr->ia_gid; |
995 | } | 1004 | } |
996 | if ((iattr->ia_valid & ATTR_SIZE) && | 1005 | |
997 | iattr->ia_size != i_size_read(dentry->d_inode)) { | ||
998 | retval = vmtruncate(dentry->d_inode, iattr->ia_size); | ||
999 | if (retval) | ||
1000 | return retval; | ||
1001 | } | ||
1002 | /* Write all dirty data */ | 1006 | /* Write all dirty data */ |
1003 | if (S_ISREG(dentry->d_inode->i_mode)) | 1007 | if (S_ISREG(dentry->d_inode->i_mode)) |
1004 | filemap_write_and_wait(dentry->d_inode->i_mapping); | 1008 | filemap_write_and_wait(dentry->d_inode->i_mapping); |
@@ -1006,6 +1010,11 @@ static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr) | |||
1006 | retval = p9_client_wstat(fid, &wstat); | 1010 | retval = p9_client_wstat(fid, &wstat); |
1007 | if (retval < 0) | 1011 | if (retval < 0) |
1008 | return retval; | 1012 | return retval; |
1013 | |||
1014 | if ((iattr->ia_valid & ATTR_SIZE) && | ||
1015 | iattr->ia_size != i_size_read(dentry->d_inode)) | ||
1016 | truncate_setsize(dentry->d_inode, iattr->ia_size); | ||
1017 | |||
1009 | v9fs_invalidate_inode_attr(dentry->d_inode); | 1018 | v9fs_invalidate_inode_attr(dentry->d_inode); |
1010 | 1019 | ||
1011 | setattr_copy(dentry->d_inode, iattr); | 1020 | setattr_copy(dentry->d_inode, iattr); |
@@ -1130,7 +1139,7 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen) | |||
1130 | 1139 | ||
1131 | P9_DPRINTK(P9_DEBUG_VFS, " %s\n", dentry->d_name.name); | 1140 | P9_DPRINTK(P9_DEBUG_VFS, " %s\n", dentry->d_name.name); |
1132 | retval = -EPERM; | 1141 | retval = -EPERM; |
1133 | v9ses = v9fs_inode2v9ses(dentry->d_inode); | 1142 | v9ses = v9fs_dentry2v9ses(dentry); |
1134 | fid = v9fs_fid_lookup(dentry); | 1143 | fid = v9fs_fid_lookup(dentry); |
1135 | if (IS_ERR(fid)) | 1144 | if (IS_ERR(fid)) |
1136 | return PTR_ERR(fid); | 1145 | return PTR_ERR(fid); |