diff options
author | Wendy Cheng <wcheng@redhat.com> | 2007-06-27 17:07:08 -0400 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2007-07-09 03:24:08 -0400 |
commit | bb9bcf061660661c57ddcf31337529f82414b937 (patch) | |
tree | 0876874e5252c4939b8e7bbd62a22a6eb4ad1abf | |
parent | f4fadb23ca49abd2f1387a0b7e78b385ebc760ce (diff) |
[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: S. Wendy Cheng <wcheng@redhat.com>
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
-rw-r--r-- | fs/gfs2/dir.c | 7 | ||||
-rw-r--r-- | fs/gfs2/inode.c | 10 | ||||
-rw-r--r-- | fs/gfs2/inode.h | 3 | ||||
-rw-r--r-- | fs/gfs2/ops_export.c | 4 | ||||
-rw-r--r-- | fs/gfs2/ops_fstype.c | 2 | ||||
-rw-r--r-- | fs/gfs2/rgrp.c | 11 |
6 files changed, 24 insertions, 13 deletions
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index f793e31a050e..2beb2f401aa2 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c | |||
@@ -1498,9 +1498,10 @@ struct inode *gfs2_dir_search(struct inode *dir, const struct qstr *name) | |||
1498 | if (dent) { | 1498 | if (dent) { |
1499 | if (IS_ERR(dent)) | 1499 | if (IS_ERR(dent)) |
1500 | return ERR_PTR(PTR_ERR(dent)); | 1500 | return ERR_PTR(PTR_ERR(dent)); |
1501 | inode = gfs2_inode_lookup(dir->i_sb, | 1501 | inode = gfs2_inode_lookup(dir->i_sb, |
1502 | be64_to_cpu(dent->de_inum.no_addr), | 1502 | be16_to_cpu(dent->de_type), |
1503 | be16_to_cpu(dent->de_type)); | 1503 | be64_to_cpu(dent->de_inum.no_addr), |
1504 | be64_to_cpu(dent->de_inum.no_formal_ino)); | ||
1504 | brelse(bh); | 1505 | brelse(bh); |
1505 | return inode; | 1506 | return inode; |
1506 | } | 1507 | } |
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 792d64f69cc2..26aaf54959d9 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -86,7 +86,10 @@ static struct inode *gfs2_iget(struct super_block *sb, u64 no_addr) | |||
86 | * Returns: A VFS inode, or an error | 86 | * Returns: A VFS inode, or an error |
87 | */ | 87 | */ |
88 | 88 | ||
89 | struct inode *gfs2_inode_lookup(struct super_block *sb, u64 no_addr, unsigned int type) | 89 | struct inode *gfs2_inode_lookup(struct super_block *sb, |
90 | unsigned int type, | ||
91 | u64 no_addr, | ||
92 | u64 no_formal_ino) | ||
90 | { | 93 | { |
91 | struct inode *inode = gfs2_iget(sb, no_addr); | 94 | struct inode *inode = gfs2_iget(sb, no_addr); |
92 | struct gfs2_inode *ip = GFS2_I(inode); | 95 | 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 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 103 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
101 | umode_t mode; | 104 | umode_t mode; |
102 | inode->i_private = ip; | 105 | inode->i_private = ip; |
106 | ip->i_no_formal_ino = no_formal_ino; | ||
103 | 107 | ||
104 | error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl); | 108 | error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl); |
105 | if (unlikely(error)) | 109 | if (unlikely(error)) |
@@ -915,7 +919,9 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, | |||
915 | if (error) | 919 | if (error) |
916 | goto fail_gunlock2; | 920 | goto fail_gunlock2; |
917 | 921 | ||
918 | inode = gfs2_inode_lookup(dir->i_sb, inum.no_addr, IF2DT(mode)); | 922 | inode = gfs2_inode_lookup(dir->i_sb, IF2DT(mode), |
923 | inum.no_addr, | ||
924 | inum.no_formal_ino); | ||
919 | if (IS_ERR(inode)) | 925 | if (IS_ERR(inode)) |
920 | goto fail_gunlock2; | 926 | goto fail_gunlock2; |
921 | 927 | ||
diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h index 35375fc43fa3..3268a2fed672 100644 --- a/fs/gfs2/inode.h +++ b/fs/gfs2/inode.h | |||
@@ -47,7 +47,8 @@ static inline void gfs2_inum_out(const struct gfs2_inode *ip, | |||
47 | 47 | ||
48 | 48 | ||
49 | void gfs2_inode_attr_in(struct gfs2_inode *ip); | 49 | void gfs2_inode_attr_in(struct gfs2_inode *ip); |
50 | struct inode *gfs2_inode_lookup(struct super_block *sb, u64 no_addr, unsigned type); | 50 | struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned type, |
51 | u64 no_addr, u64 no_formal_ino); | ||
51 | struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr); | 52 | struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr); |
52 | 53 | ||
53 | int gfs2_inode_refresh(struct gfs2_inode *ip); | 54 | int gfs2_inode_refresh(struct gfs2_inode *ip); |
diff --git a/fs/gfs2/ops_export.c b/fs/gfs2/ops_export.c index d07230ee5fc0..0fe14478a54d 100644 --- a/fs/gfs2/ops_export.c +++ b/fs/gfs2/ops_export.c | |||
@@ -245,7 +245,9 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj) | |||
245 | gfs2_glock_dq_uninit(&rgd_gh); | 245 | gfs2_glock_dq_uninit(&rgd_gh); |
246 | gfs2_glock_dq_uninit(&ri_gh); | 246 | gfs2_glock_dq_uninit(&ri_gh); |
247 | 247 | ||
248 | inode = gfs2_inode_lookup(sb, inum->no_addr, fh_obj->imode); | 248 | inode = gfs2_inode_lookup(sb, fh_obj->imode, |
249 | inum->no_addr, | ||
250 | inum->no_formal_ino); | ||
249 | if (!inode) | 251 | if (!inode) |
250 | goto fail; | 252 | goto fail; |
251 | if (IS_ERR(inode)) { | 253 | if (IS_ERR(inode)) { |
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index dae1d7142fe5..cf5aa5050548 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c | |||
@@ -236,7 +236,7 @@ fail: | |||
236 | static inline struct inode *gfs2_lookup_root(struct super_block *sb, | 236 | static inline struct inode *gfs2_lookup_root(struct super_block *sb, |
237 | u64 no_addr) | 237 | u64 no_addr) |
238 | { | 238 | { |
239 | return gfs2_inode_lookup(sb, no_addr, DT_DIR); | 239 | return gfs2_inode_lookup(sb, DT_DIR, no_addr, 0); |
240 | } | 240 | } |
241 | 241 | ||
242 | static int init_sb(struct gfs2_sbd *sdp, int silent, int undo) | 242 | static int init_sb(struct gfs2_sbd *sdp, int silent, int undo) |
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 36c523d487a7..7fb74484af63 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
@@ -860,18 +860,19 @@ static struct inode *try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked) | |||
860 | { | 860 | { |
861 | struct inode *inode; | 861 | struct inode *inode; |
862 | u32 goal = 0; | 862 | u32 goal = 0; |
863 | u64 ino; | 863 | u64 no_addr; |
864 | 864 | ||
865 | for(;;) { | 865 | for(;;) { |
866 | goal = rgblk_search(rgd, goal, GFS2_BLKST_UNLINKED, | 866 | goal = rgblk_search(rgd, goal, GFS2_BLKST_UNLINKED, |
867 | GFS2_BLKST_UNLINKED); | 867 | GFS2_BLKST_UNLINKED); |
868 | if (goal == 0) | 868 | if (goal == 0) |
869 | return 0; | 869 | return 0; |
870 | ino = goal + rgd->rd_data0; | 870 | no_addr = goal + rgd->rd_data0; |
871 | if (ino <= *last_unlinked) | 871 | if (no_addr <= *last_unlinked) |
872 | continue; | 872 | continue; |
873 | *last_unlinked = ino; | 873 | *last_unlinked = no_addr; |
874 | inode = gfs2_inode_lookup(rgd->rd_sbd->sd_vfs, ino, DT_UNKNOWN); | 874 | inode = gfs2_inode_lookup(rgd->rd_sbd->sd_vfs, DT_UNKNOWN, |
875 | no_addr, 0); | ||
875 | if (!IS_ERR(inode)) | 876 | if (!IS_ERR(inode)) |
876 | return inode; | 877 | return inode; |
877 | } | 878 | } |