Re: 6f283634 / 1976b2b3 breaks NFS (QNAP/Linux kNFSD)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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;

[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux