Date: Fri, 12 Nov 2010 00:54:34 +1100 (EST) From: Bruce Evans <brde@optusnet.com.au> To: Mark Blackman <mark@exonetric.com> Cc: freebsd-fs@freebsd.org Subject: Re: ZFS and pathconf(_PC_NO_TRUNC) Message-ID: <20101112002522.V1372@besplex.bde.org> In-Reply-To: <86371A88-1474-4A51-8C84-05C4A71A9135@exonetric.com> References: <871369D9-7D63-4CE0-BB87-B8C46A62B271@exonetric.com> <201011111206.oABC6VYG027663@higson.cam.lispworks.com> <86371A88-1474-4A51-8C84-05C4A71A9135@exonetric.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, 11 Nov 2010, Mark Blackman wrote: > On 11 Nov 2010, at 12:06, Martin Simmons wrote: >> Your call to printf is clobbering the real errno, which is EINVAL. > > Doh! thanks for pointing that out. :) > >> That is an >> allowed value according to the pathconf man page: >> >> [EINVAL] The implementation does not support an association of >> the variable name with the associated file. >> >> So it is correct, but maybe not useful. > > hmm. this is popping up in the context of building perl 5.12 on a zfs-only > filesystem. One of the POSIX::* tests fails because of the above. zfs_vnops.c:zfs_pathconf() is missing _PC_NO_TRUNC, so it seems to be just broken (it returns EOPNOTSUPP for cases not in the switch, so there seems to be no way for another level to support _PC_NO_TRUNC). It apparently depends on another layer providing defaults. Other basic things missing in it: _PC_NAME_MAX _PC_CHOWN_RESTRICTED _PC_PIPE_BUF [several other things that are in the switch statement in vop_stdpathconf(), but which are nonsense there since they only apply to device files and should depend on the file anyway, and which don't apply to zfs or any normal file system since device files on normal file systems are no longer supported] _PC_PIPE_BUF is not quite like the features that onluy apply to device files. It aplies to named pipes, and since there is no defaulting of _PC_* in FreeBSD, all file systems that support named pipes must support it in their pathconf vop although it has nothing to do with file systems. Fortunately, pathconf() is never used except by naive programs like perl :-). _PC_NAME_MAX is used by patch(1) in FreeBSD, but patch(1) also has an ifdef tangle using _POSIX_NAME_MAX and other messes which I think allows patch to work accidentally if zfs returns EOPNOTSUPP: from backupfile.c: % void % addext(char *filename, char *ext, int e) % { % char *s = (char *)(uintptr_t)(const void *)basename (filename); % int slen = strlen (s), extlen = strlen (ext); % long slen_max = -1; % % #if HAVE_PATHCONF && defined (_PC_NAME_MAX) % #ifndef _POSIX_NAME_MAX % #define _POSIX_NAME_MAX 14 % #endif _POSIX_NAME_MAX is always 14 on POSIX systems, so this ifdef is no help. % if (slen + extlen <= _POSIX_NAME_MAX) % /* The file name is so short there's no need to call pathconf. */ % slen_max = _POSIX_NAME_MAX; % else if (s == filename) % slen_max = pathconf (".", _PC_NAME_MAX); I think we get here and pathconf() fails for names of length just 15 or greater. % else % { % char c = *s; % *s = 0; % slen_max = pathconf (filename, _PC_NAME_MAX); % *s = c; % } % #endif % if (slen_max == -1) { % #ifdef HAVE_LONG_FILE_NAMES % slen_max = 255; We get here on error (since although FreeBSD only has long file names on some file systems, patch is misconfigured, possibly by configuring it on a normal file system that has long names, so HAVE_LONG_FILE_NAMES is set unconditionally in the hard-configured config.h), so the max is essentially hard-coded as 255 if pathconf() fails. % #else % slen_max = 14; % #endif % } Bruce
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20101112002522.V1372>