Knob to turn off _POSIX_NO_TRUNC
Gary Jennejohn
gljennjohn at googlemail.com
Tue Apr 5 15:27:51 UTC 2011
On Tue, 5 Apr 2011 17:16:31 +0300
Kostik Belousov <kostikbel at 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@)
More information about the freebsd-fs
mailing list