Hi Olga, thanks for coming back! On 23.02.22 15:22, Olga Kornievskaia wrote:
Hi Kurt, I apologize for the late response. I have looked at the network trace. The problem stems from the broken server that claims to support fs_locations but then decides to never reply to the query. I can implement a mount option to say fs_locquery=off to handle mounts against the broken servers? However I would like to ask if the better path forward isn't to update to the knfsd where the problem is fixed?
Well, I have ran self-compiled kernels on Qnap appliances before (to work around Qnap's ext4 breakage when doing the case-independent name lookup), but it was a painful and cumbersome process and I don't want to repeat it. Appliances are not meant to use with custom kernels. Even if I do: This does not help many many other users ... Unless we convince Qnap to provide patches for old appliances, we'll experience breakage. On my end, I have applied the attached patch, restricting the use of FS_LOCATIONS to servers that advertize NFS v4.2 or later. In the patch, you'll also see clearing the bit before it gets set. This was spotted by seth, see https://bbs.archlinux.org/viewtopic.php?pid=2023983#p2023983 In latest upstream kernels you'd also need to clear NFS_CAP_CASE_PRESERVING | NFS_CAP_CASE_INSENSITIVE so I wonder whether we should not just nullify the caps bit field prior to testing and selectively setting flags. With this patch, I can mount NFS volumes from Qnap knfsd again without any special workarounds (such as nfsver=3 or the to-be-implemented setting that you suggest). I have no idea whether or not we leave a lot features behind by restricting FS_LOCATIONS on the client side to servers >= NFS v4.2. But certainly better than breaking in a -stable kernel update, even if the server might be to blame. Best, -- Kurt Garloff <kurt@xxxxxxxxxx> Cologne, Germany
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 389fa72d4ca9..fc29daf00a72 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -3880,8 +3880,8 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f res.attr_bitmask[2] &= FATTR4_WORD2_NFS42_MASK; } memcpy(server->attr_bitmask, res.attr_bitmask, sizeof(server->attr_bitmask)); - server->caps &= ~(NFS_CAP_ACLS | NFS_CAP_HARDLINKS | - NFS_CAP_SYMLINKS| NFS_CAP_SECURITY_LABEL); + server->caps &= ~(NFS_CAP_ACLS | NFS_CAP_HARDLINKS | NFS_CAP_SYMLINKS + | NFS_CAP_SECURITY_LABEL | NFS_CAP_FS_LOCATIONS); server->fattr_valid = NFS_ATTR_FATTR_V4; if (res.attr_bitmask[0] & FATTR4_WORD0_ACL && res.acl_bitmask & ACL4_SUPPORT_ALLOW_ACL) @@ -3894,7 +3894,8 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f if (res.attr_bitmask[2] & FATTR4_WORD2_SECURITY_LABEL) server->caps |= NFS_CAP_SECURITY_LABEL; #endif - if (res.attr_bitmask[0] & FATTR4_WORD0_FS_LOCATIONS) + /* Restrict FS_LOCATIONS to NFS v4.2+ to work around Qnap knfsd-3.4.6 bug */ + if (res.attr_bitmask[0] & FATTR4_WORD0_FS_LOCATIONS && minorversion >= 2) server->caps |= NFS_CAP_FS_LOCATIONS; if (!(res.attr_bitmask[0] & FATTR4_WORD0_FILEID)) server->fattr_valid &= ~NFS_ATTR_FATTR_FILEID;