diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-16 11:58:09 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-16 11:58:09 -0400 |
commit | 26a992dbc24e34cbdd03621d1c97ce571ad74e65 (patch) | |
tree | cbb3171eb715b7c1ed28ed3ca29f1f03165e2faa /fs/9p/vfs_inode_dotl.c | |
parent | abab012a52237693ae48a655ece30cacb2ce4cf7 (diff) | |
parent | 7c9e592e1f6a994d2903c9b055e488ec90f58159 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs: (46 commits)
fs/9p: Make the writeback_fid owned by root
fs/9p: Writeback dirty data before setattr
fs/9p: call vmtruncate before setattr 9p opeation
fs/9p: Properly update inode attributes on link
fs/9p: Prevent multiple inclusion of same header
fs/9p: Workaround vfs rename rehash bug
fs/9p: Mark directory inode invalid for many directory inode operations
fs/9p: Add . and .. dentry revalidation flag
fs/9p: mark inode attribute invalid on rename, unlink and setattr
fs/9p: Add support for marking inode attribute invalid
fs/9p: Initialize root inode number for dotl
fs/9p: Update link count correctly on different file system operations
fs/9p: Add drop_inode 9p callback
fs/9p: Add direct IO support in cached mode
fs/9p: Fix inode i_size update in file_write
fs/9p: set default readahead pages in cached mode
fs/9p: Move writeback fid to v9fs_inode
fs/9p: Add v9fs_inode
fs/9p: Don't set stat.st_blocks based on nrpages
fs/9p: Add inode hashing
...
Diffstat (limited to 'fs/9p/vfs_inode_dotl.c')
-rw-r--r-- | fs/9p/vfs_inode_dotl.c | 198 |
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 | ||
89 | static 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; | ||
125 | error: | ||
126 | unlock_new_inode(inode); | ||
127 | iput(inode); | ||
128 | return ERR_PTR(retval); | ||
129 | |||
130 | } | ||
131 | |||
89 | struct inode * | 132 | struct inode * |
90 | v9fs_inode_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid, | 133 | v9fs_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; | ||
120 | error: | ||
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 | ||
231 | error: | 276 | error: |
@@ -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); | ||
331 | error: | 377 | error: |
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) | |||
439 | void | 490 | void |
440 | v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode) | 491 | v9fs_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 | ||
502 | static int | 555 | static int |
503 | v9fs_vfs_symlink_dotl(struct inode *dir, struct dentry *dentry, | 556 | v9fs_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 | ||
828 | int 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 | |||
785 | const struct inode_operations v9fs_dir_inode_operations_dotl = { | 853 | const 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, |