Changeset View
Changeset View
Standalone View
Standalone View
sys/compat/linux/linux_stats.c
Show First 20 Lines • Show All 118 Lines • ▼ Show 20 Lines | if ((!S_ISCHR(buf->st_mode) && !S_ISBLK(buf->st_mode)) || | ||||
fget(td, fd, &cap_no_rights, &fp) != 0) | fget(td, fd, &cap_no_rights, &fp) != 0) | ||||
return; | return; | ||||
vp = fp->f_vnode; | vp = fp->f_vnode; | ||||
if (vp != NULL && vn_isdisk(vp, NULL)) { | if (vp != NULL && vn_isdisk(vp, NULL)) { | ||||
buf->st_mode &= ~S_IFMT; | buf->st_mode &= ~S_IFMT; | ||||
buf->st_mode |= S_IFBLK; | buf->st_mode |= S_IFBLK; | ||||
} | } | ||||
if (vp != NULL && vp->v_rdev != NULL && | if (vp != NULL && vp->v_rdev != NULL && | ||||
linux_driver_get_major_minor(devtoname(vp->v_rdev), | linux_driver_get_major_minor(devtoname(vp->v_rdev), | ||||
kib: I think you should add __compiler_barrier() after this line, so that compiler is not allowed to… | |||||
Not Done Inline Actions(unrelated) This is very buggy. First, v_rdev is a member of union, it only means something for char vnodes. Second, it is unsafe, r_dev can be invalidated any time. kib: (unrelated) This is very buggy. First, v_rdev is a member of union, it only means something… | |||||
Done Inline ActionsI wonder if I should just vn_lock() before doing all this? trasz: I wonder if I should just vn_lock() before doing all this?
| |||||
Not Done Inline Actionsvnode lock might be not enough to ensure stability of *v_rdev Look at vn_isdisk() to how to access v_rdev safely. kib: vnode lock might be not enough to ensure stability of *v_rdev
Look at vn_isdisk() to how to… | |||||
&major, &minor) == 0) { | &major, &minor) == 0) { | ||||
buf->st_rdev = (major << 8 | minor); | buf->st_rdev = (major << 8 | minor); | ||||
} else if (fp->f_type == DTYPE_PTS) { | } else if (fp->f_type == DTYPE_PTS) { | ||||
struct tty *tp = fp->f_data; | struct tty *tp = fp->f_data; | ||||
/* Convert the numbers for the slave device. */ | /* Convert the numbers for the slave device. */ | ||||
if (linux_driver_get_major_minor(devtoname(tp->t_dev), | if (linux_driver_get_major_minor(devtoname(tp->t_dev), | ||||
&major, &minor) == 0) { | &major, &minor) == 0) { | ||||
Show All 24 Lines | |||||
static int | static int | ||||
newstat_copyout(struct stat *buf, void *ubuf) | newstat_copyout(struct stat *buf, void *ubuf) | ||||
{ | { | ||||
struct l_newstat tbuf; | struct l_newstat tbuf; | ||||
bzero(&tbuf, sizeof(tbuf)); | bzero(&tbuf, sizeof(tbuf)); | ||||
tbuf.st_dev = dev_to_ldev(buf->st_dev); | tbuf.st_dev = dev_to_ldev(buf->st_dev); | ||||
/* | |||||
* Return the same st_dev for every devfs instance. The reason | |||||
* for this is to work around an idiosyncrasy of glibc getttynam() | |||||
* implementation: it checks whether st_dev returned for fd 0 | |||||
* is the same as st_dev returned for the target of /proc/self/fd/0 | |||||
* symlink, and with linux chroots having their own devfs instance, | |||||
* the check will fail if you chroot into it. | |||||
*/ | |||||
if ((S_ISCHR(buf->st_mode) || S_ISBLK(buf->st_mode)) && | |||||
rootdevmp != NULL) { | |||||
tbuf.st_dev = dev_to_ldev(rootdevmp->mnt_stat.f_fsid.val[0]); | |||||
} | |||||
tbuf.st_ino = buf->st_ino; | tbuf.st_ino = buf->st_ino; | ||||
tbuf.st_mode = buf->st_mode; | tbuf.st_mode = buf->st_mode; | ||||
tbuf.st_nlink = buf->st_nlink; | tbuf.st_nlink = buf->st_nlink; | ||||
tbuf.st_uid = buf->st_uid; | tbuf.st_uid = buf->st_uid; | ||||
tbuf.st_gid = buf->st_gid; | tbuf.st_gid = buf->st_gid; | ||||
tbuf.st_rdev = buf->st_rdev; | tbuf.st_rdev = buf->st_rdev; | ||||
tbuf.st_size = buf->st_size; | tbuf.st_size = buf->st_size; | ||||
tbuf.st_atim.tv_sec = buf->st_atim.tv_sec; | tbuf.st_atim.tv_sec = buf->st_atim.tv_sec; | ||||
▲ Show 20 Lines • Show All 504 Lines • Show Last 20 Lines |
I think you should add __compiler_barrier() after this line, so that compiler is not allowed to reload v_mount later.