<div>Здравствуйте!</div><div><br />> Здесь возможно опечатка. gfs2_log_shutdown()</div><div><div>> вызывается вроде как раз когда во флагах _не_</div><div>> выставлен GFS2_LOG_HEAD_FLUSH_NORMAL.</div><div> </div><div>Действительно, я опечатался, спасибо. Вызываем</div><div>gfs2_log_flush() с флагом GFS2_LOG_HEAD_FLUSH_NORMAL:</div><div><a href="https://elixir.bootlin.com/linux/v6.1.164/source/fs/gfs2/glops.c#L317)" rel="noopener noreferrer" target="_blank">https://elixir.bootlin.com/linux/v6.1.164/source/fs/gfs2/glops.c#L317</a></div><div> </div><div>> Пока предлагаю подробнее изучить коммит 35264909e9d1<br /><br />Вопросы понял, разбираюсь подробнее.<br /><br />Кузнецов Николай</div></div><blockquote><p>On Sat, 11. Apr 15:20, Николай Кузнецов wrote:</p><blockquote>    Здравствуйте! Отправляю исправленную версию<br />    рассуждений по предупреждению анализатора.<br /> <br />    Предупреждение было ошибочным, далее привожу<br />    обоснование.<br />    Согласно коммиту<br />    [1]<a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/fs/gfs2/log.c?id=35264909e9d1973ab9aaa2a1b07cda70f12bb828" rel="noopener noreferrer">https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/fs/gfs2/log.c?id=35264909e9d1973ab9aaa2a1b07cda70f12bb828</a>,<br />    нулевой указатель sdp->sd_jdesc приходит<br />    в gfs2_log_flush в ситуации гонки между<br />    размонтированием файловой системы и<br />    асинхронной обработки glock в workqueue.</blockquote><p><br />Хм, всё же уверены, что этот коммит валиден? Для этого стоит изучить,<br />действительно ли возможно состояние гонки, которое он правит: где<br />зануляется указатель sdp->sd_jdesc и как происходит жизненный цикл<br />работы &gl->gl_work.<br /> </p><blockquote> <br />    Однако при размонтировании журнал<br />    обнуляется уже после переведения фс<br />    в режим readonly и сброса всех изменений<br />    на диск, а задача из очереди вызывает<br />    gfs2_log_flush (по цепочке glock_work_func -><br />    run_queue -> do_xmote -> inode_go_sync -><br />    gfs2_log_flush) без флага<br />    GFS2_LOG_HEAD_FLUSH_NORMAL, а значит,<br />    до gfs2_log_shutdown (стр. 1139 log.c)<br />    исполнение функции просто не дойдёт.</blockquote><p><br />Здесь возможно опечатка. gfs2_log_shutdown() вызывается вроде как раз<br />когда во флагах _не_ выставлен GFS2_LOG_HEAD_FLUSH_NORMAL.<br /> </p><blockquote> <br />    Проблемы с вызовами log_write_header (строки<br />    1111 и 1113) тоже нет, поскольку перед обнулением<br />    журнала вызывается gfs2_log_flush с флагом<br />    GFS2_LOG_HEAD_FLUSH_SHUTDOWN и<br />    из-за вызовов log_pull_tail и gfs2_log_update_head<br />    при размонтировании не будут выполнены<br />    условия в строках 1110 и 1112.</blockquote><p><br />Как понимаю, речь идёт об условиях<br /><br />        if (sdp->sd_log_head != sdp->sd_log_flush_head) {<!-- --><br />                log_write_header(sdp, flags);<br />        } else if (sdp->sd_log_tail != sdp->sd_log_flush_tail && !sdp->sd_log_idle) {<!-- --><br />                log_write_header(sdp, flags);<br />        }<br /><br />и почему они не будут выполнены при shutdown? Не ясна связь с<br />log_pull_tail() и gfs2_log_update_head().<br /><br /><br />Разыменовывание возможно ещё по метке out_end в функции log_distance():<br /><a href="https://elixir.bootlin.com/linux/v6.1.164/source/fs/gfs2/log.c#L1143" rel="noopener noreferrer">https://elixir.bootlin.com/linux/v6.1.164/source/fs/gfs2/log.c#L1143</a><br /><br /><br />Пока предлагаю подробнее изучить коммит 35264909e9d1 ("gfs2: Fix NULL<br />pointer dereference in gfs2_log_flush"). Согласны ли с проблемой,<br />которую он правит?<br /> </p></blockquote>