Commit 3cf387d780944305839f5b27c51f225444ba4d27
Committed by
Eric Van Hensbergen
1 parent
17311779ac
fs/9p: Add fid to inode in cached mode
The fid attached to inode will be opened O_RDWR mode and is used for dirty page writeback only. Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Signed-off-by: Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com> Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
Showing 5 changed files with 83 additions and 3 deletions Side-by-side Diff
fs/9p/fid.c
... | ... | @@ -261,4 +261,30 @@ |
261 | 261 | ret = p9_client_walk(fid, 0, NULL, 1); |
262 | 262 | return ret; |
263 | 263 | } |
264 | + | |
265 | + | |
266 | +struct p9_fid *v9fs_writeback_fid(struct dentry *dentry) | |
267 | +{ | |
268 | + int err; | |
269 | + struct p9_fid *fid; | |
270 | + | |
271 | + fid = v9fs_fid_clone(dentry); | |
272 | + if (IS_ERR(fid)) | |
273 | + goto error_out; | |
274 | + /* | |
275 | + * writeback fid will only be used to write back the | |
276 | + * dirty pages. We always request for the open fid in read-write | |
277 | + * mode so that a partial page write which result in page | |
278 | + * read can work. | |
279 | + * FIXME!!: we should make the fid owned by uid = 0 | |
280 | + */ | |
281 | + err = p9_client_open(fid, O_RDWR); | |
282 | + if (err < 0) { | |
283 | + p9_client_clunk(fid); | |
284 | + fid = ERR_PTR(err); | |
285 | + goto error_out; | |
286 | + } | |
287 | +error_out: | |
288 | + return fid; | |
289 | +} |
fs/9p/fid.h
fs/9p/vfs_file.c
... | ... | @@ -86,11 +86,30 @@ |
86 | 86 | } |
87 | 87 | |
88 | 88 | file->private_data = fid; |
89 | + if (v9ses->cache && !inode->i_private) { | |
90 | + /* | |
91 | + * clone a fid and add it to inode->i_private | |
92 | + * we do it during open time instead of | |
93 | + * page dirty time via write_begin/page_mkwrite | |
94 | + * because we want write after unlink usecase | |
95 | + * to work. | |
96 | + */ | |
97 | + fid = v9fs_writeback_fid(file->f_path.dentry); | |
98 | + if (IS_ERR(fid)) { | |
99 | + err = PTR_ERR(fid); | |
100 | + goto out_error; | |
101 | + } | |
102 | + inode->i_private = (void *) fid; | |
103 | + } | |
89 | 104 | #ifdef CONFIG_9P_FSCACHE |
90 | 105 | if (v9ses->cache) |
91 | 106 | v9fs_cache_inode_set_cookie(inode, file); |
92 | 107 | #endif |
93 | 108 | return 0; |
109 | +out_error: | |
110 | + p9_client_clunk(file->private_data); | |
111 | + file->private_data = NULL; | |
112 | + return err; | |
94 | 113 | } |
95 | 114 | |
96 | 115 | /** |
fs/9p/vfs_inode.c
... | ... | @@ -417,6 +417,11 @@ |
417 | 417 | #ifdef CONFIG_9P_FSCACHE |
418 | 418 | v9fs_cache_inode_put_cookie(inode); |
419 | 419 | #endif |
420 | + /* clunk the fid stashed in inode->i_private */ | |
421 | + if (inode->i_private) { | |
422 | + p9_client_clunk((struct p9_fid *)inode->i_private); | |
423 | + inode->i_private = NULL; | |
424 | + } | |
420 | 425 | } |
421 | 426 | |
422 | 427 | struct inode * |
... | ... | @@ -578,7 +583,7 @@ |
578 | 583 | u32 perm; |
579 | 584 | int flags; |
580 | 585 | struct v9fs_session_info *v9ses; |
581 | - struct p9_fid *fid; | |
586 | + struct p9_fid *fid, *inode_fid; | |
582 | 587 | struct file *filp; |
583 | 588 | |
584 | 589 | err = 0; |
... | ... | @@ -601,6 +606,21 @@ |
601 | 606 | |
602 | 607 | /* if we are opening a file, assign the open fid to the file */ |
603 | 608 | if (nd && nd->flags & LOOKUP_OPEN) { |
609 | + if (v9ses->cache && !dentry->d_inode->i_private) { | |
610 | + /* | |
611 | + * clone a fid and add it to inode->i_private | |
612 | + * we do it during open time instead of | |
613 | + * page dirty time via write_begin/page_mkwrite | |
614 | + * because we want write after unlink usecase | |
615 | + * to work. | |
616 | + */ | |
617 | + inode_fid = v9fs_writeback_fid(dentry); | |
618 | + if (IS_ERR(inode_fid)) { | |
619 | + err = PTR_ERR(inode_fid); | |
620 | + goto error; | |
621 | + } | |
622 | + dentry->d_inode->i_private = (void *) inode_fid; | |
623 | + } | |
604 | 624 | filp = lookup_instantiate_filp(nd, dentry, generic_file_open); |
605 | 625 | if (IS_ERR(filp)) { |
606 | 626 | err = PTR_ERR(filp); |
fs/9p/vfs_inode_dotl.c
... | ... | @@ -142,7 +142,7 @@ |
142 | 142 | mode_t mode; |
143 | 143 | struct v9fs_session_info *v9ses; |
144 | 144 | struct p9_fid *fid = NULL; |
145 | - struct p9_fid *dfid, *ofid; | |
145 | + struct p9_fid *dfid, *ofid, *inode_fid; | |
146 | 146 | struct file *filp; |
147 | 147 | struct p9_qid qid; |
148 | 148 | struct inode *inode; |
... | ... | @@ -218,7 +218,21 @@ |
218 | 218 | |
219 | 219 | /* Now set the ACL based on the default value */ |
220 | 220 | v9fs_set_create_acl(dentry, dacl, pacl); |
221 | - | |
221 | + if (v9ses->cache && !inode->i_private) { | |
222 | + /* | |
223 | + * clone a fid and add it to inode->i_private | |
224 | + * we do it during open time instead of | |
225 | + * page dirty time via write_begin/page_mkwrite | |
226 | + * because we want write after unlink usecase | |
227 | + * to work. | |
228 | + */ | |
229 | + inode_fid = v9fs_writeback_fid(dentry); | |
230 | + if (IS_ERR(inode_fid)) { | |
231 | + err = PTR_ERR(inode_fid); | |
232 | + goto error; | |
233 | + } | |
234 | + inode->i_private = (void *) inode_fid; | |
235 | + } | |
222 | 236 | /* Since we are opening a file, assign the open fid to the file */ |
223 | 237 | filp = lookup_instantiate_filp(nd, dentry, generic_file_open); |
224 | 238 | if (IS_ERR(filp)) { |