Commit 3cf387d780944305839f5b27c51f225444ba4d27

Authored by Aneesh Kumar K.V
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

... ... @@ -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 +}
... ... @@ -45,4 +45,5 @@
45 45 struct p9_fid *v9fs_fid_lookup(struct dentry *dentry);
46 46 struct p9_fid *v9fs_fid_clone(struct dentry *dentry);
47 47 int v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid);
  48 +struct p9_fid *v9fs_writeback_fid(struct dentry *dentry);
... ... @@ -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 /**
... ... @@ -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)) {