Fix the ABI wrappers to use kern_fcntl() rather than calling fcntl()
directly. This removes a few more users of the stackgap and also marks the syscalls using these wrappers MP safe where appropriate. Tested on: i386 with linux acroread5 Compiled on: i386, alpha LINT
This commit is contained in:
parent
1c01d05f9c
commit
2ca25ab53e
@ -133,7 +133,7 @@
|
||||
89 STD { int linux_getdtablesize(void); }
|
||||
90 MNOPROTO { int dup2(u_int from, u_int to); }
|
||||
91 STD { int linux_newfstat(l_uint fd, struct l_newstat *buf); }
|
||||
92 STD { int linux_fcntl(l_uint fd, l_uint cmd, l_ulong arg); }
|
||||
92 MSTD { int linux_fcntl(l_uint fd, l_uint cmd, l_ulong arg); }
|
||||
93 STD { int osf1_select(u_int nd, fd_set *in, fd_set *ou, \
|
||||
fd_set *ex, struct timeval *tv); }
|
||||
94 NOPROTO { int poll(struct pollfd*, unsigned int nfds, long timeout); }
|
||||
|
@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/syscallsubr.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/sysent.h>
|
||||
#include <sys/sysproto.h>
|
||||
@ -758,19 +759,14 @@ osf1_fcntl(td, uap)
|
||||
{
|
||||
int error;
|
||||
long tmp;
|
||||
caddr_t oarg, sg;
|
||||
struct fcntl_args a;
|
||||
struct osf1_flock osf_flock;
|
||||
struct flock bsd_flock;
|
||||
struct flock *nflock;
|
||||
|
||||
error = 0;
|
||||
|
||||
switch (uap->cmd) {
|
||||
|
||||
case F_SETFL:
|
||||
a.fd = uap->fd;
|
||||
a.cmd = F_SETFL;
|
||||
/* need to translate flags here */
|
||||
tmp = 0;
|
||||
if ((long)uap->arg & OSF1_FNONBLOCK)
|
||||
@ -791,8 +787,7 @@ osf1_fcntl(td, uap)
|
||||
tmp |= FNDELAY;
|
||||
if ((long)uap->arg & OSF1_FSYNC)
|
||||
tmp |= FFSYNC;
|
||||
a.arg = tmp;
|
||||
error = fcntl(td, &a);
|
||||
error = kern_fcntl(td, uap->fd, F_SETFL, tmp);
|
||||
break;
|
||||
|
||||
case F_SETLK:
|
||||
@ -803,20 +798,15 @@ osf1_fcntl(td, uap)
|
||||
* the BSD one, but all else is the same. We must
|
||||
* reorder the one we've gotten so that flock() groks it.
|
||||
*/
|
||||
if ((error = copyin(uap->arg, &osf_flock, sizeof(osf_flock))))
|
||||
return error;
|
||||
error = copyin(uap->arg, &osf_flock, sizeof(osf_flock));
|
||||
if (error)
|
||||
return (error);
|
||||
bsd_flock.l_type = osf_flock.l_type;
|
||||
bsd_flock.l_whence = osf_flock.l_whence;
|
||||
bsd_flock.l_start = osf_flock.l_start;
|
||||
bsd_flock.l_len = osf_flock.l_len;
|
||||
bsd_flock.l_pid = osf_flock.l_pid;
|
||||
sg = stackgap_init();
|
||||
nflock = stackgap_alloc(&sg, sizeof(struct flock));
|
||||
if ((error = copyout(&bsd_flock, nflock, sizeof(bsd_flock))) != 0)
|
||||
return error;
|
||||
oarg = uap->arg;
|
||||
uap->arg = nflock;
|
||||
error = fcntl(td, (struct fcntl_args *) uap);
|
||||
error = kern_fcntl(td, uap->fd, uap->cmd, (intptr_t)&bsd_flock);
|
||||
/* if (error) {
|
||||
printf("fcntl called with cmd=%d, args=0x%lx\n returns %d\n",uap->cmd,(long)uap->arg,error);
|
||||
printf("bsd_flock.l_type = 0x%x\n", bsd_flock.l_type);
|
||||
@ -827,14 +817,17 @@ osf1_fcntl(td, uap)
|
||||
}
|
||||
*/
|
||||
if ((uap->cmd == F_GETLK) && !error) {
|
||||
/*
|
||||
* XXX: Why are we hardcoding F_UNLCK here instead of
|
||||
* copying the structure members from bsd_flock?
|
||||
*/
|
||||
osf_flock.l_type = F_UNLCK;
|
||||
if ((error = copyout(&osf_flock, oarg,
|
||||
sizeof(osf_flock))))
|
||||
return error;
|
||||
error = copyout(&osf_flock, uap->arg,
|
||||
sizeof(osf_flock));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
error = fcntl(td, (struct fcntl_args *) uap);
|
||||
error = kern_fcntl(td, uap->fd, uap->cmd, (intptr_t)uap->arg);
|
||||
|
||||
if ((uap->cmd == OSF1_F_GETFL) && !error ) {
|
||||
tmp = td->td_retval[0] & O_ACCMODE;
|
||||
|
@ -135,7 +135,7 @@
|
||||
89 MNOPROTO { int getdtablesize(void); }
|
||||
90 MNOPROTO { int dup2(u_int from, u_int to); }
|
||||
91 STD { int osf1_fstat(int fd, void *sb); }
|
||||
92 STD { int osf1_fcntl(int fd, int cmd, void *arg); }
|
||||
92 MSTD { int osf1_fcntl(int fd, int cmd, void *arg); }
|
||||
93 STD { int osf1_select(u_int nd, fd_set *in, fd_set *ou, \
|
||||
fd_set *ex, struct timeval *tv); }
|
||||
94 NOPROTO { int poll(struct pollfd *fds, u_int nfds, int timeout); }
|
||||
|
@ -674,12 +674,7 @@ linux_accept(struct thread *td, struct linux_accept_args *args)
|
||||
struct close_args /* {
|
||||
int fd;
|
||||
} */ c_args;
|
||||
struct fcntl_args /* {
|
||||
int fd;
|
||||
int cmd;
|
||||
long arg;
|
||||
} */ f_args;
|
||||
int error;
|
||||
int error, fd;
|
||||
|
||||
if ((error = copyin(args, &linux_args, sizeof(linux_args))))
|
||||
return (error);
|
||||
@ -705,11 +700,9 @@ linux_accept(struct thread *td, struct linux_accept_args *args)
|
||||
* accepted one, so we must clear the flags in the new descriptor.
|
||||
* Ignore any errors, because we already have an open fd.
|
||||
*/
|
||||
f_args.fd = td->td_retval[0];
|
||||
f_args.cmd = F_SETFL;
|
||||
f_args.arg = 0;
|
||||
(void)fcntl(td, &f_args);
|
||||
td->td_retval[0] = f_args.fd;
|
||||
fd = td->td_retval[0];
|
||||
(void)kern_fcntl(td, fd, F_SETFL, 0);
|
||||
td->td_retval[0] = fd;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/namei.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/syscallsubr.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/vnode.h>
|
||||
|
||||
@ -580,29 +581,24 @@ svr4_sys_fcntl(td, uap)
|
||||
register struct thread *td;
|
||||
struct svr4_sys_fcntl_args *uap;
|
||||
{
|
||||
int error;
|
||||
struct fcntl_args fa;
|
||||
int *retval;
|
||||
int cmd, error, *retval;
|
||||
|
||||
retval = td->td_retval;
|
||||
|
||||
fa.fd = uap->fd;
|
||||
fa.cmd = svr4_to_bsd_cmd(uap->cmd);
|
||||
cmd = svr4_to_bsd_cmd(uap->cmd);
|
||||
|
||||
switch (fa.cmd) {
|
||||
switch (cmd) {
|
||||
case F_DUPFD:
|
||||
case F_GETFD:
|
||||
case F_SETFD:
|
||||
fa.arg = (long) uap->arg;
|
||||
return fcntl(td, &fa);
|
||||
return (kern_fcntl(td, uap->fd, cmd, (intptr_t)uap->arg));
|
||||
|
||||
case F_GETFL:
|
||||
fa.arg = (long) uap->arg;
|
||||
error = fcntl(td, &fa);
|
||||
error = kern_fcntl(td, uap->fd, cmd, (intptr_t)uap->arg);
|
||||
if (error)
|
||||
return error;
|
||||
return (error);
|
||||
*retval = bsd_to_svr4_flags(*retval);
|
||||
return error;
|
||||
return (error);
|
||||
|
||||
case F_SETFL:
|
||||
{
|
||||
@ -610,55 +606,39 @@ svr4_sys_fcntl(td, uap)
|
||||
* we must save the O_ASYNC flag, as that is
|
||||
* handled by ioctl(_, I_SETSIG, _) emulation.
|
||||
*/
|
||||
long cmd;
|
||||
int flags;
|
||||
|
||||
DPRINTF(("Setting flags %p\n", uap->arg));
|
||||
cmd = fa.cmd; /* save it for a while */
|
||||
|
||||
fa.cmd = F_GETFL;
|
||||
if ((error = fcntl(td, &fa)) != 0)
|
||||
return error;
|
||||
error = kern_fcntl(td, uap->fd, F_GETFL, 0);
|
||||
if (error)
|
||||
return (error);
|
||||
flags = *retval;
|
||||
flags &= O_ASYNC;
|
||||
flags |= svr4_to_bsd_flags((u_long) uap->arg);
|
||||
fa.cmd = cmd;
|
||||
fa.arg = (long) flags;
|
||||
return fcntl(td, &fa);
|
||||
return (kern_fcntl(td, uap->fd, F_SETFL, flags));
|
||||
}
|
||||
|
||||
case F_GETLK:
|
||||
case F_SETLK:
|
||||
case F_SETLKW:
|
||||
{
|
||||
struct svr4_flock ifl;
|
||||
struct flock *flp, fl;
|
||||
caddr_t sg = stackgap_init();
|
||||
struct svr4_flock ifl;
|
||||
struct flock fl;
|
||||
|
||||
flp = stackgap_alloc(&sg, sizeof(struct flock));
|
||||
fa.arg = (long) flp;
|
||||
|
||||
error = copyin(uap->arg, &ifl, sizeof ifl);
|
||||
error = copyin(uap->arg, &ifl, sizeof (ifl));
|
||||
if (error)
|
||||
return error;
|
||||
return (error);
|
||||
|
||||
svr4_to_bsd_flock(&ifl, &fl);
|
||||
|
||||
error = copyout(&fl, flp, sizeof fl);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
error = fcntl(td, &fa);
|
||||
if (error || fa.cmd != F_GETLK)
|
||||
return error;
|
||||
|
||||
error = copyin(flp, &fl, sizeof fl);
|
||||
if (error)
|
||||
return error;
|
||||
error = kern_fcntl(td, uap->fd, cmd, (intptr_t)&fl);
|
||||
if (error || cmd != F_GETLK)
|
||||
return (error);
|
||||
|
||||
bsd_to_svr4_flock(&fl, &ifl);
|
||||
|
||||
return copyout(&ifl, uap->arg, sizeof ifl);
|
||||
return (copyout(&ifl, uap->arg, sizeof (ifl)));
|
||||
}
|
||||
case -1:
|
||||
switch (uap->cmd) {
|
||||
@ -692,36 +672,36 @@ svr4_sys_fcntl(td, uap)
|
||||
case SVR4_F_SETLK64:
|
||||
case SVR4_F_SETLKW64:
|
||||
{
|
||||
struct svr4_flock64 ifl;
|
||||
struct flock *flp, fl;
|
||||
caddr_t sg = stackgap_init();
|
||||
|
||||
flp = stackgap_alloc(&sg, sizeof(struct flock));
|
||||
fa.arg = (long) flp;
|
||||
struct svr4_flock64 ifl;
|
||||
struct flock fl;
|
||||
|
||||
switch (uap->cmd) {
|
||||
case SVR4_F_GETLK64:
|
||||
cmd = F_GETLK;
|
||||
break;
|
||||
case SVR4_F_SETLK64:
|
||||
cmd = F_SETLK;
|
||||
break;
|
||||
case SVR4_F_SETLKW64:
|
||||
cmd = F_SETLKW;
|
||||
break;
|
||||
}
|
||||
error = copyin(uap->arg, &ifl,
|
||||
sizeof ifl);
|
||||
sizeof (ifl));
|
||||
if (error)
|
||||
return error;
|
||||
return (error);
|
||||
|
||||
svr4_to_bsd_flock64(&ifl, &fl);
|
||||
|
||||
error = copyout(&fl, flp, sizeof fl);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
error = fcntl(td, &fa);
|
||||
if (error || fa.cmd != F_GETLK)
|
||||
return error;
|
||||
|
||||
error = copyin(flp, &fl, sizeof fl);
|
||||
if (error)
|
||||
return error;
|
||||
error = kern_fcntl(td, uap->fd, cmd,
|
||||
(intptr_t)&fl);
|
||||
if (error || cmd != F_GETLK)
|
||||
return (error);
|
||||
|
||||
bsd_to_svr4_flock64(&fl, &ifl);
|
||||
|
||||
return copyout(&ifl, uap->arg,
|
||||
sizeof ifl);
|
||||
return (copyout(&ifl, uap->arg,
|
||||
sizeof (ifl)));
|
||||
}
|
||||
|
||||
case SVR4_F_FREESP64:
|
||||
|
@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/syscallsubr.h>
|
||||
#include <sys/sysproto.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/ktrace.h> /* Must come after sys/uio.h */
|
||||
@ -1473,7 +1474,6 @@ i_setsig(fp, td, retval, fd, cmd, dat)
|
||||
* We alse have to fix the O_ASYNC fcntl bit, so the
|
||||
* process will get SIGPOLLs.
|
||||
*/
|
||||
struct fcntl_args fa;
|
||||
int error;
|
||||
register_t oflags, flags;
|
||||
struct svr4_strm *st = svr4_stream_get(fp);
|
||||
@ -1483,10 +1483,9 @@ i_setsig(fp, td, retval, fd, cmd, dat)
|
||||
return EINVAL;
|
||||
}
|
||||
/* get old status flags */
|
||||
fa.fd = fd;
|
||||
fa.cmd = F_GETFL;
|
||||
if ((error = fcntl(td, &fa)) != 0)
|
||||
return error;
|
||||
error = kern_fcntl(td, fd, F_GETFL, 0);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
oflags = td->td_retval[0];
|
||||
|
||||
@ -1512,19 +1511,15 @@ i_setsig(fp, td, retval, fd, cmd, dat)
|
||||
|
||||
/* set the new flags, if changed */
|
||||
if (flags != oflags) {
|
||||
fa.cmd = F_SETFL;
|
||||
fa.arg = (long) flags;
|
||||
if ((error = fcntl(td, &fa)) != 0)
|
||||
return error;
|
||||
error = kern_fcntl(td, fd, F_SETFL, flags);
|
||||
if (error)
|
||||
return (error);
|
||||
flags = td->td_retval[0];
|
||||
}
|
||||
|
||||
/* set up SIGIO receiver if needed */
|
||||
if (dat != NULL) {
|
||||
fa.cmd = F_SETOWN;
|
||||
fa.arg = (long) td->td_proc->p_pid;
|
||||
return fcntl(td, &fa);
|
||||
}
|
||||
if (dat != NULL)
|
||||
return (kern_fcntl(td, fd, F_SETOWN, td->td_proc->p_pid));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -100,7 +100,7 @@
|
||||
59 STD { int svr4_sys_execve(char *path, char **argp, char **envp); }
|
||||
60 MNOPROTO { int umask(int newmask); }
|
||||
61 NOPROTO { int chroot(char *path); }
|
||||
62 STD { int svr4_sys_fcntl(int fd, int cmd, char *arg); }
|
||||
62 MSTD { int svr4_sys_fcntl(int fd, int cmd, char *arg); }
|
||||
63 MSTD { int svr4_sys_ulimit(int cmd, long newlimit); }
|
||||
64 UNIMPL reserved
|
||||
65 UNIMPL reserved
|
||||
|
@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/filedesc.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/syscallsubr.h>
|
||||
#include <sys/sysproto.h>
|
||||
#include <sys/ttycom.h>
|
||||
|
||||
@ -246,92 +247,62 @@ ibcs2_fcntl(td, uap)
|
||||
struct thread *td;
|
||||
struct ibcs2_fcntl_args *uap;
|
||||
{
|
||||
intptr_t arg;
|
||||
int error;
|
||||
struct fcntl_args fa;
|
||||
struct flock *flp;
|
||||
struct flock fl;
|
||||
struct ibcs2_flock ifl;
|
||||
|
||||
|
||||
arg = (intptr_t)uap->arg;
|
||||
switch(uap->cmd) {
|
||||
case IBCS2_F_DUPFD:
|
||||
fa.fd = uap->fd;
|
||||
fa.cmd = F_DUPFD;
|
||||
fa.arg = (/* XXX */ int)uap->arg;
|
||||
return fcntl(td, &fa);
|
||||
return (kern_fcntl(td, uap->fd, F_DUPFD, arg));
|
||||
case IBCS2_F_GETFD:
|
||||
fa.fd = uap->fd;
|
||||
fa.cmd = F_GETFD;
|
||||
fa.arg = (/* XXX */ int)uap->arg;
|
||||
return fcntl(td, &fa);
|
||||
return (kern_fcntl(td, uap->fd, F_GETFD, arg));
|
||||
case IBCS2_F_SETFD:
|
||||
fa.fd = uap->fd;
|
||||
fa.cmd = F_SETFD;
|
||||
fa.arg = (/* XXX */ int)uap->arg;
|
||||
return fcntl(td, &fa);
|
||||
return (kern_fcntl(td, uap->fd, F_SETFD, arg));
|
||||
case IBCS2_F_GETFL:
|
||||
fa.fd = uap->fd;
|
||||
fa.cmd = F_GETFL;
|
||||
fa.arg = (/* XXX */ int)uap->arg;
|
||||
error = fcntl(td, &fa);
|
||||
error = kern_fcntl(td, uap->fd, F_GETFL, arg);
|
||||
if (error)
|
||||
return error;
|
||||
td->td_retval[0] = oflags2ioflags(td->td_retval[0]);
|
||||
return error;
|
||||
case IBCS2_F_SETFL:
|
||||
fa.fd = uap->fd;
|
||||
fa.cmd = F_SETFL;
|
||||
fa.arg = (/* XXX */ int)
|
||||
ioflags2oflags((int)uap->arg);
|
||||
return fcntl(td, &fa);
|
||||
return (kern_fcntl(td, uap->fd, F_SETFL,
|
||||
ioflags2oflags(arg)));
|
||||
|
||||
case IBCS2_F_GETLK:
|
||||
{
|
||||
caddr_t sg = stackgap_init();
|
||||
flp = stackgap_alloc(&sg, sizeof(*flp));
|
||||
error = copyin((caddr_t)uap->arg, (caddr_t)&ifl,
|
||||
ibcs2_flock_len);
|
||||
if (error)
|
||||
return error;
|
||||
cvt_iflock2flock(&ifl, flp);
|
||||
fa.fd = uap->fd;
|
||||
fa.cmd = F_GETLK;
|
||||
fa.arg = (/* XXX */ int)flp;
|
||||
error = fcntl(td, &fa);
|
||||
cvt_iflock2flock(&ifl, &fl);
|
||||
error = kern_fcntl(td, uap->fd, F_GETLK, (intptr_t)&fl);
|
||||
if (error)
|
||||
return error;
|
||||
cvt_flock2iflock(flp, &ifl);
|
||||
cvt_flock2iflock(&fl, &ifl);
|
||||
return copyout((caddr_t)&ifl, (caddr_t)uap->arg,
|
||||
ibcs2_flock_len);
|
||||
}
|
||||
|
||||
case IBCS2_F_SETLK:
|
||||
{
|
||||
caddr_t sg = stackgap_init();
|
||||
flp = stackgap_alloc(&sg, sizeof(*flp));
|
||||
error = copyin((caddr_t)uap->arg, (caddr_t)&ifl,
|
||||
ibcs2_flock_len);
|
||||
if (error)
|
||||
return error;
|
||||
cvt_iflock2flock(&ifl, flp);
|
||||
fa.fd = uap->fd;
|
||||
fa.cmd = F_SETLK;
|
||||
fa.arg = (/* XXX */ int)flp;
|
||||
|
||||
return fcntl(td, &fa);
|
||||
cvt_iflock2flock(&ifl, &fl);
|
||||
return (kern_fcntl(td, uap->fd, F_SETLK, (intptr_t)&fl));
|
||||
}
|
||||
|
||||
case IBCS2_F_SETLKW:
|
||||
{
|
||||
caddr_t sg = stackgap_init();
|
||||
flp = stackgap_alloc(&sg, sizeof(*flp));
|
||||
error = copyin((caddr_t)uap->arg, (caddr_t)&ifl,
|
||||
ibcs2_flock_len);
|
||||
if (error)
|
||||
return error;
|
||||
cvt_iflock2flock(&ifl, flp);
|
||||
fa.fd = uap->fd;
|
||||
fa.cmd = F_SETLKW;
|
||||
fa.arg = (/* XXX */ int)flp;
|
||||
return fcntl(td, &fa);
|
||||
cvt_iflock2flock(&ifl, &fl);
|
||||
return (kern_fcntl(td, uap->fd, F_SETLKW, (intptr_t)&fl));
|
||||
}
|
||||
}
|
||||
return ENOSYS;
|
||||
|
@ -98,7 +98,7 @@
|
||||
59 STD { int ibcs2_execve(char *path, char **argp, char **envp); }
|
||||
60 MNOPROTO { int umask(int newmask); }
|
||||
61 NOPROTO { int chroot(char *path); }
|
||||
62 STD { int ibcs2_fcntl(int fd, int cmd, char *arg); }
|
||||
62 MSTD { int ibcs2_fcntl(int fd, int cmd, char *arg); }
|
||||
63 MSTD { long ibcs2_ulimit(int cmd, int newlimit); }
|
||||
64 UNIMPL reserved for unix/pc
|
||||
65 UNIMPL reserved for unix/pc
|
||||
|
@ -89,7 +89,7 @@
|
||||
52 STD { int linux_umount(char *path, l_int flags); }
|
||||
53 UNIMPL lock
|
||||
54 STD { int linux_ioctl(l_uint fd, l_uint cmd, l_ulong arg); }
|
||||
55 STD { int linux_fcntl(l_uint fd, l_uint cmd, l_ulong arg); }
|
||||
55 MSTD { int linux_fcntl(l_uint fd, l_uint cmd, l_ulong arg); }
|
||||
56 UNIMPL mpx
|
||||
57 MNOPROTO { int setpgid(int pid, int pgid); }
|
||||
58 UNIMPL ulimit
|
||||
@ -294,7 +294,7 @@
|
||||
218 STD { int linux_mincore(l_ulong start, l_size_t len, u_char *vec); }
|
||||
219 MNOPROTO { int madvise(void *addr, size_t len, int behav); }
|
||||
220 STD { int linux_getdents64(l_uint fd, void *dirent, l_uint count); }
|
||||
221 STD { int linux_fcntl64(l_uint fd, l_uint cmd, l_ulong arg); }
|
||||
221 MSTD { int linux_fcntl64(l_uint fd, l_uint cmd, l_ulong arg); }
|
||||
222 UNIMPL
|
||||
223 UNIMPL
|
||||
224 UNIMPL linux_gettid
|
||||
|
Loading…
x
Reference in New Issue
Block a user