Hi, In order to unlock flock(2), make writes to the f_iflags field of struct file atomic; similar to recent changes to both struct file and process. This also gets rid of the last kernel lock protected field in the scope of struct file.
Comments? OK? Index: kern/kern_descrip.c =================================================================== RCS file: /cvs/src/sys/kern/kern_descrip.c,v retrieving revision 1.200 diff -u -p -r1.200 kern_descrip.c --- kern/kern_descrip.c 26 Feb 2020 13:54:52 -0000 1.200 +++ kern/kern_descrip.c 5 Mar 2020 11:51:28 -0000 @@ -707,7 +707,7 @@ fdinsert(struct filedesc *fdp, int fd, i mtx_enter(&fhdlk); if ((fp->f_iflags & FIF_INSERTED) == 0) { - fp->f_iflags |= FIF_INSERTED; + atomic_setbits_int(&fp->f_iflags, FIF_INSERTED); if ((fq = fdp->fd_ofiles[0]) != NULL) { LIST_INSERT_AFTER(fq, fp, f_list); } else { @@ -1317,7 +1317,7 @@ sys_flock(struct proc *p, void *v, regis lf.l_len = 0; if (how & LOCK_UN) { lf.l_type = F_UNLCK; - fp->f_iflags &= ~FIF_HASLOCK; + atomic_clearbits_int(&fp->f_iflags, FIF_HASLOCK); error = VOP_ADVLOCK(vp, (caddr_t)fp, F_UNLCK, &lf, F_FLOCK); goto out; } @@ -1329,7 +1329,7 @@ sys_flock(struct proc *p, void *v, regis error = EINVAL; goto out; } - fp->f_iflags |= FIF_HASLOCK; + atomic_setbits_int(&fp->f_iflags, FIF_HASLOCK); if (how & LOCK_NB) error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, F_FLOCK); else Index: kern/vfs_syscalls.c =================================================================== RCS file: /cvs/src/sys/kern/vfs_syscalls.c,v retrieving revision 1.342 diff -u -p -r1.342 vfs_syscalls.c --- kern/vfs_syscalls.c 30 Jan 2020 15:36:11 -0000 1.342 +++ kern/vfs_syscalls.c 5 Mar 2020 11:51:28 -0000 @@ -1188,7 +1188,7 @@ doopenat(struct proc *p, int fd, const c goto out; } vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); - fp->f_iflags |= FIF_HASLOCK; + atomic_setbits_int(&fp->f_iflags, FIF_HASLOCK); } if (localtrunc) { if ((fp->f_flag & FWRITE) == 0) @@ -1457,7 +1457,7 @@ sys_fhopen(struct proc *p, void *v, regi goto bad; } vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); - fp->f_iflags |= FIF_HASLOCK; + atomic_setbits_int(&fp->f_iflags, FIF_HASLOCK); } VOP_UNLOCK(vp); *retval = indx; Index: sys/file.h =================================================================== RCS file: /cvs/src/sys/sys/file.h,v retrieving revision 1.60 diff -u -p -r1.60 file.h --- sys/file.h 1 Feb 2020 08:57:27 -0000 1.60 +++ sys/file.h 5 Mar 2020 11:51:28 -0000 @@ -75,7 +75,6 @@ struct fileops { * a atomic operations * f per file `f_mtx' * v vnode lock - * k kernel lock */ struct file { LIST_ENTRY(file) f_list;/* [F] list of active files */ @@ -86,7 +85,7 @@ struct file { #define DTYPE_PIPE 3 /* pipe */ #define DTYPE_KQUEUE 4 /* event queue */ #define DTYPE_DMABUF 5 /* DMA buffer (for DRM) */ - int f_iflags; /* [k] internal flags */ + u_int f_iflags; /* [a] internal flags */ int f_type; /* [I] descriptor type */ u_int f_count; /* [a] reference count */ struct ucred *f_cred; /* [I] credentials associated with descriptor */ Index: sys/sysctl.h =================================================================== RCS file: /cvs/src/sys/sys/sysctl.h,v retrieving revision 1.204 diff -u -p -r1.204 sysctl.h --- sys/sysctl.h 16 Feb 2020 07:55:30 -0000 1.204 +++ sys/sysctl.h 5 Mar 2020 11:51:28 -0000 @@ -735,7 +735,7 @@ do { \ struct kinfo_file { uint64_t f_fileaddr; /* PTR: address of struct file */ uint32_t f_flag; /* UINT: flags (see fcntl.h) */ - uint32_t f_iflags; /* INT: internal flags */ + uint32_t f_iflags; /* UINT: internal flags */ uint32_t f_type; /* INT: descriptor type */ uint32_t f_count; /* UINT: reference count */ uint32_t f_msgcount; /* UINT: references from msg queue */