After an absence of 9 years, I make my triumphant return to sys/nfs. There are some silly programs out there (looking at you boost) that actually use pathconf instead of just hard coding 1024 for max path length. If you run them from nfs, fireworks ensue.
Here's a pathconf implementation for nfs, copied mostly from ufs. Even if some of these values are lies, they're better than nothing. My theory is that the values you care about (NAME_MAX, PATH_MAX) are going to be right, and the values you don't (REC_MAX_XFER_SIZE) are harmless even if incorrect. Index: nfs_vnops.c =================================================================== RCS file: /cvs/src/sys/nfs/nfs_vnops.c,v retrieving revision 1.140 diff -u -p -r1.140 nfs_vnops.c --- nfs_vnops.c 17 Nov 2012 22:28:26 -0000 1.140 +++ nfs_vnops.c 26 Mar 2013 07:04:53 -0000 @@ -61,6 +61,7 @@ #include <sys/hash.h> #include <sys/queue.h> #include <sys/specdev.h> +#include <sys/unistd.h> #include <uvm/uvm_extern.h> @@ -2937,19 +2938,70 @@ loop: /* * Return POSIX pathconf information applicable to nfs. - * - * The NFS V2 protocol doesn't support this, so just return EINVAL - * for V2. */ /* ARGSUSED */ int nfs_pathconf(void *v) { -#if 0 struct vop_pathconf_args *ap = v; -#endif + struct nfsmount *nmp = VFSTONFS(ap->a_vp->v_mount); + int error = 0; - return (EINVAL); + switch (ap->a_name) { + case _PC_LINK_MAX: + *ap->a_retval = LINK_MAX; + break; + case _PC_NAME_MAX: + *ap->a_retval = NAME_MAX; + break; + case _PC_PATH_MAX: + *ap->a_retval = PATH_MAX; + break; + case _PC_PIPE_BUF: + *ap->a_retval = PIPE_BUF; + break; + case _PC_CHOWN_RESTRICTED: + *ap->a_retval = 1; + break; + case _PC_NO_TRUNC: + *ap->a_retval = 1; + break; + case _PC_PRIO_IO: + *ap->a_retval = 0; + break; + case _PC_SYNC_IO: + *ap->a_retval = 0; + break; + case _PC_ALLOC_SIZE_MIN: + *ap->a_retval = NFS_FABLKSIZE; + break; + case _PC_FILESIZEBITS: + *ap->a_retval = 64; + break; + case _PC_REC_INCR_XFER_SIZE: + *ap->a_retval = min(nmp->nm_rsize, nmp->nm_wsize); + break; + case _PC_REC_MAX_XFER_SIZE: + *ap->a_retval = -1; /* means ``unlimited'' */ + break; + case _PC_REC_MIN_XFER_SIZE: + *ap->a_retval = min(nmp->nm_rsize, nmp->nm_wsize); + break; + case _PC_REC_XFER_ALIGN: + *ap->a_retval = PAGE_SIZE; + break; + case _PC_SYMLINK_MAX: + *ap->a_retval = MAXPATHLEN; + break; + case _PC_2_SYMLINKS: + *ap->a_retval = 1; + break; + default: + error = EINVAL; + break; + } + + return (error); } /*