|
@@ -577,6 +577,13 @@ struct gfs2_rgrpd *gfs2_rgrpd_get_next(struct gfs2_rgrpd *rgd)
|
|
|
return rgd;
|
|
|
}
|
|
|
|
|
|
+void check_and_update_goal(struct gfs2_inode *ip)
|
|
|
+{
|
|
|
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
|
|
+ if (!ip->i_goal || gfs2_blk2rgrpd(sdp, ip->i_goal, 1) == NULL)
|
|
|
+ ip->i_goal = ip->i_no_addr;
|
|
|
+}
|
|
|
+
|
|
|
void gfs2_free_clones(struct gfs2_rgrpd *rgd)
|
|
|
{
|
|
|
int x;
|
|
@@ -1910,6 +1917,7 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, const struct gfs2_alloc_parms *a
|
|
|
} else if (ip->i_rgd && rgrp_contains_block(ip->i_rgd, ip->i_goal)) {
|
|
|
rs->rs_rbm.rgd = begin = ip->i_rgd;
|
|
|
} else {
|
|
|
+ check_and_update_goal(ip);
|
|
|
rs->rs_rbm.rgd = begin = gfs2_blk2rgrpd(sdp, ip->i_goal, 1);
|
|
|
}
|
|
|
if (S_ISDIR(ip->i_inode.i_mode) && (ap->aflags & GFS2_AF_ORLOV))
|
|
@@ -2089,7 +2097,7 @@ static struct gfs2_rgrpd *rgblk_free(struct gfs2_sbd *sdp, u64 bstart,
|
|
|
u32 blen, unsigned char new_state)
|
|
|
{
|
|
|
struct gfs2_rbm rbm;
|
|
|
- struct gfs2_bitmap *bi;
|
|
|
+ struct gfs2_bitmap *bi, *bi_prev = NULL;
|
|
|
|
|
|
rbm.rgd = gfs2_blk2rgrpd(sdp, bstart, 1);
|
|
|
if (!rbm.rgd) {
|
|
@@ -2098,18 +2106,22 @@ static struct gfs2_rgrpd *rgblk_free(struct gfs2_sbd *sdp, u64 bstart,
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
+ gfs2_rbm_from_block(&rbm, bstart);
|
|
|
while (blen--) {
|
|
|
- gfs2_rbm_from_block(&rbm, bstart);
|
|
|
bi = rbm_bi(&rbm);
|
|
|
- bstart++;
|
|
|
- if (!bi->bi_clone) {
|
|
|
- bi->bi_clone = kmalloc(bi->bi_bh->b_size,
|
|
|
- GFP_NOFS | __GFP_NOFAIL);
|
|
|
- memcpy(bi->bi_clone + bi->bi_offset,
|
|
|
- bi->bi_bh->b_data + bi->bi_offset, bi->bi_len);
|
|
|
+ if (bi != bi_prev) {
|
|
|
+ if (!bi->bi_clone) {
|
|
|
+ bi->bi_clone = kmalloc(bi->bi_bh->b_size,
|
|
|
+ GFP_NOFS | __GFP_NOFAIL);
|
|
|
+ memcpy(bi->bi_clone + bi->bi_offset,
|
|
|
+ bi->bi_bh->b_data + bi->bi_offset,
|
|
|
+ bi->bi_len);
|
|
|
+ }
|
|
|
+ gfs2_trans_add_meta(rbm.rgd->rd_gl, bi->bi_bh);
|
|
|
+ bi_prev = bi;
|
|
|
}
|
|
|
- gfs2_trans_add_meta(rbm.rgd->rd_gl, bi->bi_bh);
|
|
|
gfs2_setbit(&rbm, false, new_state);
|
|
|
+ gfs2_rbm_incr(&rbm);
|
|
|
}
|
|
|
|
|
|
return rbm.rgd;
|