svn commit: r319734 - in head/sys: compat/freebsd32 kern
Konstantin Belousov
kib at FreeBSD.org
Fri Jun 9 11:17:09 UTC 2017
Author: kib
Date: Fri Jun 9 11:17:08 2017
New Revision: 319734
URL: https://svnweb.freebsd.org/changeset/base/319734
Log:
Enhance vfs.ino64_trunc_error sysctl.
Provide a new mode "2" which returns a special overflow indicator in
the non-representable field instead of the silent truncation (mode
"0") or EOVERFLOW (mode "1").
In particular, the typical use of st_ino to detect hard links with
mode "2" reports false positives, which might be more suitable for
some uses.
Discussed with: bde
Sponsored by: The FreeBSD Foundation
Modified:
head/sys/compat/freebsd32/freebsd32_misc.c
head/sys/kern/vfs_syscalls.c
Modified: head/sys/compat/freebsd32/freebsd32_misc.c
==============================================================================
--- head/sys/compat/freebsd32/freebsd32_misc.c Fri Jun 9 07:08:58 2017 (r319733)
+++ head/sys/compat/freebsd32/freebsd32_misc.c Fri Jun 9 11:17:08 2017 (r319734)
@@ -1911,11 +1911,31 @@ freebsd11_cvtstat32(struct stat *in, struct freebsd11_
{
CP(*in, *out, st_ino);
- if (in->st_ino != out->st_ino && ino64_trunc_error)
- return (EOVERFLOW);
+ if (in->st_ino != out->st_ino) {
+ switch (ino64_trunc_error) {
+ default:
+ case 0:
+ break;
+ case 1:
+ return (EOVERFLOW);
+ case 2:
+ out->st_ino = UINT32_MAX;
+ break;
+ }
+ }
CP(*in, *out, st_nlink);
- if (in->st_nlink != out->st_nlink && ino64_trunc_error)
- return (EOVERFLOW);
+ if (in->st_nlink != out->st_nlink) {
+ switch (ino64_trunc_error) {
+ default:
+ case 0:
+ break;
+ case 1:
+ return (EOVERFLOW);
+ case 2:
+ out->st_nlink = UINT16_MAX;
+ break;
+ }
+ }
CP(*in, *out, st_dev);
CP(*in, *out, st_mode);
CP(*in, *out, st_uid);
Modified: head/sys/kern/vfs_syscalls.c
==============================================================================
--- head/sys/kern/vfs_syscalls.c Fri Jun 9 07:08:58 2017 (r319733)
+++ head/sys/kern/vfs_syscalls.c Fri Jun 9 11:17:08 2017 (r319734)
@@ -2117,12 +2117,32 @@ freebsd11_cvtstat(struct stat *st, struct freebsd11_st
ost->st_dev = st->st_dev;
ost->st_ino = st->st_ino;
- if (ost->st_ino != st->st_ino && ino64_trunc_error)
- return (EOVERFLOW);
+ if (ost->st_ino != st->st_ino) {
+ switch (ino64_trunc_error) {
+ default:
+ case 0:
+ break;
+ case 1:
+ return (EOVERFLOW);
+ case 2:
+ ost->st_ino = UINT32_MAX;
+ break;
+ }
+ }
ost->st_mode = st->st_mode;
ost->st_nlink = st->st_nlink;
- if (ost->st_nlink != st->st_nlink && ino64_trunc_error)
- return (EOVERFLOW);
+ if (ost->st_nlink != st->st_nlink) {
+ switch (ino64_trunc_error) {
+ default:
+ case 0:
+ break;
+ case 1:
+ return (EOVERFLOW);
+ case 2:
+ ost->st_nlink = UINT16_MAX;
+ break;
+ }
+ }
ost->st_uid = st->st_uid;
ost->st_gid = st->st_gid;
ost->st_rdev = st->st_rdev;
@@ -3751,8 +3771,19 @@ freebsd11_kern_getdirentries(struct thread *td, int fd
dstdp.d_type = dp->d_type;
dstdp.d_namlen = dp->d_namlen;
dstdp.d_fileno = dp->d_fileno; /* truncate */
- if (dstdp.d_fileno != dp->d_fileno && ino64_trunc_error)
- continue;
+ if (dstdp.d_fileno != dp->d_fileno) {
+ switch (ino64_trunc_error) {
+ default:
+ case 0:
+ break;
+ case 1:
+ error = EOVERFLOW;
+ goto done;
+ case 2:
+ dstdp.d_fileno = UINT32_MAX;
+ break;
+ }
+ }
dstdp.d_reclen = sizeof(dstdp) - sizeof(dstdp.d_name) +
((dp->d_namlen + 1 + 3) &~ 3);
bcopy(dp->d_name, dstdp.d_name, dstdp.d_namlen);
More information about the svn-src-all
mailing list