aboutsummaryrefslogtreecommitdiffstats
path: root/fs/9p
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2011-03-24 02:17:25 -0400
committerPaul Mundt <lethal@linux-sh.org>2011-03-24 02:17:25 -0400
commita3d3362287fbe96fe90abdb5c6d1a35471129a8c (patch)
treead3c85ed1feef470c66599eb514e30f43c2db5dd /fs/9p
parentfb7f045ace0624f1e59a7db8497e460bd54b1cbc (diff)
parent4bbba111d94781d34081c37856bbc5eb33f6c72a (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6 into sh-latest
Diffstat (limited to 'fs/9p')
-rw-r--r--fs/9p/acl.c4
-rw-r--r--fs/9p/fid.c19
-rw-r--r--fs/9p/v9fs.h6
-rw-r--r--fs/9p/vfs_file.c13
-rw-r--r--fs/9p/vfs_inode.c29
-rw-r--r--fs/9p/vfs_inode_dotl.c22
-rw-r--r--fs/9p/vfs_super.c2
7 files changed, 65 insertions, 30 deletions
diff --git a/fs/9p/acl.c b/fs/9p/acl.c
index 515455296378..33aa116732c8 100644
--- a/fs/9p/acl.c
+++ b/fs/9p/acl.c
@@ -262,7 +262,7 @@ static int v9fs_xattr_get_acl(struct dentry *dentry, const char *name,
262 if (strcmp(name, "") != 0) 262 if (strcmp(name, "") != 0)
263 return -EINVAL; 263 return -EINVAL;
264 264
265 v9ses = v9fs_inode2v9ses(dentry->d_inode); 265 v9ses = v9fs_dentry2v9ses(dentry);
266 /* 266 /*
267 * We allow set/get/list of acl when access=client is not specified 267 * We allow set/get/list of acl when access=client is not specified
268 */ 268 */
@@ -312,7 +312,7 @@ static int v9fs_xattr_set_acl(struct dentry *dentry, const char *name,
312 if (strcmp(name, "") != 0) 312 if (strcmp(name, "") != 0)
313 return -EINVAL; 313 return -EINVAL;
314 314
315 v9ses = v9fs_inode2v9ses(dentry->d_inode); 315 v9ses = v9fs_dentry2v9ses(dentry);
316 /* 316 /*
317 * set the attribute on the remote. Without even looking at the 317 * set the attribute on the remote. Without even looking at the
318 * xattr value. We leave it to the server to validate 318 * xattr value. We leave it to the server to validate
diff --git a/fs/9p/fid.c b/fs/9p/fid.c
index cd63e002d826..0ee594569dcc 100644
--- a/fs/9p/fid.c
+++ b/fs/9p/fid.c
@@ -134,7 +134,7 @@ static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry,
134 struct v9fs_session_info *v9ses; 134 struct v9fs_session_info *v9ses;
135 struct p9_fid *fid, *old_fid = NULL; 135 struct p9_fid *fid, *old_fid = NULL;
136 136
137 v9ses = v9fs_inode2v9ses(dentry->d_inode); 137 v9ses = v9fs_dentry2v9ses(dentry);
138 access = v9ses->flags & V9FS_ACCESS_MASK; 138 access = v9ses->flags & V9FS_ACCESS_MASK;
139 fid = v9fs_fid_find(dentry, uid, any); 139 fid = v9fs_fid_find(dentry, uid, any);
140 if (fid) 140 if (fid)
@@ -237,7 +237,7 @@ struct p9_fid *v9fs_fid_lookup(struct dentry *dentry)
237 int any, access; 237 int any, access;
238 struct v9fs_session_info *v9ses; 238 struct v9fs_session_info *v9ses;
239 239
240 v9ses = v9fs_inode2v9ses(dentry->d_inode); 240 v9ses = v9fs_dentry2v9ses(dentry);
241 access = v9ses->flags & V9FS_ACCESS_MASK; 241 access = v9ses->flags & V9FS_ACCESS_MASK;
242 switch (access) { 242 switch (access) {
243 case V9FS_ACCESS_SINGLE: 243 case V9FS_ACCESS_SINGLE:
@@ -286,9 +286,11 @@ static struct p9_fid *v9fs_fid_clone_with_uid(struct dentry *dentry, uid_t uid)
286 286
287struct p9_fid *v9fs_writeback_fid(struct dentry *dentry) 287struct p9_fid *v9fs_writeback_fid(struct dentry *dentry)
288{ 288{
289 int err; 289 int err, flags;
290 struct p9_fid *fid; 290 struct p9_fid *fid;
291 struct v9fs_session_info *v9ses;
291 292
293 v9ses = v9fs_dentry2v9ses(dentry);
292 fid = v9fs_fid_clone_with_uid(dentry, 0); 294 fid = v9fs_fid_clone_with_uid(dentry, 0);
293 if (IS_ERR(fid)) 295 if (IS_ERR(fid))
294 goto error_out; 296 goto error_out;
@@ -297,8 +299,17 @@ struct p9_fid *v9fs_writeback_fid(struct dentry *dentry)
297 * dirty pages. We always request for the open fid in read-write 299 * dirty pages. We always request for the open fid in read-write
298 * mode so that a partial page write which result in page 300 * mode so that a partial page write which result in page
299 * read can work. 301 * read can work.
302 *
303 * we don't have a tsyncfs operation for older version
304 * of protocol. So make sure the write back fid is
305 * opened in O_SYNC mode.
300 */ 306 */
301 err = p9_client_open(fid, O_RDWR); 307 if (!v9fs_proto_dotl(v9ses))
308 flags = O_RDWR | O_SYNC;
309 else
310 flags = O_RDWR;
311
312 err = p9_client_open(fid, flags);
302 if (err < 0) { 313 if (err < 0) {
303 p9_client_clunk(fid); 314 p9_client_clunk(fid);
304 fid = ERR_PTR(err); 315 fid = ERR_PTR(err);
diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h
index bd8496db135b..9665c2b840e6 100644
--- a/fs/9p/v9fs.h
+++ b/fs/9p/v9fs.h
@@ -130,6 +130,7 @@ struct v9fs_inode {
130#endif 130#endif
131 unsigned int cache_validity; 131 unsigned int cache_validity;
132 struct p9_fid *writeback_fid; 132 struct p9_fid *writeback_fid;
133 struct mutex v_mutex;
133 struct inode vfs_inode; 134 struct inode vfs_inode;
134}; 135};
135 136
@@ -173,6 +174,11 @@ static inline struct v9fs_session_info *v9fs_inode2v9ses(struct inode *inode)
173 return (inode->i_sb->s_fs_info); 174 return (inode->i_sb->s_fs_info);
174} 175}
175 176
177static inline struct v9fs_session_info *v9fs_dentry2v9ses(struct dentry *dentry)
178{
179 return dentry->d_sb->s_fs_info;
180}
181
176static inline int v9fs_proto_dotu(struct v9fs_session_info *v9ses) 182static inline int v9fs_proto_dotu(struct v9fs_session_info *v9ses)
177{ 183{
178 return v9ses->flags & V9FS_PROTO_2000U; 184 return v9ses->flags & V9FS_PROTO_2000U;
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
index 78bcb97c3425..ffed55817f0c 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -90,7 +90,9 @@ int v9fs_file_open(struct inode *inode, struct file *file)
90 } 90 }
91 91
92 file->private_data = fid; 92 file->private_data = fid;
93 if (v9ses->cache && !v9inode->writeback_fid) { 93 mutex_lock(&v9inode->v_mutex);
94 if (v9ses->cache && !v9inode->writeback_fid &&
95 ((file->f_flags & O_ACCMODE) != O_RDONLY)) {
94 /* 96 /*
95 * clone a fid and add it to writeback_fid 97 * clone a fid and add it to writeback_fid
96 * we do it during open time instead of 98 * we do it during open time instead of
@@ -101,10 +103,12 @@ int v9fs_file_open(struct inode *inode, struct file *file)
101 fid = v9fs_writeback_fid(file->f_path.dentry); 103 fid = v9fs_writeback_fid(file->f_path.dentry);
102 if (IS_ERR(fid)) { 104 if (IS_ERR(fid)) {
103 err = PTR_ERR(fid); 105 err = PTR_ERR(fid);
106 mutex_unlock(&v9inode->v_mutex);
104 goto out_error; 107 goto out_error;
105 } 108 }
106 v9inode->writeback_fid = (void *) fid; 109 v9inode->writeback_fid = (void *) fid;
107 } 110 }
111 mutex_unlock(&v9inode->v_mutex);
108#ifdef CONFIG_9P_FSCACHE 112#ifdef CONFIG_9P_FSCACHE
109 if (v9ses->cache) 113 if (v9ses->cache)
110 v9fs_cache_inode_set_cookie(inode, file); 114 v9fs_cache_inode_set_cookie(inode, file);
@@ -504,9 +508,12 @@ v9fs_file_write(struct file *filp, const char __user * data,
504 if (!count) 508 if (!count)
505 goto out; 509 goto out;
506 510
507 return v9fs_file_write_internal(filp->f_path.dentry->d_inode, 511 retval = v9fs_file_write_internal(filp->f_path.dentry->d_inode,
508 filp->private_data, 512 filp->private_data,
509 data, count, offset, 1); 513 data, count, &origin, 1);
514 /* update offset on successful write */
515 if (retval > 0)
516 *offset = origin;
510out: 517out:
511 return retval; 518 return retval;
512} 519}
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);
diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c
index 67c138e94feb..ffbb113d5f33 100644
--- a/fs/9p/vfs_inode_dotl.c
+++ b/fs/9p/vfs_inode_dotl.c
@@ -245,7 +245,9 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int omode,
245 v9fs_set_create_acl(dentry, dacl, pacl); 245 v9fs_set_create_acl(dentry, dacl, pacl);
246 246
247 v9inode = V9FS_I(inode); 247 v9inode = V9FS_I(inode);
248 if (v9ses->cache && !v9inode->writeback_fid) { 248 mutex_lock(&v9inode->v_mutex);
249 if (v9ses->cache && !v9inode->writeback_fid &&
250 ((flags & O_ACCMODE) != O_RDONLY)) {
249 /* 251 /*
250 * clone a fid and add it to writeback_fid 252 * clone a fid and add it to writeback_fid
251 * we do it during open time instead of 253 * we do it during open time instead of
@@ -256,10 +258,12 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int omode,
256 inode_fid = v9fs_writeback_fid(dentry); 258 inode_fid = v9fs_writeback_fid(dentry);
257 if (IS_ERR(inode_fid)) { 259 if (IS_ERR(inode_fid)) {
258 err = PTR_ERR(inode_fid); 260 err = PTR_ERR(inode_fid);
261 mutex_unlock(&v9inode->v_mutex);
259 goto error; 262 goto error;
260 } 263 }
261 v9inode->writeback_fid = (void *) inode_fid; 264 v9inode->writeback_fid = (void *) inode_fid;
262 } 265 }
266 mutex_unlock(&v9inode->v_mutex);
263 /* Since we are opening a file, assign the open fid to the file */ 267 /* Since we are opening a file, assign the open fid to the file */
264 filp = lookup_instantiate_filp(nd, dentry, generic_file_open); 268 filp = lookup_instantiate_filp(nd, dentry, generic_file_open);
265 if (IS_ERR(filp)) { 269 if (IS_ERR(filp)) {
@@ -391,7 +395,7 @@ v9fs_vfs_getattr_dotl(struct vfsmount *mnt, struct dentry *dentry,
391 395
392 P9_DPRINTK(P9_DEBUG_VFS, "dentry: %p\n", dentry); 396 P9_DPRINTK(P9_DEBUG_VFS, "dentry: %p\n", dentry);
393 err = -EPERM; 397 err = -EPERM;
394 v9ses = v9fs_inode2v9ses(dentry->d_inode); 398 v9ses = v9fs_dentry2v9ses(dentry);
395 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) { 399 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
396 generic_fillattr(dentry->d_inode, stat); 400 generic_fillattr(dentry->d_inode, stat);
397 return 0; 401 return 0;
@@ -448,17 +452,11 @@ int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr)
448 p9attr.mtime_nsec = iattr->ia_mtime.tv_nsec; 452 p9attr.mtime_nsec = iattr->ia_mtime.tv_nsec;
449 453
450 retval = -EPERM; 454 retval = -EPERM;
451 v9ses = v9fs_inode2v9ses(dentry->d_inode); 455 v9ses = v9fs_dentry2v9ses(dentry);
452 fid = v9fs_fid_lookup(dentry); 456 fid = v9fs_fid_lookup(dentry);
453 if (IS_ERR(fid)) 457 if (IS_ERR(fid))
454 return PTR_ERR(fid); 458 return PTR_ERR(fid);
455 459
456 if ((iattr->ia_valid & ATTR_SIZE) &&
457 iattr->ia_size != i_size_read(dentry->d_inode)) {
458 retval = vmtruncate(dentry->d_inode, iattr->ia_size);
459 if (retval)
460 return retval;
461 }
462 /* Write all dirty data */ 460 /* Write all dirty data */
463 if (S_ISREG(dentry->d_inode->i_mode)) 461 if (S_ISREG(dentry->d_inode->i_mode))
464 filemap_write_and_wait(dentry->d_inode->i_mapping); 462 filemap_write_and_wait(dentry->d_inode->i_mapping);
@@ -466,8 +464,12 @@ int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr)
466 retval = p9_client_setattr(fid, &p9attr); 464 retval = p9_client_setattr(fid, &p9attr);
467 if (retval < 0) 465 if (retval < 0)
468 return retval; 466 return retval;
469 v9fs_invalidate_inode_attr(dentry->d_inode);
470 467
468 if ((iattr->ia_valid & ATTR_SIZE) &&
469 iattr->ia_size != i_size_read(dentry->d_inode))
470 truncate_setsize(dentry->d_inode, iattr->ia_size);
471
472 v9fs_invalidate_inode_attr(dentry->d_inode);
471 setattr_copy(dentry->d_inode, iattr); 473 setattr_copy(dentry->d_inode, iattr);
472 mark_inode_dirty(dentry->d_inode); 474 mark_inode_dirty(dentry->d_inode);
473 if (iattr->ia_valid & ATTR_MODE) { 475 if (iattr->ia_valid & ATTR_MODE) {
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c
index 09fd08d1606f..f3eed3383e4f 100644
--- a/fs/9p/vfs_super.c
+++ b/fs/9p/vfs_super.c
@@ -262,7 +262,7 @@ static int v9fs_statfs(struct dentry *dentry, struct kstatfs *buf)
262 goto done; 262 goto done;
263 } 263 }
264 264
265 v9ses = v9fs_inode2v9ses(dentry->d_inode); 265 v9ses = v9fs_dentry2v9ses(dentry);
266 if (v9fs_proto_dotl(v9ses)) { 266 if (v9fs_proto_dotl(v9ses)) {
267 res = p9_client_statfs(fid, &rs); 267 res = p9_client_statfs(fid, &rs);
268 if (res == 0) { 268 if (res == 0) {