mfc linux_stats.c:1.86 to releng_6 - fifoor fix
John E Hein
jhein at timing.com
Tue Jun 3 19:21:23 UTC 2008
Can someone MFC to 6.x Junk-uk Kim's fix for the linux block-on-a-fifo
problem (rev 1.86 of linux_stats.c)?
I've been running with it for nearly two years now without a problem.
It's already in RELENG_7.
I prepared a patch against RELENG_6 to make it easier...
Index: sys/compat/linux/linux_stats.c
===================================================================
RCS file: /base/FreeBSD-CVS/src/sys/compat/linux/linux_stats.c,v
retrieving revision 1.72.2.8
diff -u -p -r1.72.2.8 linux_stats.c
--- sys/compat/linux/linux_stats.c 9 Jan 2008 16:07:32 -0000 1.72.2.8
+++ sys/compat/linux/linux_stats.c 3 Jun 2008 15:57:55 -0000
@@ -99,23 +99,16 @@ static void
translate_fd_major_minor(struct thread *td, int fd, struct stat *buf)
{
struct file *fp;
- int error;
int major, minor;
- if ((error = fget(td, fd, &fp)) != 0)
+ if ((!S_ISCHR(buf->st_mode) && !S_ISBLK(buf->st_mode)) ||
+ fget(td, fd, &fp) != 0)
return;
- if (fp->f_vnode) {
- if (fp->f_vnode->v_type == VCHR
- || fp->f_vnode->v_type == VBLK) {
- if (fp->f_vnode->v_un.vu_cdev) {
- if (linux_driver_get_major_minor(
- fp->f_vnode->v_un.vu_cdev->si_name,
- &major, &minor) == 0) {
- buf->st_rdev = (major << 8 | minor);
- }
- }
- }
- }
+ if (fp->f_vnode != NULL &&
+ fp->f_vnode->v_un.vu_cdev != NULL &&
+ linux_driver_get_major_minor(fp->f_vnode->v_un.vu_cdev->si_name,
+ &major, &minor) == 0)
+ buf->st_rdev = (major << 8 | minor);
fdrop(fp, td);
}
@@ -128,6 +121,8 @@ translate_path_major_minor(struct thread
int fd;
int temp;
+ if (!S_ISCHR(buf->st_mode) && !S_ISBLK(buf->st_mode))
+ return;
temp = td->td_retval[0];
if (kern_open(td, path, UIO_SYSSPACE, O_RDONLY, 0) != 0)
return;
@@ -178,18 +173,19 @@ linux_newstat(struct thread *td, struct
#endif
error = kern_stat(td, path, UIO_SYSSPACE, &buf);
- if (!error && strlen(path) > strlen("/dev/pts/") &&
- !strncmp(path, "/dev/pts/", strlen("/dev/pts/"))
- && path[9] >= '0' && path[9] <= '9') {
- /*
- * Linux checks major and minors of the slave device to make
- * sure it's a pty device, so let's make him believe it is.
- */
- buf.st_rdev = (136 << 8);
- }
-
- translate_path_major_minor(td, path, &buf);
-
+ if (!error) {
+ if (strlen(path) > strlen("/dev/pts/") &&
+ !strncmp(path, "/dev/pts/", strlen("/dev/pts/")) &&
+ path[9] >= '0' && path[9] <= '9') {
+ /*
+ * Linux checks major and minors of the slave device
+ * to make sure it's a pty device, so let's make him
+ * believe it is.
+ */
+ buf.st_rdev = (136 << 8);
+ } else
+ translate_path_major_minor(td, path, &buf);
+ }
LFREEPATH(path);
if (error)
return (error);
More information about the freebsd-emulation
mailing list