]> err.no Git - linux-2.6/commitdiff
[GFS2] Obtaining no_formal_ino from directory entry
authorWendy Cheng <wcheng@redhat.com>
Wed, 27 Jun 2007 21:07:08 +0000 (17:07 -0400)
committerSteven Whitehouse <swhiteho@redhat.com>
Mon, 9 Jul 2007 07:24:08 +0000 (08:24 +0100)
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: S. Wendy Cheng <wcheng@redhat.com>
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
fs/gfs2/dir.c
fs/gfs2/inode.c
fs/gfs2/inode.h
fs/gfs2/ops_export.c
fs/gfs2/ops_fstype.c
fs/gfs2/rgrp.c

index f793e31a050ec3936bd493b613a34d94f66b0f11..2beb2f401aa24a2b23cf511d813d21db06e521b7 100644 (file)
@@ -1498,9 +1498,10 @@ struct inode *gfs2_dir_search(struct inode *dir, const struct qstr *name)
        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;
        }
index 792d64f69cc25ceb642df8a27a13e6f4d5b7ae60..26aaf54959d92ace19ab1574d9af1e0894ca995c 100644 (file)
@@ -86,7 +86,10 @@ static struct inode *gfs2_iget(struct super_block *sb, u64 no_addr)
  * 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 super_block *sb, u64 no_addr, unsigned in
                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_holder *ghs, const struct qstr *name,
        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;
 
index 35375fc43fa335e1af7def13f51faa5df56f0250..3268a2fed6724d63ccd0f02b3396fc0528f21561 100644 (file)
@@ -47,7 +47,8 @@ static inline void gfs2_inum_out(const 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);
 
 int gfs2_inode_refresh(struct gfs2_inode *ip);
index d07230ee5fc00b8b23324408c8333c67382a3fa7..0fe14478a54d1597cef17508fd7181f0c99c807d 100644 (file)
@@ -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(&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)) {
index dae1d7142fe5e8f48d9e7120031a6401453bc790..cf5aa50505488d95a62719f9728660e742728575 100644 (file)
@@ -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)
index 36c523d487a71b5ca01b56c262380340c476d0df..7fb74484af633ad5e71ab15ec9d32e974df6a5df 100644 (file)
@@ -860,18 +860,19 @@ static struct inode *try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked)
 {
        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;
        }