Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 5 Apr 2011 17:27:46 +0200
From:      Gary Jennejohn <gljennjohn@googlemail.com>
To:        Kostik Belousov <kostikbel@gmail.com>
Cc:        freebsd-fs@freebsd.org
Subject:   Re: Knob to turn off _POSIX_NO_TRUNC
Message-ID:  <20110405172746.4a02fe42@ernst.jennejohn.org>
In-Reply-To: <20110405141631.GA78089@deviant.kiev.zoral.com.ua>
References:  <20110405141631.GA78089@deviant.kiev.zoral.com.ua>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, 5 Apr 2011 17:16:31 +0300
Kostik Belousov <kostikbel@gmail.com> wrote:

> From very old and gloomy SysV times I remembered filesystem behaviour
> that silently truncated the file name components to the NAME_MAX limit,
> that was, AFAIR, 14. To much of my dismay, I met some usermode software
> recently that blindly tried to create the file from externally provided
> name, and sometimes failed with ENAMETOOLONG in similar situation.
> The authors are not cooperative.
> 
> I ended up with the following hack, which almost turns off the
> _POSIX_NO_TRUNC behaviour, globally on the system. Patch allowed me
> to proceed. The cost in the default case is a single check, which is
> performed only on ENAMETOOLONG path.
> 
> I am too chicken to commit it without prior discussion.
> 
> diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c
> index 50a2570..e9e7697 100644
> --- a/sys/kern/vfs_lookup.c
> +++ b/sys/kern/vfs_lookup.c
> @@ -99,6 +99,11 @@ SYSCTL_INT(_vfs, OID_AUTO, lookup_shared, CTLFLAG_RW, &lookup_shared, 0,
>      "Enables/Disables shared locks for path name translation");
>  TUNABLE_INT("vfs.lookup_shared", &lookup_shared);
>  
> +static int lookup_trim;
> +SYSCTL_INT(_vfs, OID_AUTO, lookup_trim, CTLFLAG_RW, &lookup_trim, 0,
> +    "Enables/Disables trim of the long path component instead of ENAMETOOLONG");
> +TUNABLE_INT("vfs.lookup_trim", &lookup_trim);
> +
>  /*
>   * Convert a pathname into a pointer to a locked vnode.
>   *
> @@ -514,8 +519,14 @@ dirloop:
>  		continue;
>  	cnp->cn_namelen = cp - cnp->cn_nameptr;
>  	if (cnp->cn_namelen > NAME_MAX) {
> -		error = ENAMETOOLONG;
> -		goto bad;
> +		if (!lookup_trim) {

I would intuitively expect trimming to be enabled when the sysctl is set
to 1, but this is exactly the opposite of that.  I personally would
initialize it to 1.

> +			error = ENAMETOOLONG;
> +			goto bad;
> +		}
> +		ndp->ni_pathlen -= cnp->cn_namelen - NAME_MAX;
> +		cnp->cn_namelen = NAME_MAX;
> +		strcpy(cnp->cn_nameptr + cnp->cn_namelen, cp);
> +		cp = cnp->cn_nameptr + cnp->cn_namelen;
>  	}
>  #ifdef NAMEI_DIAGNOSTIC
>  	{ char c = *cp;

I must admit that I don't care for hacks like this to suit the vagaries
of some idiot software developers who never heard of POSIX.  But as long
as it's off by default, then I guess it would be acceptable.

-- 
Gary Jennejohn (gj@)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20110405172746.4a02fe42>