--- 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, qi-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: @@ -1321,6 +1326,9 @@ int gfs2_quota_sync(struct super_block *sb, int type) qda[x]->qd_sync_gen = sdp->sd_quota_sync_gen; + if (error == -EIO) + break; + for (x = 0; x < num_qd; x++) qd_unlock(qda[x]); } @@ -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; @@ -1454,11 +1464,12 @@ int gfs2_quota_init(struct gfs2_sbd *sdp) void gfs2_quota_cleanup(struct gfs2_sbd *sdp) { struct list_head *head = &sdp->sd_quota_list; - struct gfs2_quota_data *qd; + struct gfs2_quota_data *qd, *safe; spin_lock(&qd_lock); - while (!list_empty(head)) { - qd = list_last_entry(head, struct gfs2_quota_data, qd_list); + list_for_each_entry_safe(qd, safe, head, qd_list) { + if (qd->qd_lockref.count > 0) + qd_unlock(qd); list_del(&qd->qd_list); @@ -1471,6 +1482,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); @@ -1484,8 +1496,10 @@ void gfs2_quota_cleanup(struct gfs2_sbd *sdp) gfs2_assert_warn(sdp, !atomic_read(&sdp->sd_quota_count)); - kvfree(sdp->sd_quota_bitmap); - sdp->sd_quota_bitmap = NULL; + if (sdp->sd_quota_bitmap) { + kvfree(sdp->sd_quota_bitmap); + sdp->sd_quota_bitmap = NULL; + } } static void quotad_error(struct gfs2_sbd *sdp, const char *msg, int error) --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -1332,10 +1332,13 @@ int gfs2_glock_holder_ready(struct gfs2_holder *gh) int gfs2_glock_wait(struct gfs2_holder *gh) { unsigned long start_time = jiffies; + struct gfs2_sbd *sdp = gh->gh_gl->gl_name.ln_sbd; might_sleep(); wait_on_bit(&gh->gh_iflags, HIF_WAIT, TASK_UNINTERRUPTIBLE); gfs2_glock_update_hold_time(gh->gh_gl, start_time); + if (sdp->sd_quota_inode == gh->gh_gl->gl_object) + return gh->gh_error; return gfs2_glock_holder_ready(gh); }