I found a workaround. By using option '--host' in rpc.nfsd(8), it will creating the socket from user space, then passing the file descriptor to kernel via /proc/fs/nfsd/portlist; thus bypasses the previously mentioned socket creation code in kernel.
So to listen on IPv4 only, pass option '--host=0.0.0.0' to rpc.nfsd(8). For Debian Bullseye and early releases, add this option to 'RPCNFSDOPTS' variable of file /etc/default/nfs-kernel-server; for example: RPCNFSDOPTS="--no-udp --host=0.0.0.0" For later releases, simply set the 'host' directive under '[nfsd]' section. Now I have: # netstat -nl | grep -F :2049 tcp 0 0 0.0.0.0:2049 0.0.0.0:* LISTEN