aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2017-12-19 19:18:48 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2017-12-19 19:18:48 +0000
commita0a073b16d0ca366a263137fb9dda4950fd75720 (patch)
treecbe8cb27cd14c6c29aa674df9f29c888a02fdee1
parent4a627952604a89c352586a71a7e4d281ed3da3a3 (diff)
downloadsrc-a0a073b16d0ca366a263137fb9dda4950fd75720.tar.gz
src-a0a073b16d0ca366a263137fb9dda4950fd75720.zip
Update NFS to handle larger link counts post ino64.
- Define a NFS_LINK_MAX as UINT32_MAX to match the wire protocol. - Use NFS_LINK_MAX instead of LINK_MAX as the fallback value reported for a PATHCONF RPC by the NFS server. - Use NFS_LINK_MAX instead of LINK_MAX as the default value reported by the NFS client pathconf() if not overridden by the NFS server. - When reading the link count out of an RPC reply, read the full 32 bits instead of the lower 16 bits. Reviewed by: rmacklem (earlier version) Sponsored by: Chelsio Communications
Notes
Notes: svn path=/head/; revision=326991
-rw-r--r--sys/fs/nfs/nfs_commonport.c2
-rw-r--r--sys/fs/nfs/nfs_commonsubs.c4
-rw-r--r--sys/fs/nfs/nfsproto.h2
-rw-r--r--sys/fs/nfsclient/nfs_clcomsubs.c2
-rw-r--r--sys/fs/nfsclient/nfs_clvnops.c4
5 files changed, 8 insertions, 6 deletions
diff --git a/sys/fs/nfs/nfs_commonport.c b/sys/fs/nfs/nfs_commonport.c
index e36bfed8cc85..ece5626d83cc 100644
--- a/sys/fs/nfs/nfs_commonport.c
+++ b/sys/fs/nfs/nfs_commonport.c
@@ -331,7 +331,7 @@ nfsvno_pathconf(struct vnode *vp, int flag, register_t *retf,
*/
switch (flag) {
case _PC_LINK_MAX:
- *retf = LINK_MAX;
+ *retf = NFS_LINK_MAX;
break;
case _PC_NAME_MAX:
*retf = NAME_MAX;
diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c
index 5e91a4942f59..dc441cecef0c 100644
--- a/sys/fs/nfs/nfs_commonsubs.c
+++ b/sys/fs/nfs/nfs_commonsubs.c
@@ -883,7 +883,7 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp,
NFSV3_FSFHOMOGENEOUS | NFSV3_FSFCANSETTIME);
}
if (pc != NULL) {
- pc->pc_linkmax = LINK_MAX;
+ pc->pc_linkmax = NFS_LINK_MAX;
pc->pc_namemax = NAME_MAX;
pc->pc_notrunc = 0;
pc->pc_chownrestricted = 0;
@@ -1320,7 +1320,7 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp,
NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
if (compare) {
if (!(*retcmpp)) {
- if (fxdr_unsigned(int, *tl) != LINK_MAX)
+ if (fxdr_unsigned(int, *tl) != NFS_LINK_MAX)
*retcmpp = NFSERR_NOTSAME;
}
} else if (pc != NULL) {
diff --git a/sys/fs/nfs/nfsproto.h b/sys/fs/nfs/nfsproto.h
index 90731ef770db..6c96081df9f1 100644
--- a/sys/fs/nfs/nfsproto.h
+++ b/sys/fs/nfs/nfsproto.h
@@ -785,6 +785,8 @@ struct nfs_fattr {
#define fa3_mtime fa_un.fa_nfsv3.nfsv3fa_mtime
#define fa3_ctime fa_un.fa_nfsv3.nfsv3fa_ctime
+#define NFS_LINK_MAX UINT32_MAX
+
struct nfsv2_sattr {
u_int32_t sa_mode;
u_int32_t sa_uid;
diff --git a/sys/fs/nfsclient/nfs_clcomsubs.c b/sys/fs/nfsclient/nfs_clcomsubs.c
index 94a253f83f16..6194343378bd 100644
--- a/sys/fs/nfsclient/nfs_clcomsubs.c
+++ b/sys/fs/nfsclient/nfs_clcomsubs.c
@@ -433,7 +433,7 @@ nfsm_loadattr(struct nfsrv_descript *nd, struct nfsvattr *nap)
nap->na_mode = fxdr_unsigned(u_short, fp->fa_mode);
nap->na_rdev = makedev(fxdr_unsigned(u_char, fp->fa3_rdev.specdata1),
fxdr_unsigned(u_char, fp->fa3_rdev.specdata2));
- nap->na_nlink = fxdr_unsigned(u_short, fp->fa_nlink);
+ nap->na_nlink = fxdr_unsigned(uint32_t, fp->fa_nlink);
nap->na_uid = fxdr_unsigned(uid_t, fp->fa_uid);
nap->na_gid = fxdr_unsigned(gid_t, fp->fa_gid);
nap->na_size = fxdr_hyper(&fp->fa3_size);
diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c
index d33162cd6e45..fd9ecb0d210f 100644
--- a/sys/fs/nfsclient/nfs_clvnops.c
+++ b/sys/fs/nfsclient/nfs_clvnops.c
@@ -3450,7 +3450,7 @@ nfs_pathconf(struct vop_pathconf_args *ap)
* For NFSv2 (or NFSv3 when not one of the above 4 a_names),
* just fake them.
*/
- pc.pc_linkmax = LINK_MAX;
+ pc.pc_linkmax = NFS_LINK_MAX;
pc.pc_namemax = NFS_MAXNAMLEN;
pc.pc_notrunc = 1;
pc.pc_chownrestricted = 1;
@@ -3460,7 +3460,7 @@ nfs_pathconf(struct vop_pathconf_args *ap)
}
switch (ap->a_name) {
case _PC_LINK_MAX:
- *ap->a_retval = pc.pc_linkmax;
+ *ap->a_retval = MIN(LONG_MAX, pc.pc_linkmax);
break;
case _PC_NAME_MAX:
*ap->a_retval = pc.pc_namemax;