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 */

Reply via email to