From: Wendy Cheng <wcheng@redhat.com> Subject: [RHEL5.1 PATCH] 2/4 BZ 243136 GFS2 no_formal_ino Date: Thu, 28 Jun 2007 01:22:01 -0400 Bugzilla: 243136 Message-Id: <46834579.6060401@redhat.com> Changelog: [gfs2] Obtaining no_formal_ino from directory entry BZ 243136 [patch 2/4] 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, it 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 NFS file handle. Clients will get ESTALE error whenever it tries to access these files. -- Wendy --- gfs2-nfs1/fs/gfs2/inode.h 2007-06-22 22:11:42.000000000 -0400 +++ gfs2-nfs2/fs/gfs2/inode.h 2007-06-27 00:17:41.000000000 -0400 @@ -47,7 +47,8 @@ static inline void gfs2_inum_out(const s 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); int gfs2_inode_refresh(struct gfs2_inode *ip); --- gfs2-nfs1/fs/gfs2/inode.c 2007-06-22 22:11:42.000000000 -0400 +++ gfs2-nfs2/fs/gfs2/inode.c 2007-06-27 01:17:18.000000000 -0400 @@ -86,7 +86,10 @@ static struct inode *gfs2_iget(struct su * 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 gfs2_inode *ip = GFS2_I(inode); @@ -100,6 +103,7 @@ struct inode *gfs2_inode_lookup(struct s struct gfs2_sbd *sdp = GFS2_SB(inode); umode_t mode; 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); if (unlikely(error)) @@ -915,7 +919,9 @@ struct inode *gfs2_createi(struct gfs2_h if (error) 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)) goto fail_gunlock2; --- gfs2-nfs1/fs/gfs2/dir.c 2007-06-22 22:11:42.000000000 -0400 +++ gfs2-nfs2/fs/gfs2/dir.c 2007-06-27 13:43:03.000000000 -0400 @@ -1498,9 +1498,10 @@ struct inode *gfs2_dir_search(struct ino if (dent) { if (IS_ERR(dent)) return ERR_PTR(PTR_ERR(dent)); - inode = gfs2_inode_lookup(dir->i_sb, - be64_to_cpu(dent->de_inum.no_addr), - be16_to_cpu(dent->de_type)); + 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_formal_ino)); brelse(bh); return inode; } --- gfs2-nfs1/fs/gfs2/ops_export.c 2007-06-22 22:11:42.000000000 -0400 +++ gfs2-nfs2/fs/gfs2/ops_export.c 2007-06-27 00:24:38.000000000 -0400 @@ -245,7 +245,9 @@ static struct dentry *gfs2_get_dentry(st gfs2_glock_dq_uninit(&rgd_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) goto fail; if (IS_ERR(inode)) { --- gfs2-nfs1/fs/gfs2/ops_fstype.c 2007-06-22 22:11:42.000000000 -0400 +++ gfs2-nfs2/fs/gfs2/ops_fstype.c 2007-06-27 00:30:22.000000000 -0400 @@ -236,7 +236,7 @@ fail: static inline struct inode *gfs2_lookup_root(struct super_block *sb, 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) --- gfs2-nfs1/fs/gfs2/rgrp.c 2007-06-22 22:11:42.000000000 -0400 +++ gfs2-nfs2/fs/gfs2/rgrp.c 2007-06-27 01:18:09.000000000 -0400 @@ -861,18 +861,19 @@ static struct inode *try_rgrp_unlink(str { struct inode *inode; u32 goal = 0; - u64 ino; + u64 no_addr; for(;;) { goal = rgblk_search(rgd, goal, GFS2_BLKST_UNLINKED, GFS2_BLKST_UNLINKED); if (goal == 0) return 0; - ino = goal + rgd->rd_data0; - if (ino <= *last_unlinked) + no_addr = goal + rgd->rd_data0; + if (no_addr <= *last_unlinked) continue; - *last_unlinked = ino; - inode = gfs2_inode_lookup(rgd->rd_sbd->sd_vfs, ino, DT_UNKNOWN); + *last_unlinked = no_addr; + inode = gfs2_inode_lookup(rgd->rd_sbd->sd_vfs, DT_UNKNOWN, + no_addr, 0); if (!IS_ERR(inode)) return inode; }