Re: fdexpand() & open file tracking

2018-07-02 Thread Martin Pieuchot
On 02/07/18(Mon) 11:22, Martin Pieuchot wrote:
> Let's use a array of structures to keep track of open files.  This will
> allow us to simplify locking when expending it.
> 
> While here consistently use M_ZERO when (re)allocating M_FILEDESC
> structures.  I doubt the memset() solution makes any difference these
> days and the resulting code is simpler to understand.
> 
> Finally passes a 'struct filedesc' to fdexpand() to be coherent with
> the other functions.

Updated diff now that Visa committed his nice refcounting code using
atomics.

Since flags are now part of the `fd_ofiles' array we can use the new
spinning `fd_fplock' to serialize access to them instead of fdplock().

Comments, oks?

Index: kern/kern_descrip.c
===
RCS file: /cvs/src/sys/kern/kern_descrip.c,v
retrieving revision 1.175
diff -u -p -r1.175 kern_descrip.c
--- kern/kern_descrip.c 2 Jul 2018 14:36:33 -   1.175
+++ kern/kern_descrip.c 2 Jul 2018 15:36:46 -
@@ -235,7 +235,7 @@ fd_getfile(struct filedesc *fdp, int fd)
return (NULL);
 
mtx_enter(>fd_fplock);
-   fp = fdp->fd_ofiles[fd];
+   fp = fdp->fd_ofiles[fd].fn_fp;
if (fp != NULL)
atomic_inc_int(>f_count);
mtx_leave(>fd_fplock);
@@ -288,7 +288,7 @@ restart:
if ((error = fdalloc(p, 0, )) != 0) {
FRELE(fp, p);
if (error == ENOSPC) {
-   fdexpand(p);
+   fdexpand(fdp);
fdpunlock(fdp);
goto restart;
}
@@ -363,7 +363,7 @@ restart:
if ((error = fdalloc(p, new, )) != 0) {
FRELE(fp, p);
if (error == ENOSPC) {
-   fdexpand(p);
+   fdexpand(fdp);
fdpunlock(fdp);
goto restart;
}
@@ -375,8 +375,11 @@ restart:
}
/* No need for FRELE(), finishdup() uses current ref. */
error = finishdup(p, fp, old, new, retval, 1);
-   if (!error && flags & O_CLOEXEC)
-   fdp->fd_ofileflags[new] |= UF_EXCLOSE;
+   if (!error && flags & O_CLOEXEC) {
+   mtx_enter(>fd_fplock);
+   fdp->fd_ofiles[new].fn_flags |= UF_EXCLOSE;
+   mtx_leave(>fd_fplock);
+   }
 
 out:
fdpunlock(fdp);
@@ -423,7 +426,7 @@ restart:
if ((error = fdalloc(p, newmin, )) != 0) {
FRELE(fp, p);
if (error == ENOSPC) {
-   fdexpand(p);
+   fdexpand(fdp);
fdpunlock(fdp);
goto restart;
}
@@ -431,26 +434,29 @@ restart:
/* No need for FRELE(), finishdup() uses current ref. */
error = finishdup(p, fp, fd, i, retval, 0);
 
-   if (!error && SCARG(uap, cmd) == F_DUPFD_CLOEXEC)
-   fdp->fd_ofileflags[i] |= UF_EXCLOSE;
+   if (!error && SCARG(uap, cmd) == F_DUPFD_CLOEXEC) {
+   mtx_enter(>fd_fplock);
+   fdp->fd_ofiles[i].fn_flags |= UF_EXCLOSE;
+   mtx_leave(>fd_fplock);
+   }
}
 
fdpunlock(fdp);
return (error);
 
case F_GETFD:
-   fdplock(fdp);
-   *retval = fdp->fd_ofileflags[fd] & UF_EXCLOSE ? 1 : 0;
-   fdpunlock(fdp);
+   mtx_enter(>fd_fplock);
+   *retval = fdp->fd_ofiles[fd].fn_flags & UF_EXCLOSE ? 1 : 0;
+   mtx_leave(>fd_fplock);
break;
 
case F_SETFD:
-   fdplock(fdp);
+   mtx_enter(>fd_fplock);
if ((long)SCARG(uap, arg) & 1)
-   fdp->fd_ofileflags[fd] |= UF_EXCLOSE;
+   fdp->fd_ofiles[fd].fn_flags |= UF_EXCLOSE;
else
-   fdp->fd_ofileflags[fd] &= ~UF_EXCLOSE;
-   fdpunlock(fdp);
+   fdp->fd_ofiles[fd].fn_flags &= ~UF_EXCLOSE;
+   mtx_leave(>fd_fplock);
break;
 
case F_GETFL:
@@ -679,10 +685,10 @@ finishdup(struct proc *p, struct file *f
 * the function no longer creates a new reference to the old file.
 */
mtx_enter(>fd_fplock);
-   fdp->fd_ofiles[new] = fp;
+   fdp->fd_ofiles[new].fn_fp = fp;
+   fdp->fd_ofiles[new].fn_flags =
+   fdp->fd_ofiles[old].fn_flags & ~UF_EXCLOSE;
mtx_leave(>fd_fplock);
-
-   fdp->fd_ofileflags[new] = fdp->fd_ofileflags[old] & ~UF_EXCLOSE;
*retval = new;
 
if (oldfp != NULL) {
@@ -703,7 +709,8 @@ fdinsert(struct filedesc 

fdexpand() & open file tracking

2018-07-02 Thread Martin Pieuchot
Let's use a array of structures to keep track of open files.  This will
allow us to simplify locking when expending it.

While here consistently use M_ZERO when (re)allocating M_FILEDESC
structures.  I doubt the memset() solution makes any difference these
days and the resulting code is simpler to understand.

Finally passes a 'struct filedesc' to fdexpand() to be coherent with
the other functions.

Comments?  Oks?

Index: kern/kern_descrip.c
===
RCS file: /cvs/src/sys/kern/kern_descrip.c,v
retrieving revision 1.173
diff -u -p -r1.173 kern_descrip.c
--- kern/kern_descrip.c 1 Jul 2018 16:33:15 -   1.173
+++ kern/kern_descrip.c 2 Jul 2018 09:12:30 -
@@ -229,7 +229,7 @@ fd_getfile(struct filedesc *fdp, int fd)
return (NULL);
 
mtx_enter();
-   fp = fdp->fd_ofiles[fd];
+   fp = fdp->fd_files[fd].fn_fp;
if (fp != NULL)
fp->f_count++;
mtx_leave();
@@ -282,7 +282,7 @@ restart:
if ((error = fdalloc(p, 0, )) != 0) {
FRELE(fp, p);
if (error == ENOSPC) {
-   fdexpand(p);
+   fdexpand(fdp);
fdpunlock(fdp);
goto restart;
}
@@ -357,7 +357,7 @@ restart:
if ((error = fdalloc(p, new, )) != 0) {
FRELE(fp, p);
if (error == ENOSPC) {
-   fdexpand(p);
+   fdexpand(fdp);
fdpunlock(fdp);
goto restart;
}
@@ -370,7 +370,7 @@ restart:
/* No need for FRELE(), finishdup() uses current ref. */
error = finishdup(p, fp, old, new, retval, 1);
if (!error && flags & O_CLOEXEC)
-   fdp->fd_ofileflags[new] |= UF_EXCLOSE;
+   fdp->fd_files[new].fn_flags |= UF_EXCLOSE;
 
 out:
fdpunlock(fdp);
@@ -417,7 +417,7 @@ restart:
if ((error = fdalloc(p, newmin, )) != 0) {
FRELE(fp, p);
if (error == ENOSPC) {
-   fdexpand(p);
+   fdexpand(fdp);
fdpunlock(fdp);
goto restart;
}
@@ -426,7 +426,7 @@ restart:
error = finishdup(p, fp, fd, i, retval, 0);
 
if (!error && SCARG(uap, cmd) == F_DUPFD_CLOEXEC)
-   fdp->fd_ofileflags[i] |= UF_EXCLOSE;
+   fdp->fd_files[i].fn_flags |= UF_EXCLOSE;
}
 
fdpunlock(fdp);
@@ -434,16 +434,16 @@ restart:
 
case F_GETFD:
fdplock(fdp);
-   *retval = fdp->fd_ofileflags[fd] & UF_EXCLOSE ? 1 : 0;
+   *retval = fdp->fd_files[fd].fn_flags & UF_EXCLOSE ? 1 : 0;
fdpunlock(fdp);
break;
 
case F_SETFD:
fdplock(fdp);
if ((long)SCARG(uap, arg) & 1)
-   fdp->fd_ofileflags[fd] |= UF_EXCLOSE;
+   fdp->fd_files[fd].fn_flags |= UF_EXCLOSE;
else
-   fdp->fd_ofileflags[fd] &= ~UF_EXCLOSE;
+   fdp->fd_files[fd].fn_flags &= ~UF_EXCLOSE;
fdpunlock(fdp);
break;
 
@@ -668,8 +668,8 @@ finishdup(struct proc *p, struct file *f
fd_used(fdp, new);
}
 
-   fdp->fd_ofiles[new] = fp;
-   fdp->fd_ofileflags[new] = fdp->fd_ofileflags[old] & ~UF_EXCLOSE;
+   fdp->fd_files[new].fn_fp = fp;
+   fdp->fd_files[new].fn_flags = fdp->fd_files[old].fn_flags & ~UF_EXCLOSE;
*retval = new;
 
if (oldfp != NULL) {
@@ -690,15 +690,15 @@ fdinsert(struct filedesc *fdp, int fd, i
mtx_enter();
if ((fp->f_iflags & FIF_INSERTED) == 0) {
fp->f_iflags |= FIF_INSERTED;
-   if ((fq = fdp->fd_ofiles[0]) != NULL) {
+   if ((fq = fdp->fd_files[0].fn_fp) != NULL) {
LIST_INSERT_AFTER(fq, fp, f_list);
} else {
LIST_INSERT_HEAD(, fp, f_list);
}
}
-   KASSERT(fdp->fd_ofiles[fd] == NULL);
-   fdp->fd_ofiles[fd] = fp;
-   fdp->fd_ofileflags[fd] |= (flags & UF_EXCLOSE);
+   KASSERT(fdp->fd_files[fd].fn_fp == NULL);
+   fdp->fd_files[fd].fn_fp = fp;
+   fdp->fd_files[fd].fn_flags |= (flags & UF_EXCLOSE);
mtx_leave();
 }
 
@@ -706,8 +706,8 @@ void
 fdremove(struct filedesc *fdp, int fd)
 {
fdpassertlocked(fdp);
-   fdp->fd_ofiles[fd] = NULL;
-   fdp->fd_ofileflags[fd] = 0;
+   fdp->fd_files[fd].fn_fp = NULL;
+   fdp->fd_files[fd].fn_flags = 0;
fd_unused(fdp, fd);
 }
 
@@ -872,9 +872,9 @@ restart: