commit 30b9fa486ce20a1788b463dad7c856d13ba05c48 Author: Abhijith Das <adas@redhat.com> Date: Mon May 10 11:51:02 2010 -0500 gfs2_convert: gfs2_convert doesn't convert quota files With this patch, gfs2_convert now assigns the metadata and data blocks of the old quota file to the newly created quota inode in the master directory. Instead of having a initialized quota file, we now have a quota file that preserves all teh quota information from the gfs1 filesystem. Resolves: rhbz#589820 Signed-off-by: Abhi Das <adas@redhat.com> diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c index 8835a5b..b8a8cd9 100644 --- a/gfs2/convert/gfs2_convert.c +++ b/gfs2/convert/gfs2_convert.c @@ -333,6 +333,7 @@ static void fix_metatree(struct gfs2_sbd *sbp, struct gfs2_inode *ip, bh = ip->i_bh; /* First, build up the metatree */ for (h = 0; h < blk->height; h++) { + new = 0; lookup_block(ip, bh, h, &blk->mp, 1, &new, &block); if (bh != ip->i_bh) brelse(bh); @@ -652,8 +653,6 @@ void fix_jdatatree(struct gfs2_sbd *sbp, struct gfs2_inode *ip, mh.mh_type = GFS2_METATYPE_IN; mh.mh_format = GFS2_FORMAT_IN; - /* This condition should never arise. - We're always dealing with unstuffed inodes */ if (!ip->i_di.di_height) unstuff_dinode(ip); @@ -665,6 +664,7 @@ void fix_jdatatree(struct gfs2_sbd *sbp, struct gfs2_inode *ip, /* First, build up the metatree */ for (h = 0; h < blk->height; h++) { + new = 0; lookup_block(ip, bh, h, &blk->mp, 1, &new, &block); if (bh != ip->i_bh) brelse(bh); @@ -830,7 +830,7 @@ int adjust_jdata_inode(struct gfs2_sbd *sbp, struct gfs2_inode *ip) unsigned int len; blk = osi_list_entry(tmp, struct blocklist, list); - /* If it's not a data block at the highest level */ + /* If it's not a highest level indirect block */ if (blk->height != di_height - 1) { osi_list_del(tmp); free(blk->ptrbuf); @@ -1256,7 +1256,8 @@ static int process_dirent_info(struct gfs2_inode *dip, struct gfs2_sbd *sbp, if (inum.no_formal_ino) { /* if not a sentinel (placeholder) */ error = fetch_inum(sbp, inum.no_addr, &inum, NULL); if (error) { - log_crit("Error retrieving inode %" PRIx64 "\n", inum.no_addr); + log_crit("Error retrieving inode %" PRIx64 "\n", + (long unsigned int) inum.no_addr); break; } /* fix the dirent's inode number from the fetched inum. */ @@ -1849,7 +1850,7 @@ static int journ_space_to_rg(struct gfs2_sbd *sdp) rgdhigh = rgd; } /* for each rg */ log_info("Addr %" PRIx64 " comes after rg at addr %" PRIx64 "\n", - jndx->ji_addr, rgdhigh->ri.ri_addr); + jndx->ji_addr, (long unsigned int)(rgdhigh->ri.ri_addr)); if (!rgdhigh) { /* if we somehow didn't find one. */ log_crit("Error: No suitable rg found for journal.\n"); return -1; @@ -2103,6 +2104,40 @@ static int check_fit(struct gfs2_sbd *sdp) return blks_avail > blks_need; } +/* We fetch the old quota inode block and copy the contents of the block + * (minus the struct gfs2_dinode) into the new quota block. We update the + * inode height/size of the new quota file to that of the old one and set the + * old quota inode height/size to zero, so only the inode block gets freed. + */ +static void copy_quotas(struct gfs2_sbd *sdp) +{ + struct gfs2_inum inum; + struct gfs2_inode *oq_ip, *nq_ip; + int err; + + err = gfs2_lookupi(sdp->master_dir, "quota", 5, &nq_ip); + if (err) + die("Couldn't lookup new quota file: %d\n", err); + + gfs2_inum_in(&inum, (char *)&raw_gfs1_ondisk_sb.sb_quota_di); + oq_ip = inode_read(sdp, inum.no_addr); + + nq_ip->i_di.di_height = oq_ip->i_di.di_height; + nq_ip->i_di.di_size = oq_ip->i_di.di_size; + memcpy(nq_ip->i_bh->b_data + sizeof(struct gfs2_dinode), + oq_ip->i_bh->b_data + sizeof(struct gfs2_dinode), + sdp->bsize - sizeof(struct gfs2_dinode)); + + oq_ip->i_di.di_height = 0; + oq_ip->i_di.di_size = 0; + + bmodified(nq_ip->i_bh); + inode_put(&nq_ip); + + bmodified(oq_ip->i_bh); + inode_put(&oq_ip); +} + /* ------------------------------------------------------------------------- */ /* main - mainline code */ /* ------------------------------------------------------------------------- */ @@ -2221,6 +2256,15 @@ int main(int argc, char **argv) /* Create the quota file */ build_quota(&sb2); + /* Copy out the master dinode */ + { + struct gfs2_inode *ip = sb2.master_dir; + if (ip->i_bh->b_modified) + gfs2_dinode_out(&ip->i_di, ip->i_bh); + } + /* Copy old quotas */ + copy_quotas(&sb2); + update_inode_file(&sb2); /* Now delete the now-obsolete gfs1 files: */ remove_obsolete_gfs1(&sb2);