aboutsummaryrefslogtreecommitdiffstats
path: root/fs/9p/vfs_inode_dotl.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/9p/vfs_inode_dotl.c')
-rw-r--r--fs/9p/vfs_inode_dotl.c198
1 files changed, 133 insertions, 65 deletions
diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c
index fe3ffa9aace4..67c138e94feb 100644
--- a/fs/9p/vfs_inode_dotl.c
+++ b/fs/9p/vfs_inode_dotl.c
@@ -86,40 +86,63 @@ static struct dentry *v9fs_dentry_from_dir_inode(struct inode *inode)
86 return dentry; 86 return dentry;
87} 87}
88 88
89static struct inode *v9fs_qid_iget_dotl(struct super_block *sb,
90 struct p9_qid *qid,
91 struct p9_fid *fid,
92 struct p9_stat_dotl *st)
93{
94 int retval;
95 unsigned long i_ino;
96 struct inode *inode;
97 struct v9fs_session_info *v9ses = sb->s_fs_info;
98
99 i_ino = v9fs_qid2ino(qid);
100 inode = iget_locked(sb, i_ino);
101 if (!inode)
102 return ERR_PTR(-ENOMEM);
103 if (!(inode->i_state & I_NEW))
104 return inode;
105 /*
106 * initialize the inode with the stat info
107 * FIXME!! we may need support for stale inodes
108 * later.
109 */
110 retval = v9fs_init_inode(v9ses, inode, st->st_mode);
111 if (retval)
112 goto error;
113
114 v9fs_stat2inode_dotl(st, inode);
115#ifdef CONFIG_9P_FSCACHE
116 v9fs_fscache_set_key(inode, &st->qid);
117 v9fs_cache_inode_get_cookie(inode);
118#endif
119 retval = v9fs_get_acl(inode, fid);
120 if (retval)
121 goto error;
122
123 unlock_new_inode(inode);
124 return inode;
125error:
126 unlock_new_inode(inode);
127 iput(inode);
128 return ERR_PTR(retval);
129
130}
131
89struct inode * 132struct inode *
90v9fs_inode_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid, 133v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid,
91 struct super_block *sb) 134 struct super_block *sb)
92{ 135{
93 struct inode *ret = NULL;
94 int err;
95 struct p9_stat_dotl *st; 136 struct p9_stat_dotl *st;
137 struct inode *inode = NULL;
96 138
97 st = p9_client_getattr_dotl(fid, P9_STATS_BASIC); 139 st = p9_client_getattr_dotl(fid, P9_STATS_BASIC);
98 if (IS_ERR(st)) 140 if (IS_ERR(st))
99 return ERR_CAST(st); 141 return ERR_CAST(st);
100 142
101 ret = v9fs_get_inode(sb, st->st_mode); 143 inode = v9fs_qid_iget_dotl(sb, &st->qid, fid, st);
102 if (IS_ERR(ret)) {
103 err = PTR_ERR(ret);
104 goto error;
105 }
106
107 v9fs_stat2inode_dotl(st, ret);
108 ret->i_ino = v9fs_qid2ino(&st->qid);
109#ifdef CONFIG_9P_FSCACHE
110 v9fs_vcookie_set_qid(ret, &st->qid);
111 v9fs_cache_inode_get_cookie(ret);
112#endif
113 err = v9fs_get_acl(ret, fid);
114 if (err) {
115 iput(ret);
116 goto error;
117 }
118 kfree(st);
119 return ret;
120error:
121 kfree(st); 144 kfree(st);
122 return ERR_PTR(err); 145 return inode;
123} 146}
124 147
125/** 148/**
@@ -136,16 +159,17 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int omode,
136 struct nameidata *nd) 159 struct nameidata *nd)
137{ 160{
138 int err = 0; 161 int err = 0;
139 char *name = NULL;
140 gid_t gid; 162 gid_t gid;
141 int flags; 163 int flags;
142 mode_t mode; 164 mode_t mode;
143 struct v9fs_session_info *v9ses; 165 char *name = NULL;
144 struct p9_fid *fid = NULL;
145 struct p9_fid *dfid, *ofid;
146 struct file *filp; 166 struct file *filp;
147 struct p9_qid qid; 167 struct p9_qid qid;
148 struct inode *inode; 168 struct inode *inode;
169 struct p9_fid *fid = NULL;
170 struct v9fs_inode *v9inode;
171 struct p9_fid *dfid, *ofid, *inode_fid;
172 struct v9fs_session_info *v9ses;
149 struct posix_acl *pacl = NULL, *dacl = NULL; 173 struct posix_acl *pacl = NULL, *dacl = NULL;
150 174
151 v9ses = v9fs_inode2v9ses(dir); 175 v9ses = v9fs_inode2v9ses(dir);
@@ -196,6 +220,7 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int omode,
196 err); 220 err);
197 goto error; 221 goto error;
198 } 222 }
223 v9fs_invalidate_inode_attr(dir);
199 224
200 /* instantiate inode and assign the unopened fid to the dentry */ 225 /* instantiate inode and assign the unopened fid to the dentry */
201 fid = p9_client_walk(dfid, 1, &name, 1); 226 fid = p9_client_walk(dfid, 1, &name, 1);
@@ -205,7 +230,7 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int omode,
205 fid = NULL; 230 fid = NULL;
206 goto error; 231 goto error;
207 } 232 }
208 inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb); 233 inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
209 if (IS_ERR(inode)) { 234 if (IS_ERR(inode)) {
210 err = PTR_ERR(inode); 235 err = PTR_ERR(inode);
211 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err); 236 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err);
@@ -219,6 +244,22 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int omode,
219 /* Now set the ACL based on the default value */ 244 /* Now set the ACL based on the default value */
220 v9fs_set_create_acl(dentry, dacl, pacl); 245 v9fs_set_create_acl(dentry, dacl, pacl);
221 246
247 v9inode = V9FS_I(inode);
248 if (v9ses->cache && !v9inode->writeback_fid) {
249 /*
250 * clone a fid and add it to writeback_fid
251 * we do it during open time instead of
252 * page dirty time via write_begin/page_mkwrite
253 * because we want write after unlink usecase
254 * to work.
255 */
256 inode_fid = v9fs_writeback_fid(dentry);
257 if (IS_ERR(inode_fid)) {
258 err = PTR_ERR(inode_fid);
259 goto error;
260 }
261 v9inode->writeback_fid = (void *) inode_fid;
262 }
222 /* Since we are opening a file, assign the open fid to the file */ 263 /* Since we are opening a file, assign the open fid to the file */
223 filp = lookup_instantiate_filp(nd, dentry, generic_file_open); 264 filp = lookup_instantiate_filp(nd, dentry, generic_file_open);
224 if (IS_ERR(filp)) { 265 if (IS_ERR(filp)) {
@@ -226,6 +267,10 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int omode,
226 return PTR_ERR(filp); 267 return PTR_ERR(filp);
227 } 268 }
228 filp->private_data = ofid; 269 filp->private_data = ofid;
270#ifdef CONFIG_9P_FSCACHE
271 if (v9ses->cache)
272 v9fs_cache_inode_set_cookie(inode, filp);
273#endif
229 return 0; 274 return 0;
230 275
231error: 276error:
@@ -300,7 +345,7 @@ static int v9fs_vfs_mkdir_dotl(struct inode *dir,
300 goto error; 345 goto error;
301 } 346 }
302 347
303 inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb); 348 inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
304 if (IS_ERR(inode)) { 349 if (IS_ERR(inode)) {
305 err = PTR_ERR(inode); 350 err = PTR_ERR(inode);
306 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", 351 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n",
@@ -327,7 +372,8 @@ static int v9fs_vfs_mkdir_dotl(struct inode *dir,
327 } 372 }
328 /* Now set the ACL based on the default value */ 373 /* Now set the ACL based on the default value */
329 v9fs_set_create_acl(dentry, dacl, pacl); 374 v9fs_set_create_acl(dentry, dacl, pacl);
330 375 inc_nlink(dir);
376 v9fs_invalidate_inode_attr(dir);
331error: 377error:
332 if (fid) 378 if (fid)
333 p9_client_clunk(fid); 379 p9_client_clunk(fid);
@@ -346,9 +392,10 @@ v9fs_vfs_getattr_dotl(struct vfsmount *mnt, struct dentry *dentry,
346 P9_DPRINTK(P9_DEBUG_VFS, "dentry: %p\n", dentry); 392 P9_DPRINTK(P9_DEBUG_VFS, "dentry: %p\n", dentry);
347 err = -EPERM; 393 err = -EPERM;
348 v9ses = v9fs_inode2v9ses(dentry->d_inode); 394 v9ses = v9fs_inode2v9ses(dentry->d_inode);
349 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) 395 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
350 return simple_getattr(mnt, dentry, stat); 396 generic_fillattr(dentry->d_inode, stat);
351 397 return 0;
398 }
352 fid = v9fs_fid_lookup(dentry); 399 fid = v9fs_fid_lookup(dentry);
353 if (IS_ERR(fid)) 400 if (IS_ERR(fid))
354 return PTR_ERR(fid); 401 return PTR_ERR(fid);
@@ -406,16 +453,20 @@ int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr)
406 if (IS_ERR(fid)) 453 if (IS_ERR(fid))
407 return PTR_ERR(fid); 454 return PTR_ERR(fid);
408 455
409 retval = p9_client_setattr(fid, &p9attr);
410 if (retval < 0)
411 return retval;
412
413 if ((iattr->ia_valid & ATTR_SIZE) && 456 if ((iattr->ia_valid & ATTR_SIZE) &&
414 iattr->ia_size != i_size_read(dentry->d_inode)) { 457 iattr->ia_size != i_size_read(dentry->d_inode)) {
415 retval = vmtruncate(dentry->d_inode, iattr->ia_size); 458 retval = vmtruncate(dentry->d_inode, iattr->ia_size);
416 if (retval) 459 if (retval)
417 return retval; 460 return retval;
418 } 461 }
462 /* Write all dirty data */
463 if (S_ISREG(dentry->d_inode->i_mode))
464 filemap_write_and_wait(dentry->d_inode->i_mapping);
465
466 retval = p9_client_setattr(fid, &p9attr);
467 if (retval < 0)
468 return retval;
469 v9fs_invalidate_inode_attr(dentry->d_inode);
419 470
420 setattr_copy(dentry->d_inode, iattr); 471 setattr_copy(dentry->d_inode, iattr);
421 mark_inode_dirty(dentry->d_inode); 472 mark_inode_dirty(dentry->d_inode);
@@ -439,6 +490,7 @@ int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr)
439void 490void
440v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode) 491v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode)
441{ 492{
493 struct v9fs_inode *v9inode = V9FS_I(inode);
442 494
443 if ((stat->st_result_mask & P9_STATS_BASIC) == P9_STATS_BASIC) { 495 if ((stat->st_result_mask & P9_STATS_BASIC) == P9_STATS_BASIC) {
444 inode->i_atime.tv_sec = stat->st_atime_sec; 496 inode->i_atime.tv_sec = stat->st_atime_sec;
@@ -497,20 +549,21 @@ v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode)
497 /* Currently we don't support P9_STATS_BTIME and P9_STATS_DATA_VERSION 549 /* Currently we don't support P9_STATS_BTIME and P9_STATS_DATA_VERSION
498 * because the inode structure does not have fields for them. 550 * because the inode structure does not have fields for them.
499 */ 551 */
552 v9inode->cache_validity &= ~V9FS_INO_INVALID_ATTR;
500} 553}
501 554
502static int 555static int
503v9fs_vfs_symlink_dotl(struct inode *dir, struct dentry *dentry, 556v9fs_vfs_symlink_dotl(struct inode *dir, struct dentry *dentry,
504 const char *symname) 557 const char *symname)
505{ 558{
506 struct v9fs_session_info *v9ses;
507 struct p9_fid *dfid;
508 struct p9_fid *fid = NULL;
509 struct inode *inode;
510 struct p9_qid qid;
511 char *name;
512 int err; 559 int err;
513 gid_t gid; 560 gid_t gid;
561 char *name;
562 struct p9_qid qid;
563 struct inode *inode;
564 struct p9_fid *dfid;
565 struct p9_fid *fid = NULL;
566 struct v9fs_session_info *v9ses;
514 567
515 name = (char *) dentry->d_name.name; 568 name = (char *) dentry->d_name.name;
516 P9_DPRINTK(P9_DEBUG_VFS, "v9fs_vfs_symlink_dotl : %lu,%s,%s\n", 569 P9_DPRINTK(P9_DEBUG_VFS, "v9fs_vfs_symlink_dotl : %lu,%s,%s\n",
@@ -534,6 +587,7 @@ v9fs_vfs_symlink_dotl(struct inode *dir, struct dentry *dentry,
534 goto error; 587 goto error;
535 } 588 }
536 589
590 v9fs_invalidate_inode_attr(dir);
537 if (v9ses->cache) { 591 if (v9ses->cache) {
538 /* Now walk from the parent so we can get an unopened fid. */ 592 /* Now walk from the parent so we can get an unopened fid. */
539 fid = p9_client_walk(dfid, 1, &name, 1); 593 fid = p9_client_walk(dfid, 1, &name, 1);
@@ -546,7 +600,7 @@ v9fs_vfs_symlink_dotl(struct inode *dir, struct dentry *dentry,
546 } 600 }
547 601
548 /* instantiate inode and assign the unopened fid to dentry */ 602 /* instantiate inode and assign the unopened fid to dentry */
549 inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb); 603 inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
550 if (IS_ERR(inode)) { 604 if (IS_ERR(inode)) {
551 err = PTR_ERR(inode); 605 err = PTR_ERR(inode);
552 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", 606 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n",
@@ -588,10 +642,10 @@ v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir,
588 struct dentry *dentry) 642 struct dentry *dentry)
589{ 643{
590 int err; 644 int err;
591 struct p9_fid *dfid, *oldfid;
592 char *name; 645 char *name;
593 struct v9fs_session_info *v9ses;
594 struct dentry *dir_dentry; 646 struct dentry *dir_dentry;
647 struct p9_fid *dfid, *oldfid;
648 struct v9fs_session_info *v9ses;
595 649
596 P9_DPRINTK(P9_DEBUG_VFS, "dir ino: %lu, old_name: %s, new_name: %s\n", 650 P9_DPRINTK(P9_DEBUG_VFS, "dir ino: %lu, old_name: %s, new_name: %s\n",
597 dir->i_ino, old_dentry->d_name.name, 651 dir->i_ino, old_dentry->d_name.name,
@@ -616,29 +670,17 @@ v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir,
616 return err; 670 return err;
617 } 671 }
618 672
673 v9fs_invalidate_inode_attr(dir);
619 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) { 674 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
620 /* Get the latest stat info from server. */ 675 /* Get the latest stat info from server. */
621 struct p9_fid *fid; 676 struct p9_fid *fid;
622 struct p9_stat_dotl *st;
623
624 fid = v9fs_fid_lookup(old_dentry); 677 fid = v9fs_fid_lookup(old_dentry);
625 if (IS_ERR(fid)) 678 if (IS_ERR(fid))
626 return PTR_ERR(fid); 679 return PTR_ERR(fid);
627 680
628 st = p9_client_getattr_dotl(fid, P9_STATS_BASIC); 681 v9fs_refresh_inode_dotl(fid, old_dentry->d_inode);
629 if (IS_ERR(st))
630 return PTR_ERR(st);
631
632 v9fs_stat2inode_dotl(st, old_dentry->d_inode);
633
634 kfree(st);
635 } else {
636 /* Caching disabled. No need to get upto date stat info.
637 * This dentry will be released immediately. So, just hold the
638 * inode
639 */
640 ihold(old_dentry->d_inode);
641 } 682 }
683 ihold(old_dentry->d_inode);
642 d_instantiate(dentry, old_dentry->d_inode); 684 d_instantiate(dentry, old_dentry->d_inode);
643 685
644 return err; 686 return err;
@@ -657,12 +699,12 @@ v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int omode,
657 dev_t rdev) 699 dev_t rdev)
658{ 700{
659 int err; 701 int err;
702 gid_t gid;
660 char *name; 703 char *name;
661 mode_t mode; 704 mode_t mode;
662 struct v9fs_session_info *v9ses; 705 struct v9fs_session_info *v9ses;
663 struct p9_fid *fid = NULL, *dfid = NULL; 706 struct p9_fid *fid = NULL, *dfid = NULL;
664 struct inode *inode; 707 struct inode *inode;
665 gid_t gid;
666 struct p9_qid qid; 708 struct p9_qid qid;
667 struct dentry *dir_dentry; 709 struct dentry *dir_dentry;
668 struct posix_acl *dacl = NULL, *pacl = NULL; 710 struct posix_acl *dacl = NULL, *pacl = NULL;
@@ -699,6 +741,7 @@ v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int omode,
699 if (err < 0) 741 if (err < 0)
700 goto error; 742 goto error;
701 743
744 v9fs_invalidate_inode_attr(dir);
702 /* instantiate inode and assign the unopened fid to the dentry */ 745 /* instantiate inode and assign the unopened fid to the dentry */
703 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) { 746 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
704 fid = p9_client_walk(dfid, 1, &name, 1); 747 fid = p9_client_walk(dfid, 1, &name, 1);
@@ -710,7 +753,7 @@ v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int omode,
710 goto error; 753 goto error;
711 } 754 }
712 755
713 inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb); 756 inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
714 if (IS_ERR(inode)) { 757 if (IS_ERR(inode)) {
715 err = PTR_ERR(inode); 758 err = PTR_ERR(inode);
716 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", 759 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n",
@@ -782,6 +825,31 @@ ndset:
782 return NULL; 825 return NULL;
783} 826}
784 827
828int v9fs_refresh_inode_dotl(struct p9_fid *fid, struct inode *inode)
829{
830 loff_t i_size;
831 struct p9_stat_dotl *st;
832 struct v9fs_session_info *v9ses;
833
834 v9ses = v9fs_inode2v9ses(inode);
835 st = p9_client_getattr_dotl(fid, P9_STATS_ALL);
836 if (IS_ERR(st))
837 return PTR_ERR(st);
838
839 spin_lock(&inode->i_lock);
840 /*
841 * We don't want to refresh inode->i_size,
842 * because we may have cached data
843 */
844 i_size = inode->i_size;
845 v9fs_stat2inode_dotl(st, inode);
846 if (v9ses->cache)
847 inode->i_size = i_size;
848 spin_unlock(&inode->i_lock);
849 kfree(st);
850 return 0;
851}
852
785const struct inode_operations v9fs_dir_inode_operations_dotl = { 853const struct inode_operations v9fs_dir_inode_operations_dotl = {
786 .create = v9fs_vfs_create_dotl, 854 .create = v9fs_vfs_create_dotl,
787 .lookup = v9fs_vfs_lookup, 855 .lookup = v9fs_vfs_lookup,