diff options
| -rw-r--r-- | fs/gfs2/export.c | 36 | ||||
| -rw-r--r-- | fs/gfs2/rgrp.c | 42 | ||||
| -rw-r--r-- | fs/gfs2/rgrp.h | 4 | ||||
| -rw-r--r-- | fs/gfs2/super.c | 4 |
4 files changed, 51 insertions, 35 deletions
diff --git a/fs/gfs2/export.c b/fs/gfs2/export.c index 9200ef221716..d15876e9aa26 100644 --- a/fs/gfs2/export.c +++ b/fs/gfs2/export.c | |||
| @@ -143,17 +143,14 @@ static struct dentry *gfs2_get_parent(struct dentry *child) | |||
| 143 | } | 143 | } |
| 144 | 144 | ||
| 145 | static struct dentry *gfs2_get_dentry(struct super_block *sb, | 145 | static struct dentry *gfs2_get_dentry(struct super_block *sb, |
| 146 | struct gfs2_inum_host *inum) | 146 | struct gfs2_inum_host *inum) |
| 147 | { | 147 | { |
| 148 | struct gfs2_sbd *sdp = sb->s_fs_info; | 148 | struct gfs2_sbd *sdp = sb->s_fs_info; |
| 149 | struct gfs2_holder i_gh, ri_gh, rgd_gh; | 149 | struct gfs2_holder i_gh; |
| 150 | struct gfs2_rgrpd *rgd; | ||
| 151 | struct inode *inode; | 150 | struct inode *inode; |
| 152 | struct dentry *dentry; | 151 | struct dentry *dentry; |
| 153 | int error; | 152 | int error; |
| 154 | 153 | ||
| 155 | /* System files? */ | ||
| 156 | |||
| 157 | inode = gfs2_ilookup(sb, inum->no_addr); | 154 | inode = gfs2_ilookup(sb, inum->no_addr); |
| 158 | if (inode) { | 155 | if (inode) { |
| 159 | if (GFS2_I(inode)->i_no_formal_ino != inum->no_formal_ino) { | 156 | if (GFS2_I(inode)->i_no_formal_ino != inum->no_formal_ino) { |
| @@ -168,29 +165,11 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, | |||
| 168 | if (error) | 165 | if (error) |
| 169 | return ERR_PTR(error); | 166 | return ERR_PTR(error); |
| 170 | 167 | ||
| 171 | error = gfs2_rindex_hold(sdp, &ri_gh); | 168 | error = gfs2_check_blk_type(sdp, inum->no_addr, GFS2_BLKST_DINODE); |
| 172 | if (error) | 169 | if (error) |
| 173 | goto fail; | 170 | goto fail; |
| 174 | 171 | ||
| 175 | error = -EINVAL; | 172 | inode = gfs2_inode_lookup(sb, DT_UNKNOWN, inum->no_addr, 0, 0); |
| 176 | rgd = gfs2_blk2rgrpd(sdp, inum->no_addr); | ||
| 177 | if (!rgd) | ||
| 178 | goto fail_rindex; | ||
| 179 | |||
| 180 | error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_SHARED, 0, &rgd_gh); | ||
| 181 | if (error) | ||
| 182 | goto fail_rindex; | ||
| 183 | |||
| 184 | error = -ESTALE; | ||
| 185 | if (gfs2_get_block_type(rgd, inum->no_addr) != GFS2_BLKST_DINODE) | ||
| 186 | goto fail_rgd; | ||
| 187 | |||
| 188 | gfs2_glock_dq_uninit(&rgd_gh); | ||
| 189 | gfs2_glock_dq_uninit(&ri_gh); | ||
| 190 | |||
| 191 | inode = gfs2_inode_lookup(sb, DT_UNKNOWN, | ||
| 192 | inum->no_addr, | ||
| 193 | 0, 0); | ||
| 194 | if (IS_ERR(inode)) { | 173 | if (IS_ERR(inode)) { |
| 195 | error = PTR_ERR(inode); | 174 | error = PTR_ERR(inode); |
| 196 | goto fail; | 175 | goto fail; |
| @@ -224,13 +203,6 @@ out_inode: | |||
| 224 | if (!IS_ERR(dentry)) | 203 | if (!IS_ERR(dentry)) |
| 225 | dentry->d_op = &gfs2_dops; | 204 | dentry->d_op = &gfs2_dops; |
| 226 | return dentry; | 205 | return dentry; |
| 227 | |||
| 228 | fail_rgd: | ||
| 229 | gfs2_glock_dq_uninit(&rgd_gh); | ||
| 230 | |||
| 231 | fail_rindex: | ||
| 232 | gfs2_glock_dq_uninit(&ri_gh); | ||
| 233 | |||
| 234 | fail: | 206 | fail: |
| 235 | gfs2_glock_dq_uninit(&i_gh); | 207 | gfs2_glock_dq_uninit(&i_gh); |
| 236 | return ERR_PTR(error); | 208 | return ERR_PTR(error); |
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 388a61d12fc8..caaa665d4033 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
| @@ -1256,7 +1256,7 @@ void gfs2_inplace_release(struct gfs2_inode *ip) | |||
| 1256 | * Returns: The block type (GFS2_BLKST_*) | 1256 | * Returns: The block type (GFS2_BLKST_*) |
| 1257 | */ | 1257 | */ |
| 1258 | 1258 | ||
| 1259 | unsigned char gfs2_get_block_type(struct gfs2_rgrpd *rgd, u64 block) | 1259 | static unsigned char gfs2_get_block_type(struct gfs2_rgrpd *rgd, u64 block) |
| 1260 | { | 1260 | { |
| 1261 | struct gfs2_bitmap *bi = NULL; | 1261 | struct gfs2_bitmap *bi = NULL; |
| 1262 | u32 length, rgrp_block, buf_block; | 1262 | u32 length, rgrp_block, buf_block; |
| @@ -1694,6 +1694,46 @@ void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip) | |||
| 1694 | } | 1694 | } |
| 1695 | 1695 | ||
| 1696 | /** | 1696 | /** |
| 1697 | * gfs2_check_blk_type - Check the type of a block | ||
| 1698 | * @sdp: The superblock | ||
| 1699 | * @no_addr: The block number to check | ||
| 1700 | * @type: The block type we are looking for | ||
| 1701 | * | ||
| 1702 | * Returns: 0 if the block type matches the expected type | ||
| 1703 | * -ESTALE if it doesn't match | ||
| 1704 | * or -ve errno if something went wrong while checking | ||
| 1705 | */ | ||
| 1706 | |||
| 1707 | int gfs2_check_blk_type(struct gfs2_sbd *sdp, u64 no_addr, unsigned int type) | ||
| 1708 | { | ||
| 1709 | struct gfs2_rgrpd *rgd; | ||
| 1710 | struct gfs2_holder ri_gh, rgd_gh; | ||
| 1711 | int error; | ||
| 1712 | |||
| 1713 | error = gfs2_rindex_hold(sdp, &ri_gh); | ||
| 1714 | if (error) | ||
| 1715 | goto fail; | ||
| 1716 | |||
| 1717 | error = -EINVAL; | ||
| 1718 | rgd = gfs2_blk2rgrpd(sdp, no_addr); | ||
| 1719 | if (!rgd) | ||
| 1720 | goto fail_rindex; | ||
| 1721 | |||
| 1722 | error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_SHARED, 0, &rgd_gh); | ||
| 1723 | if (error) | ||
| 1724 | goto fail_rindex; | ||
| 1725 | |||
| 1726 | if (gfs2_get_block_type(rgd, no_addr) != type) | ||
| 1727 | error = -ESTALE; | ||
| 1728 | |||
| 1729 | gfs2_glock_dq_uninit(&rgd_gh); | ||
| 1730 | fail_rindex: | ||
| 1731 | gfs2_glock_dq_uninit(&ri_gh); | ||
| 1732 | fail: | ||
| 1733 | return error; | ||
| 1734 | } | ||
| 1735 | |||
| 1736 | /** | ||
| 1697 | * gfs2_rlist_add - add a RG to a list of RGs | 1737 | * gfs2_rlist_add - add a RG to a list of RGs |
| 1698 | * @sdp: the filesystem | 1738 | * @sdp: the filesystem |
| 1699 | * @rlist: the list of resource groups | 1739 | * @rlist: the list of resource groups |
diff --git a/fs/gfs2/rgrp.h b/fs/gfs2/rgrp.h index a8dedd78245b..b4106ddaaa98 100644 --- a/fs/gfs2/rgrp.h +++ b/fs/gfs2/rgrp.h | |||
| @@ -44,8 +44,6 @@ gfs2_inplace_reserve_i((ip), __FILE__, __LINE__) | |||
| 44 | 44 | ||
| 45 | extern void gfs2_inplace_release(struct gfs2_inode *ip); | 45 | extern void gfs2_inplace_release(struct gfs2_inode *ip); |
| 46 | 46 | ||
| 47 | extern unsigned char gfs2_get_block_type(struct gfs2_rgrpd *rgd, u64 block); | ||
| 48 | |||
| 49 | extern int gfs2_alloc_block(struct gfs2_inode *ip, u64 *bn, unsigned int *n); | 47 | extern int gfs2_alloc_block(struct gfs2_inode *ip, u64 *bn, unsigned int *n); |
| 50 | extern int gfs2_alloc_di(struct gfs2_inode *ip, u64 *bn, u64 *generation); | 48 | extern int gfs2_alloc_di(struct gfs2_inode *ip, u64 *bn, u64 *generation); |
| 51 | 49 | ||
| @@ -53,6 +51,8 @@ extern void gfs2_free_data(struct gfs2_inode *ip, u64 bstart, u32 blen); | |||
| 53 | extern void gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen); | 51 | extern void gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen); |
| 54 | extern void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip); | 52 | extern void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip); |
| 55 | extern void gfs2_unlink_di(struct inode *inode); | 53 | extern void gfs2_unlink_di(struct inode *inode); |
| 54 | extern int gfs2_check_blk_type(struct gfs2_sbd *sdp, u64 no_addr, | ||
| 55 | unsigned int type); | ||
| 56 | 56 | ||
| 57 | struct gfs2_rgrp_list { | 57 | struct gfs2_rgrp_list { |
| 58 | unsigned int rl_rgrps; | 58 | unsigned int rl_rgrps; |
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index d95cf777d244..0ec3ec672de1 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c | |||
| @@ -1286,6 +1286,10 @@ static void gfs2_delete_inode(struct inode *inode) | |||
| 1286 | goto out; | 1286 | goto out; |
| 1287 | } | 1287 | } |
| 1288 | 1288 | ||
| 1289 | error = gfs2_check_blk_type(sdp, ip->i_no_addr, GFS2_BLKST_UNLINKED); | ||
| 1290 | if (error) | ||
| 1291 | goto out_truncate; | ||
| 1292 | |||
| 1289 | gfs2_glock_dq_wait(&ip->i_iopen_gh); | 1293 | gfs2_glock_dq_wait(&ip->i_iopen_gh); |
| 1290 | gfs2_holder_reinit(LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, &ip->i_iopen_gh); | 1294 | gfs2_holder_reinit(LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, &ip->i_iopen_gh); |
| 1291 | error = gfs2_glock_nq(&ip->i_iopen_gh); | 1295 | error = gfs2_glock_nq(&ip->i_iopen_gh); |
