在 2024/12/25 6:53, NeilBrown 写道:
On Tue, 17 Dec 2024, Yang Erkun wrote:
From: Yang Erkun <yangerkun@xxxxxxxxxx>
After f8c989a0c89a ("nfsd: release svc_expkey/svc_export with
rcu_work"), svc_export_put/expkey_put will call path_put with async
mode. This can lead some unexpected failure:
mkdir /mnt/sda
mkfs.xfs -f /dev/sda
echo "/ *(rw,no_root_squash,fsid=0)" > /etc/exports
echo "/mnt *(rw,no_root_squash,fsid=1)" >> /etc/exports
exportfs -ra
service nfs-server start
mount -t nfs -o vers=4.0 127.0.0.1:/mnt /mnt1
mount /dev/sda /mnt/sda
touch /mnt1/sda/file
exportfs -r
umount /mnt/sda # failed unexcepted
The touch above will finally call nfsd_cross_mnt, add refcount to mount,
and then add cache_head. Before this commit, exportfs -r will call
cache_flush to cleanup all cache_head, and path_put in
svc_export_put/expkey_put will be finished with sync mode. So, the
latter umount will always success. However, after this commit, path_put
will be called with async mode, the latter umount may failed, and if we
add some delay, umount will success too. Personally I think this bug and
should be fixed. We first revert before bugfix patch, and then fix the
original bug with a different way.
Thanks for these patches. I think they are certainly a better approach
to fixing the problem - well done.
My only thought was that instead of changing how cache_check() works, we
could introduce cache_check_rcu() which doesn't drop the ref.
cache_check() would then just call that then optionally drop the ref.
I'm not convinced that is better, so I'm just mentioning it in case
anyone else wants to agree. I'm happy for the patch set to be applied
as-is.
Reviewed-By: NeilBrown <neilb@xxxxxxx>
Thanks a lot for your review!
Yeah, keep cache_check and give a separate function cache_check_rcu will
make code more clean. Thanks for your advise!
Thanks,
NeilBrown