PERFORCE change 102658 for review
John Baldwin
jhb at FreeBSD.org
Fri Jul 28 16:24:21 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=102658
Change 102658 by jhb at jhb_mutex on 2006/07/28 16:24:09
- Explicitly lock Giant to protect all of the fields in the stream
structure except st_family (read-only field only set when the
stream structure is created). This does mean holding it a lot in
getmsg() since it wants to read the previous command from putmsg()
and then set a new one when it's done.
- Mark svr4_sys_ioctl(), svr4_sys_getmsg(), and svr4_sys_putmsg()
MPSAFE.
Affected files ...
.. //depot/projects/smpng/sys/compat/svr4/svr4_stream.c#40 edit
.. //depot/projects/smpng/sys/compat/svr4/svr4_stropts.h#4 edit
.. //depot/projects/smpng/sys/compat/svr4/syscalls.master#23 edit
Differences ...
==== //depot/projects/smpng/sys/compat/svr4/svr4_stream.c#40 (text+ko) ====
@@ -1041,13 +1041,16 @@
return EINVAL;
}
+ mtx_lock(&Giant);
if (st->s_afd == -1) {
DPRINTF(("fdinsert: accept fd not found\n"));
+ mtx_unlock(&Giant);
return ENOENT;
}
if ((error = copyin(dat, &fdi, sizeof(fdi))) != 0) {
DPRINTF(("fdinsert: copyin failed %d\n", error));
+ mtx_unlock(&Giant);
return error;
}
@@ -1057,16 +1060,19 @@
if ((error = dup2(td, &d2p)) != 0) {
DPRINTF(("fdinsert: dup2(%d, %d) failed %d\n",
st->s_afd, fdi.fd, error));
+ mtx_unlock(&Giant);
return error;
}
if ((error = kern_close(td, st->s_afd)) != 0) {
DPRINTF(("fdinsert: close(%d) failed %d\n",
st->s_afd, error));
+ mtx_unlock(&Giant);
return error;
}
st->s_afd = -1;
+ mtx_unlock(&Giant);
*retval = 0;
return 0;
@@ -1194,6 +1200,7 @@
oflags = td->td_retval[0];
/* update the flags */
+ mtx_lock(&Giant);
if (dat != NULL) {
int mask;
@@ -1212,6 +1219,7 @@
flags = oflags & ~O_ASYNC;
st->s_eventmask = 0;
}
+ mtx_unlock(&Giant);
/* set the new flags, if changed */
if (flags != oflags) {
@@ -1236,7 +1244,7 @@
u_long cmd;
caddr_t dat;
{
- int error;
+ int error, eventmask;
if (dat != NULL) {
struct svr4_strm *st = svr4_stream_get(fp);
@@ -1245,8 +1253,11 @@
DPRINTF(("i_getsig: bad file descriptor\n"));
return EINVAL;
}
- if ((error = copyout(&st->s_eventmask, dat,
- sizeof(st->s_eventmask))) != 0) {
+ mtx_lock(&Giant);
+ eventmask = st->s_eventmask;
+ mtx_unlock(&Giant);
+ if ((error = copyout(&eventmask, dat,
+ sizeof(eventmask))) != 0) {
DPRINTF(("i_getsig: bad eventmask pointer\n"));
return error;
}
@@ -1569,7 +1580,10 @@
return ENOSYS;
}
- switch (st->s_cmd = sc.cmd) {
+ mtx_lock(&Giant);
+ st->s_cmd = sc.cmd;
+ mtx_unlock(&Giant);
+ switch (sc.cmd) {
case SVR4_TI_CONNECT_REQUEST: /* connect */
{
@@ -1701,6 +1715,7 @@
return ENOSYS;
}
+ mtx_lock(&Giant);
switch (st->s_cmd) {
case SVR4_TI_CONNECT_REQUEST:
DPRINTF(("getmsg: TI_CONNECT_REQUEST\n"));
@@ -1726,6 +1741,7 @@
error = kern_getpeername(td, uap->fd, &sa, &sasize);
if (error) {
+ mtx_unlock(&Giant);
DPRINTF(("getmsg: getpeername failed %d\n", error));
return error;
}
@@ -1748,6 +1764,7 @@
break;
default:
+ mtx_unlock(&Giant);
free(sa, M_SONAME);
return ENOSYS;
}
@@ -1782,6 +1799,7 @@
error = kern_accept(td, uap->fd, &sa, &sasize, &afp);
if (error) {
+ mtx_unlock(&Giant);
DPRINTF(("getmsg: accept failed %d\n", error));
return error;
}
@@ -1814,6 +1832,7 @@
fdclose(td->td_proc->p_fd, afp, st->s_afd, td);
fdrop(afp, td);
st->s_afd = -1;
+ mtx_unlock(&Giant);
free(sa, M_SONAME);
return ENOSYS;
}
@@ -1832,8 +1851,10 @@
if (ctl.len > sizeof(sc))
ctl.len = sizeof(sc);
- if ((error = copyin(ctl.buf, &sc, ctl.len)) != 0)
+ if ((error = copyin(ctl.buf, &sc, ctl.len)) != 0) {
+ mtx_unlock(&Giant);
return error;
+ }
switch (st->s_family) {
case AF_INET:
@@ -1847,6 +1868,7 @@
break;
default:
+ mtx_unlock(&Giant);
return ENOSYS;
}
@@ -1862,6 +1884,7 @@
error = kern_recvit(td, uap->fd, &msg, UIO_SYSSPACE, NULL);
if (error) {
+ mtx_unlock(&Giant);
DPRINTF(("getmsg: recvit failed %d\n", error));
return error;
}
@@ -1880,6 +1903,7 @@
break;
default:
+ mtx_unlock(&Giant);
return ENOSYS;
}
@@ -1908,6 +1932,7 @@
ra.buf = dat.buf;
ra.nbyte = dat.maxlen;
if ((error = read(td, &ra)) != 0) {
+ mtx_unlock(&Giant);
return error;
}
dat.len = *retval;
@@ -1915,6 +1940,7 @@
st->s_cmd = SVR4_TI_SENDTO_REQUEST;
break;
}
+ mtx_unlock(&Giant);
DPRINTF(("getmsg: Unknown state %x\n", st->s_cmd));
return EINVAL;
}
@@ -1945,8 +1971,10 @@
fdrop(afp, td);
st->s_afd = -1;
}
+ mtx_unlock(&Giant);
return (error);
}
+ mtx_unlock(&Giant);
if (afp)
fdrop(afp, td);
==== //depot/projects/smpng/sys/compat/svr4/svr4_stropts.h#4 (text+ko) ====
@@ -116,12 +116,16 @@
* Our internal state for the stream
* For now we keep almost nothing... In the future we can keep more
* streams state.
+ *
+ * Locking key:
+ * r - Read only field only set during creation
+ * G - Giant
*/
struct svr4_strm {
- int s_family; /* socket family */
- int s_cmd; /* last getmsg reply or putmsg request */
- int s_afd; /* last accepted fd; [for fd_insert] */
- int s_eventmask; /* state info from I_SETSIG et al */
+ int s_family; /* (r) socket family */
+ int s_cmd; /* (G) last getmsg reply or putmsg request */
+ int s_afd; /* (G) last accepted fd; [for fd_insert] */
+ int s_eventmask; /* (G) state info from I_SETSIG et al */
};
/*
==== //depot/projects/smpng/sys/compat/svr4/syscalls.master#23 (text+ko) ====
@@ -104,7 +104,7 @@
int a3, int a4, int a5); }
53 AUE_NULL MSTD { int svr4_sys_semsys(int what, int a2, \
int a3, int a4, int a5); }
-54 AUE_NULL STD { int svr4_sys_ioctl(int fd, u_long com, \
+54 AUE_NULL MSTD { int svr4_sys_ioctl(int fd, u_long com, \
caddr_t data); }
55 AUE_NULL UNIMPL uadmin
56 AUE_NULL UNIMPL exch
@@ -141,10 +141,10 @@
82 AUE_NULL UNIMPL libattach
83 AUE_NULL UNIMPL libdetach
84 AUE_NULL UNIMPL sysfs
-85 AUE_NULL STD { int svr4_sys_getmsg(int fd, \
+85 AUE_NULL MSTD { int svr4_sys_getmsg(int fd, \
struct svr4_strbuf *ctl, \
struct svr4_strbuf *dat, int *flags); }
-86 AUE_NULL STD { int svr4_sys_putmsg(int fd, \
+86 AUE_NULL MSTD { int svr4_sys_putmsg(int fd, \
struct svr4_strbuf *ctl, \
struct svr4_strbuf *dat, int flags); }
87 AUE_NULL MSTD { int svr4_sys_poll(struct pollfd *fds, \
More information about the p4-projects
mailing list