Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 5 Apr 2011 17:16:31 +0300
From:      Kostik Belousov <kostikbel@gmail.com>
To:        freebsd-fs@freebsd.org
Subject:   Knob to turn off _POSIX_NO_TRUNC
Message-ID:  <20110405141631.GA78089@deviant.kiev.zoral.com.ua>

next in thread | raw e-mail | index | archive | help

--FYjy/y/1gvMuB097
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

=46rom 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, &l=
ookup_shared, 0,
     "Enables/Disables shared locks for path name translation");
 TUNABLE_INT("vfs.lookup_shared", &lookup_shared);
=20
+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 ENAMETOOL=
ONG");
+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 =3D cp - cnp->cn_nameptr;
 	if (cnp->cn_namelen > NAME_MAX) {
-		error =3D ENAMETOOLONG;
-		goto bad;
+		if (!lookup_trim) {
+			error =3D ENAMETOOLONG;
+			goto bad;
+		}
+		ndp->ni_pathlen -=3D cnp->cn_namelen - NAME_MAX;
+		cnp->cn_namelen =3D NAME_MAX;
+		strcpy(cnp->cn_nameptr + cnp->cn_namelen, cp);
+		cp =3D cnp->cn_nameptr + cnp->cn_namelen;
 	}
 #ifdef NAMEI_DIAGNOSTIC
 	{ char c =3D *cp;

--FYjy/y/1gvMuB097
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (FreeBSD)

iEYEARECAAYFAk2bJD4ACgkQC3+MBN1Mb4j8JgCdHDI6bfeegkO1rSFiIf8RblPC
YnoAoNl3bJkPaEcn07P6xUaurYrxo3PW
=Ntd5
-----END PGP SIGNATURE-----

--FYjy/y/1gvMuB097--



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