}
if (IS_ERR(dent))
return PTR_ERR(dent);
- da->bh = bh;
- da->dent = dent;
+
+ if (da->save_loc) {
+ da->bh = bh;
+ da->dent = dent;
+ } else {
+ brelse(bh);
+ }
return 0;
}
unsigned nr_blocks;
struct gfs2_dirent *dent;
struct buffer_head *bh;
+ int save_loc;
};
extern struct inode *gfs2_dir_search(struct inode *dir,
{
INIT_LIST_HEAD(&gh->gh_list);
gh->gh_gl = gl;
- gh->gh_ip = (unsigned long)__builtin_return_address(0);
+ gh->gh_ip = _RET_IP_;
gh->gh_owner_pid = get_pid(task_pid(current));
gh->gh_state = state;
gh->gh_flags = flags;
gh->gh_state = state;
gh->gh_flags = flags;
gh->gh_iflags = 0;
- gh->gh_ip = (unsigned long)__builtin_return_address(0);
+ gh->gh_ip = _RET_IP_;
if (gh->gh_owner_pid)
put_pid(gh->gh_owner_pid);
gh->gh_owner_pid = get_pid(task_pid(current));
* tr->alloced is not set since the transaction structure is
* on the stack */
tr.tr_reserved = 1 + gfs2_struct2blk(sdp, tr.tr_revokes, sizeof(u64));
- tr.tr_ip = (unsigned long)__builtin_return_address(0);
+ tr.tr_ip = _RET_IP_;
sb_start_intwrite(sdp->sd_vfs);
if (gfs2_log_reserve(sdp, tr.tr_reserved) < 0) {
sb_end_intwrite(sdp->sd_vfs);
int error, free_vfs_inode = 0;
u32 aflags = 0;
unsigned blocks = 1;
- struct gfs2_diradd da = { .bh = NULL, };
+ struct gfs2_diradd da = { .bh = NULL, .save_loc = 1, };
if (!name->len || name->len > GFS2_FNAMESIZE)
return -ENAMETOOLONG;
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
gfs2_set_inode_blocks(inode, 1);
munge_mode_uid_gid(dip, inode);
+ check_and_update_goal(dip);
ip->i_goal = dip->i_goal;
ip->i_diskflags = 0;
ip->i_eattr = 0;
struct gfs2_inode *ip = GFS2_I(inode);
struct gfs2_holder ghs[2];
struct buffer_head *dibh;
- struct gfs2_diradd da = { .bh = NULL, };
+ struct gfs2_diradd da = { .bh = NULL, .save_loc = 1, };
int error;
if (S_ISDIR(inode->i_mode))
struct gfs2_rgrpd *nrgd;
unsigned int num_gh;
int dir_rename = 0;
- struct gfs2_diradd da = { .nr_blocks = 0, };
+ struct gfs2_diradd da = { .nr_blocks = 0, .save_loc = 0, };
unsigned int x;
int error;
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;
} 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))
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) {
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;
return rs && !RB_EMPTY_NODE(&rs->rs_node);
}
+extern void check_and_update_goal(struct gfs2_inode *ip);
#endif /* __RGRP_DOT_H__ */
if (!tr)
return -ENOMEM;
- tr->tr_ip = (unsigned long)__builtin_return_address(0);
+ tr->tr_ip = _RET_IP_;
tr->tr_blocks = blocks;
tr->tr_revokes = revokes;
tr->tr_reserved = 1;