|
@@ -613,46 +613,6 @@ static int gfs2_ri_update(struct gfs2_inode *ip)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- * gfs2_ri_update_special - Pull in a new resource index from the disk
|
|
|
- *
|
|
|
- * This is a special version that's safe to call from gfs2_inplace_reserve_i.
|
|
|
- * In this case we know that we don't have any resource groups in memory yet.
|
|
|
- *
|
|
|
- * @ip: pointer to the rindex inode
|
|
|
- *
|
|
|
- * Returns: 0 on successful update, error code otherwise
|
|
|
- */
|
|
|
-static int gfs2_ri_update_special(struct gfs2_inode *ip)
|
|
|
-{
|
|
|
- struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
|
|
- struct inode *inode = &ip->i_inode;
|
|
|
- struct file_ra_state ra_state;
|
|
|
- struct gfs2_rgrpd *rgd;
|
|
|
- unsigned int max_data = 0;
|
|
|
- int error;
|
|
|
-
|
|
|
- file_ra_state_init(&ra_state, inode->i_mapping);
|
|
|
- for (sdp->sd_rgrps = 0;; sdp->sd_rgrps++) {
|
|
|
- /* Ignore partials */
|
|
|
- if ((sdp->sd_rgrps + 1) * sizeof(struct gfs2_rindex) >
|
|
|
- i_size_read(inode))
|
|
|
- break;
|
|
|
- error = read_rindex_entry(ip, &ra_state);
|
|
|
- if (error) {
|
|
|
- clear_rgrpdi(sdp);
|
|
|
- return error;
|
|
|
- }
|
|
|
- }
|
|
|
- list_for_each_entry(rgd, &sdp->sd_rindex_list, rd_list)
|
|
|
- if (rgd->rd_data > max_data)
|
|
|
- max_data = rgd->rd_data;
|
|
|
- sdp->sd_max_rg_data = max_data;
|
|
|
-
|
|
|
- sdp->sd_rindex_uptodate = 1;
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
/**
|
|
|
* gfs2_rindex_hold - Grab a lock on the rindex
|
|
|
* @sdp: The GFS2 superblock
|
|
@@ -1226,16 +1186,25 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, int hold_rindex,
|
|
|
error = gfs2_rindex_hold(sdp, &al->al_ri_gh);
|
|
|
else if (!sdp->sd_rgrps) /* We may not have the rindex read
|
|
|
in, so: */
|
|
|
- error = gfs2_ri_update_special(ip);
|
|
|
+ error = gfs2_ri_update(ip);
|
|
|
if (error)
|
|
|
return error;
|
|
|
}
|
|
|
|
|
|
+try_again:
|
|
|
do {
|
|
|
error = get_local_rgrp(ip, &last_unlinked);
|
|
|
/* If there is no space, flushing the log may release some */
|
|
|
- if (error)
|
|
|
+ if (error) {
|
|
|
+ if (ip == GFS2_I(sdp->sd_rindex) &&
|
|
|
+ !sdp->sd_rindex_uptodate) {
|
|
|
+ error = gfs2_ri_update(ip);
|
|
|
+ if (error)
|
|
|
+ return error;
|
|
|
+ goto try_again;
|
|
|
+ }
|
|
|
gfs2_log_flush(sdp, NULL);
|
|
|
+ }
|
|
|
} while (error && tries++ < 3);
|
|
|
|
|
|
if (error) {
|