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
This commit is contained in:
parent
de24bcb8b3
commit
f703462277
@ -1911,11 +1911,31 @@ freebsd11_cvtstat32(struct stat *in, struct freebsd11_stat32 *out)
|
||||
{
|
||||
|
||||
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);
|
||||
|
@ -2117,12 +2117,32 @@ freebsd11_cvtstat(struct stat *st, struct freebsd11_stat *ost)
|
||||
|
||||
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, char *ubuf, u_int count,
|
||||
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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user