Well, you're right about one thing - the comment there says that it should
just return EINVAL for nfs v2 - and I think it should - but that code returns
EINVAL for v3 - and that's wrong.  We have server side support for this in v3
and what we should probably be doing is actually doing the rpc call to the v3
server in the v3 case and returning what it returns - and doing EINVAL
in the v2 case.


On Tue, Mar 26, 2013 at 1:12 AM, Ted Unangst <t...@tedunangst.com> wrote:
> 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);
>  }
>
>  /*
>
>

Reply via email to