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>

index | next in thread | raw e-mail

[-- Attachment #1 --]
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) {
+			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;

[-- Attachment #2 --]
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (FreeBSD)

iEYEARECAAYFAk2bJD4ACgkQC3+MBN1Mb4j8JgCdHDI6bfeegkO1rSFiIf8RblPC
YnoAoNl3bJkPaEcn07P6xUaurYrxo3PW
=Ntd5
-----END PGP SIGNATURE-----
home | help

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