--- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c @@ -681,6 +681,10 @@ static void do_qc(struct gfs2_quota_data *qd, s64 change) x = be64_to_cpu(qc->qc_change) + change; qc->qc_change = cpu_to_be64(x); + printk("qc-i_inode.i_ino: %d, qcid: %d,qc_change: %d, %s", + ip->i_inode.i_ino, + cpu_to_be32(from_kqid(&init_user_ns, qd->qd_id)), + qc->qc_change, __func__); spin_lock(&qd_lock); qd->qd_change = x; @@ -972,6 +976,7 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda) gfs2_glock_dq_uninit(&ghs[qx]); inode_unlock(&ip->i_inode); kfree(ghs); + printk("error: %d, qd-i_inode.i_ino: %d, num_qd: %d, %s\n", error, ip->i_inode.i_ino, num_qd, __func__); gfs2_log_flush(ip->i_gl->gl_name.ln_sbd, ip->i_gl, GFS2_LOG_HEAD_FLUSH_NORMAL | GFS2_LFC_DO_SYNC); out: @@ -1323,6 +1328,9 @@ int gfs2_quota_sync(struct super_block *sb, int type) for (x = 0; x < num_qd; x++) qd_unlock(qda[x]); + + if (error == -EIO) + gfs2_quota_cleanup(sdp); } } while (!error && num_qd == max_qd); @@ -1362,6 +1370,7 @@ int gfs2_quota_init(struct gfs2_sbd *sdp) u64 dblock; u32 extlen = 0; int error; + u32 qcid = 0; if (gfs2_check_internal_file_size(sdp->sd_qc_inode, 1, 64 << 20)) return -EIO; @@ -1376,6 +1385,7 @@ int gfs2_quota_init(struct gfs2_sbd *sdp) __GFP_ZERO); if (!sdp->sd_quota_bitmap) return error; + qcid = ip->i_inode.i_ino; for (x = 0; x < blocks; x++) { struct buffer_head *bh; @@ -1442,7 +1452,7 @@ int gfs2_quota_init(struct gfs2_sbd *sdp) } if (found) - fs_info(sdp, "found %u quota changes\n", found); + fs_info(sdp, "found %u quota changes, i_ino:%d, i_height: %d\n", found, qcid, ip->i_height); return 0; @@ -1459,6 +1469,8 @@ void gfs2_quota_cleanup(struct gfs2_sbd *sdp) spin_lock(&qd_lock); while (!list_empty(head)) { qd = list_last_entry(head, struct gfs2_quota_data, qd_list); + if (qd->qd_lockref.count > 0) + continue; list_del(&qd->qd_list); @@ -1471,6 +1483,7 @@ void gfs2_quota_cleanup(struct gfs2_sbd *sdp) hlist_bl_del_rcu(&qd->qd_hlist); spin_unlock_bucket(qd->qd_hash); + fs_info(sdp, "qc_id:%d\n", cpu_to_be32(from_kqid(&init_user_ns, qd->qd_id))); gfs2_assert_warn(sdp, !qd->qd_change); gfs2_assert_warn(sdp, !qd->qd_slot_count); gfs2_assert_warn(sdp, !qd->qd_bh_count);