aboutsummaryrefslogtreecommitdiffstats
path: root/fs/9p/vfs_inode.c
diff options
context:
space:
mode:
authorAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>2011-07-11 12:40:59 -0400
committerEric Van Hensbergen <ericvh@gmail.com>2011-07-23 10:32:48 -0400
commitfd2421f54423f307ecd31bdebdca6bc317e0c492 (patch)
tree6e681349c6111a6bca9a562090bdedfd5b2ed29c /fs/9p/vfs_inode.c
parent5034990e28efb2d232ee82443a9edd62defd17ba (diff)
fs/9p: When doing inode lookup compare qid details and inode mode bits.
This make sure we don't use wrong inode from the inode hash. The inode number of the file deleted is reused by the next file system object created and if we only use inode number for inode hash lookup we could end up with wrong struct inode. Also compare inode generation number. Not all Linux file system provide st_gen in userspace. So it could be 0; Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
Diffstat (limited to 'fs/9p/vfs_inode.c')
-rw-r--r--fs/9p/vfs_inode.c36
1 files changed, 33 insertions, 3 deletions
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index a5a95372cd68..3d8a18ee78e6 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -216,7 +216,6 @@ struct inode *v9fs_alloc_inode(struct super_block *sb)
216 return NULL; 216 return NULL;
217#ifdef CONFIG_9P_FSCACHE 217#ifdef CONFIG_9P_FSCACHE
218 v9inode->fscache = NULL; 218 v9inode->fscache = NULL;
219 v9inode->fscache_key = NULL;
220 spin_lock_init(&v9inode->fscache_lock); 219 spin_lock_init(&v9inode->fscache_lock);
221#endif 220#endif
222 v9inode->writeback_fid = NULL; 221 v9inode->writeback_fid = NULL;
@@ -433,6 +432,37 @@ void v9fs_evict_inode(struct inode *inode)
433 } 432 }
434} 433}
435 434
435static int v9fs_test_inode(struct inode *inode, void *data)
436{
437 int umode;
438 struct v9fs_inode *v9inode = V9FS_I(inode);
439 struct p9_wstat *st = (struct p9_wstat *)data;
440 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
441
442 umode = p9mode2unixmode(v9ses, st->mode);
443 /* don't match inode of different type */
444 if ((inode->i_mode & S_IFMT) != (umode & S_IFMT))
445 return 0;
446
447 /* compare qid details */
448 if (memcmp(&v9inode->qid.version,
449 &st->qid.version, sizeof(v9inode->qid.version)))
450 return 0;
451
452 if (v9inode->qid.type != st->qid.type)
453 return 0;
454 return 1;
455}
456
457static int v9fs_set_inode(struct inode *inode, void *data)
458{
459 struct v9fs_inode *v9inode = V9FS_I(inode);
460 struct p9_wstat *st = (struct p9_wstat *)data;
461
462 memcpy(&v9inode->qid, &st->qid, sizeof(st->qid));
463 return 0;
464}
465
436static struct inode *v9fs_qid_iget(struct super_block *sb, 466static struct inode *v9fs_qid_iget(struct super_block *sb,
437 struct p9_qid *qid, 467 struct p9_qid *qid,
438 struct p9_wstat *st) 468 struct p9_wstat *st)
@@ -443,7 +473,7 @@ static struct inode *v9fs_qid_iget(struct super_block *sb,
443 struct v9fs_session_info *v9ses = sb->s_fs_info; 473 struct v9fs_session_info *v9ses = sb->s_fs_info;
444 474
445 i_ino = v9fs_qid2ino(qid); 475 i_ino = v9fs_qid2ino(qid);
446 inode = iget_locked(sb, i_ino); 476 inode = iget5_locked(sb, i_ino, v9fs_test_inode, v9fs_set_inode, st);
447 if (!inode) 477 if (!inode)
448 return ERR_PTR(-ENOMEM); 478 return ERR_PTR(-ENOMEM);
449 if (!(inode->i_state & I_NEW)) 479 if (!(inode->i_state & I_NEW))
@@ -453,6 +483,7 @@ static struct inode *v9fs_qid_iget(struct super_block *sb,
453 * FIXME!! we may need support for stale inodes 483 * FIXME!! we may need support for stale inodes
454 * later. 484 * later.
455 */ 485 */
486 inode->i_ino = i_ino;
456 umode = p9mode2unixmode(v9ses, st->mode); 487 umode = p9mode2unixmode(v9ses, st->mode);
457 retval = v9fs_init_inode(v9ses, inode, umode); 488 retval = v9fs_init_inode(v9ses, inode, umode);
458 if (retval) 489 if (retval)
@@ -460,7 +491,6 @@ static struct inode *v9fs_qid_iget(struct super_block *sb,
460 491
461 v9fs_stat2inode(st, inode, sb); 492 v9fs_stat2inode(st, inode, sb);
462#ifdef CONFIG_9P_FSCACHE 493#ifdef CONFIG_9P_FSCACHE
463 v9fs_fscache_set_key(inode, &st->qid);
464 v9fs_cache_inode_get_cookie(inode); 494 v9fs_cache_inode_get_cookie(inode);
465#endif 495#endif
466 unlock_new_inode(inode); 496 unlock_new_inode(inode);