]> www.infradead.org Git - linux.git/commitdiff
ocfs2: cancel dqi_sync_work before freeing oinfo
authorJoseph Qi <joseph.qi@linux.alibaba.com>
Wed, 4 Sep 2024 07:10:03 +0000 (15:10 +0800)
committerAndrew Morton <akpm@linux-foundation.org>
Mon, 9 Sep 2024 22:15:54 +0000 (15:15 -0700)
ocfs2_global_read_info() will initialize and schedule dqi_sync_work at the
end, if error occurs after successfully reading global quota, it will
trigger the following warning with CONFIG_DEBUG_OBJECTS_* enabled:

ODEBUG: free active (active state 0) object: 00000000d8b0ce28 object type: timer_list hint: qsync_work_fn+0x0/0x16c

This reports that there is an active delayed work when freeing oinfo in
error handling, so cancel dqi_sync_work first.  BTW, return status instead
of -1 when .read_file_info fails.

Link: https://syzkaller.appspot.com/bug?extid=f7af59df5d6b25f0febd
Link: https://lkml.kernel.org/r/20240904071004.2067695-1-joseph.qi@linux.alibaba.com
Fixes: 171bf93ce11f ("ocfs2: Periodic quota syncing")
Signed-off-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Reviewed-by: Heming Zhao <heming.zhao@suse.com>
Reported-by: syzbot+f7af59df5d6b25f0febd@syzkaller.appspotmail.com
Tested-by: syzbot+f7af59df5d6b25f0febd@syzkaller.appspotmail.com
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Junxiao Bi <junxiao.bi@oracle.com>
Cc: Changwei Ge <gechangwei@live.cn>
Cc: Gang He <ghe@suse.com>
Cc: Jun Piao <piaojun@huawei.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
fs/ocfs2/quota_local.c

index 8ce462c64c51baed15cc42391f3a7ce1db0fb073..73d3367c533b8a212a65e73fa7f8fa979499e692 100644 (file)
@@ -692,7 +692,7 @@ static int ocfs2_local_read_info(struct super_block *sb, int type)
        int status;
        struct buffer_head *bh = NULL;
        struct ocfs2_quota_recovery *rec;
-       int locked = 0;
+       int locked = 0, global_read = 0;
 
        info->dqi_max_spc_limit = 0x7fffffffffffffffLL;
        info->dqi_max_ino_limit = 0x7fffffffffffffffLL;
@@ -700,6 +700,7 @@ static int ocfs2_local_read_info(struct super_block *sb, int type)
        if (!oinfo) {
                mlog(ML_ERROR, "failed to allocate memory for ocfs2 quota"
                               " info.");
+               status = -ENOMEM;
                goto out_err;
        }
        info->dqi_priv = oinfo;
@@ -712,6 +713,7 @@ static int ocfs2_local_read_info(struct super_block *sb, int type)
        status = ocfs2_global_read_info(sb, type);
        if (status < 0)
                goto out_err;
+       global_read = 1;
 
        status = ocfs2_inode_lock(lqinode, &oinfo->dqi_lqi_bh, 1);
        if (status < 0) {
@@ -782,10 +784,12 @@ out_err:
                if (locked)
                        ocfs2_inode_unlock(lqinode, 1);
                ocfs2_release_local_quota_bitmaps(&oinfo->dqi_chunk);
+               if (global_read)
+                       cancel_delayed_work_sync(&oinfo->dqi_sync_work);
                kfree(oinfo);
        }
        brelse(bh);
-       return -1;
+       return status;
 }
 
 /* Write local info to quota file */