Commit bb9bcf06 authored by Wendy Cheng's avatar Wendy Cheng Committed by Steven Whitehouse

[GFS2] Obtaining no_formal_ino from directory entry

GFS2 lookup code doesn't ask for inode shared glock. This implies during
in-memory inode creation for existing file, GFS2 will not disk-read in
the inode contents. This leaves no_formal_ino un-initialized during
lookup time. The un-initialized no_formal_ino is subsequently encoded
into file handle. Clients will get ESTALE error whenever it tries to
access these files.
Signed-off-by: default avatarS. Wendy Cheng <wcheng@redhat.com>
Signed-off-by: default avatarSteven Whitehouse <swhiteho@redhat.com>
parent f4fadb23
...@@ -1499,8 +1499,9 @@ struct inode *gfs2_dir_search(struct inode *dir, const struct qstr *name) ...@@ -1499,8 +1499,9 @@ struct inode *gfs2_dir_search(struct inode *dir, const struct qstr *name)
if (IS_ERR(dent)) if (IS_ERR(dent))
return ERR_PTR(PTR_ERR(dent)); return ERR_PTR(PTR_ERR(dent));
inode = gfs2_inode_lookup(dir->i_sb, inode = gfs2_inode_lookup(dir->i_sb,
be16_to_cpu(dent->de_type),
be64_to_cpu(dent->de_inum.no_addr), be64_to_cpu(dent->de_inum.no_addr),
be16_to_cpu(dent->de_type)); be64_to_cpu(dent->de_inum.no_formal_ino));
brelse(bh); brelse(bh);
return inode; return inode;
} }
......
...@@ -86,7 +86,10 @@ static struct inode *gfs2_iget(struct super_block *sb, u64 no_addr) ...@@ -86,7 +86,10 @@ static struct inode *gfs2_iget(struct super_block *sb, u64 no_addr)
* Returns: A VFS inode, or an error * Returns: A VFS inode, or an error
*/ */
struct inode *gfs2_inode_lookup(struct super_block *sb, u64 no_addr, unsigned int type) struct inode *gfs2_inode_lookup(struct super_block *sb,
unsigned int type,
u64 no_addr,
u64 no_formal_ino)
{ {
struct inode *inode = gfs2_iget(sb, no_addr); struct inode *inode = gfs2_iget(sb, no_addr);
struct gfs2_inode *ip = GFS2_I(inode); struct gfs2_inode *ip = GFS2_I(inode);
...@@ -100,6 +103,7 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, u64 no_addr, unsigned in ...@@ -100,6 +103,7 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, u64 no_addr, unsigned in
struct gfs2_sbd *sdp = GFS2_SB(inode); struct gfs2_sbd *sdp = GFS2_SB(inode);
umode_t mode; umode_t mode;
inode->i_private = ip; inode->i_private = ip;
ip->i_no_formal_ino = no_formal_ino;
error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl); error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl);
if (unlikely(error)) if (unlikely(error))
...@@ -915,7 +919,9 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, ...@@ -915,7 +919,9 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
if (error) if (error)
goto fail_gunlock2; goto fail_gunlock2;
inode = gfs2_inode_lookup(dir->i_sb, inum.no_addr, IF2DT(mode)); inode = gfs2_inode_lookup(dir->i_sb, IF2DT(mode),
inum.no_addr,
inum.no_formal_ino);
if (IS_ERR(inode)) if (IS_ERR(inode))
goto fail_gunlock2; goto fail_gunlock2;
......
...@@ -47,7 +47,8 @@ static inline void gfs2_inum_out(const struct gfs2_inode *ip, ...@@ -47,7 +47,8 @@ static inline void gfs2_inum_out(const struct gfs2_inode *ip,
void gfs2_inode_attr_in(struct gfs2_inode *ip); void gfs2_inode_attr_in(struct gfs2_inode *ip);
struct inode *gfs2_inode_lookup(struct super_block *sb, u64 no_addr, unsigned type); struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned type,
u64 no_addr, u64 no_formal_ino);
struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr); struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr);
int gfs2_inode_refresh(struct gfs2_inode *ip); int gfs2_inode_refresh(struct gfs2_inode *ip);
......
...@@ -245,7 +245,9 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj) ...@@ -245,7 +245,9 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj)
gfs2_glock_dq_uninit(&rgd_gh); gfs2_glock_dq_uninit(&rgd_gh);
gfs2_glock_dq_uninit(&ri_gh); gfs2_glock_dq_uninit(&ri_gh);
inode = gfs2_inode_lookup(sb, inum->no_addr, fh_obj->imode); inode = gfs2_inode_lookup(sb, fh_obj->imode,
inum->no_addr,
inum->no_formal_ino);
if (!inode) if (!inode)
goto fail; goto fail;
if (IS_ERR(inode)) { if (IS_ERR(inode)) {
......
...@@ -236,7 +236,7 @@ static int init_locking(struct gfs2_sbd *sdp, struct gfs2_holder *mount_gh, ...@@ -236,7 +236,7 @@ static int init_locking(struct gfs2_sbd *sdp, struct gfs2_holder *mount_gh,
static inline struct inode *gfs2_lookup_root(struct super_block *sb, static inline struct inode *gfs2_lookup_root(struct super_block *sb,
u64 no_addr) u64 no_addr)
{ {
return gfs2_inode_lookup(sb, no_addr, DT_DIR); return gfs2_inode_lookup(sb, DT_DIR, no_addr, 0);
} }
static int init_sb(struct gfs2_sbd *sdp, int silent, int undo) static int init_sb(struct gfs2_sbd *sdp, int silent, int undo)
......
...@@ -860,18 +860,19 @@ static struct inode *try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked) ...@@ -860,18 +860,19 @@ static struct inode *try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked)
{ {
struct inode *inode; struct inode *inode;
u32 goal = 0; u32 goal = 0;
u64 ino; u64 no_addr;
for(;;) { for(;;) {
goal = rgblk_search(rgd, goal, GFS2_BLKST_UNLINKED, goal = rgblk_search(rgd, goal, GFS2_BLKST_UNLINKED,
GFS2_BLKST_UNLINKED); GFS2_BLKST_UNLINKED);
if (goal == 0) if (goal == 0)
return 0; return 0;
ino = goal + rgd->rd_data0; no_addr = goal + rgd->rd_data0;
if (ino <= *last_unlinked) if (no_addr <= *last_unlinked)
continue; continue;
*last_unlinked = ino; *last_unlinked = no_addr;
inode = gfs2_inode_lookup(rgd->rd_sbd->sd_vfs, ino, DT_UNKNOWN); inode = gfs2_inode_lookup(rgd->rd_sbd->sd_vfs, DT_UNKNOWN,
no_addr, 0);
if (!IS_ERR(inode)) if (!IS_ERR(inode))
return inode; return inode;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment