Remove all fgrp code
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 24 Jul 2015 19:38:45 +0000 (15:38 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Tue, 28 Jul 2015 23:57:18 +0000 (19:57 -0400)
Now that we're using the fd table for everything, there's no need to
keep the fgrp around.

kern/include/ns.h
kern/include/vfs.h
kern/src/ns/pgrp.c
kern/src/ns/sysfile.c
kern/src/process.c
kern/src/syscall.c
kern/src/vfs.c

index f17dc8e..c19eb60 100644 (file)
@@ -527,16 +527,6 @@ struct pgrp {
        int pin;
 };
 
-struct fgrp {
-       spinlock_t lock;
-       struct kref ref;
-       struct chan **fd;
-       int nfd;                                        /* number of fd slots */
-       int maxfd;                                      /* highest fd in use */
-       int minfd;                                      /* lower bound on free fd */
-       int closed;
-};
-
 struct evalue {
        char *var;
        char *val;
@@ -651,7 +641,6 @@ void cinit(void);
 struct chan *cclone(struct chan *);
 void cclose(struct chan *);
 void closeegrp(struct egrp *);
-void closefgrp(struct fgrp *);
 void closemount(struct mount *);
 void closepgrp(struct pgrp *);
 void closesigs(struct skeyset *);
@@ -707,7 +696,6 @@ int domount(struct chan **, struct mhead **);
 void drawactive(int);
 void drawcmap(void);
 void dumpstack(void);
-struct fgrp *dupfgrp(struct proc *, struct fgrp *);
 void egrpcpy(struct egrp *, struct egrp *);
 int emptystr(char *unused_char_p_t);
 int eqchan(struct chan *, struct chan *, int);
@@ -743,7 +731,6 @@ int kbdcr2nl(struct queue *, int);
 int kbdputc(struct queue *, int);
 void kbdrepeat(int);
 void kproc(char *unused_char_p_t, void (*)(void *), void *, int);
-int fgrpclose(struct fd_table *, int);
 void kprocchild(struct proc *, void (*)(void *), void *);
 void (*kproftick) (uint32_t);
 void ksetenv(char *unused_char_p_t, char *, int);
@@ -766,7 +753,6 @@ void muxclose(struct mnt *);
 struct chan *namec(char *unused_char_p_t, int unused_int, int, uint32_t);
 struct chan *newchan(void);
 struct egrp *newegrp(void);
-struct fgrp *newfgrp(void);
 struct mount *newmount(struct mhead *, struct chan *, int unused_int,
                                           char *unused_char_p_t);
 struct pgrp *newpgrp(void);
@@ -1017,9 +1003,7 @@ int sysdirwstat(char *name, struct dir *dir);
 int sysdirfwstat(int fd, struct dir *dir);
 long sysdirread(int fd, struct kdirent **d);
 int sysiounit(int fd);
-void close_9ns_files(struct proc *p, bool only_cloexec);
 void print_chaninfo(struct chan *ch);
-void print_9ns_files(struct proc *p);
 int plan9setup(struct proc *new_proc, struct proc *parent, int flags);
 int iseve(void);
 int fd_getfl(int fd);
index 59be8a8..82548b2 100644 (file)
@@ -390,8 +390,6 @@ struct fd_table {
        struct fd_set                           *open_fds;              /* init, pts to open_fds_init */
        struct small_fd_set                     open_fds_init;
        struct file_desc                        fd_array[NR_OPEN_FILES_DEFAULT];
-
-       struct fgrp                                     *fgrp;                  /* 9ns compat hack */
 };
 
 /* Process specific filesystem info */
index 33d84ad..db28ad3 100644 (file)
@@ -141,90 +141,6 @@ void pgrpcpy(struct pgrp *to, struct pgrp *from)
        wunlock(&from->ns);
 }
 
-void closefgrp(struct fgrp *f)
-{
-       /* TODO: look at this more carefully.  sharing fgrps might be unnecessary,
-        * due to our parallelism style. */
-       /* closefgrp can't be called from proc_destroy, due to races on the fgrp.
-        * current->fgrp is a kref source, and we'd need some form of external sync
-        * to remove it, since multiple kthreads could be accessing current->fgrp.
-        * proc_free is synchronized, for instance.  we could put some sync in the
-        * fgrp, but that would require splitting the deallocation (which we do
-        * manually), and would require not having multiple procs per fgrp (which we
-        * also require).  another option would be to use RCU: clear current->fgrp,
-        * then closefgrp after a grace period. */
-       warn("Don't call closefgrp()");
-
-       if (!f)
-               return;
-       kref_put(&f->ref);
-}
-
-static void freefgrp(struct kref *k)
-{
-       struct fgrp *f = container_of(k, struct fgrp, ref);
-       struct chan *c;
-       for (int i = 0; i <= f->maxfd; i++)
-               if ((c = f->fd[i]))
-                       cclose(c);
-
-       kfree(f->fd);
-       kfree(f);
-}
-
-struct fgrp *newfgrp(void)
-{
-       struct fgrp *new;
-       int n;
-
-       new = kzmalloc(sizeof(struct fgrp), 0);
-       kref_init(&new->ref, freefgrp, 1);
-       spinlock_init(&new->lock);
-       n = DELTAFD;
-       new->nfd = n;
-       new->fd = kzmalloc(n * sizeof(struct chan *), 0);
-       return new;
-}
-
-struct fgrp *dupfgrp(struct proc *new_proc, struct fgrp *f)
-{
-       int i;
-       struct chan *c;
-       struct fgrp *new;
-       int n;
-
-       new = kzmalloc(sizeof(struct fgrp), KMALLOC_WAIT);
-       kref_init(&new->ref, freefgrp, 1);
-       spin_lock(&f->lock);
-       if (f->closed) {
-               spin_unlock(&f->lock);
-               kfree(new);
-               error("File group closed");
-       }
-       n = DELTAFD;
-       if (f->maxfd >= n)
-               n = (f->maxfd + 1 + DELTAFD - 1) / DELTAFD * DELTAFD;
-       new->nfd = n;
-       new->fd = kzmalloc(n * sizeof(struct chan *), 0);
-       if (new->fd == NULL) {
-               spin_unlock(&f->lock);
-               kfree(new);
-               error(Enomem);
-       }
-       new->maxfd = f->maxfd;
-       new->minfd = f->minfd;
-       for (i = 0; i <= f->maxfd; i++) {
-               if ((c = f->fd[i])) {
-                       chan_incref(c);
-                       claim_fd(&new_proc->open_files, i);
-                       new->fd[i] = c;
-               }
-       }
-       spin_unlock(&f->lock);
-
-       return new;
-}
-
 struct mount *newmount(struct mhead *mh, struct chan *to, int flag, char *spec)
 {
        struct mount *m;
index 7e27cd9..fc15db5 100644 (file)
@@ -21,38 +21,6 @@ enum {
                                 * let's not yet exceed a common MSIZE. */
 };
 
-static int growfd(struct fgrp *f, int fd)
-{
-       int n;
-       struct chan **nfd, **ofd;
-
-       if (fd < f->nfd) {
-               return 0;
-       }
-       /* want to grow by a reasonable amount (delta), but also make sure we can
-        * handle the fd we're asked for */
-       n = MAX(f->nfd, fd + 1) + DELTAFD;
-       if (n > MAXNFD)
-               n = MAXNFD;
-       if (fd >= n) {
-               set_errno(EMFILE);
-               set_errstr("Asked for FD %d, more than %d\n", fd, MAXNFD);
-               return -1;
-       }
-       nfd = kzmalloc(n * sizeof(struct chan *), 0);
-       if (nfd == NULL) {
-               set_errno(ENOMEM);
-               set_errstr("Failed to growfd for FD %d, OOM\n", fd);
-               return -1;
-       }
-       ofd = f->fd;
-       memmove(nfd, ofd, f->nfd * sizeof(struct chan *));
-       f->fd = nfd;
-       f->nfd = n;
-       kfree(ofd);
-       return 0;
-}
-
 int newfd(struct chan *c, int oflags)
 {
        int ret = insert_obj_fdt(&current->open_files, c, 0,
@@ -180,14 +148,15 @@ int syschdir(char *path)
        return 0;
 }
 
-int fgrpclose(struct fd_table *fdt, int fd)
+int sysclose(int fd)
 {
        ERRSTACK(1);
+       struct fd_table *fdt = &current->open_files;
+
        if (waserror()) {
                poperror();
                return -1;
        }
-
        /*
         * Take no reference on the chan because we don't really need the
         * data structure, and are calling fdtochan only for error checks.
@@ -199,11 +168,6 @@ int fgrpclose(struct fd_table *fdt, int fd)
        return 0;
 }
 
-int sysclose(int fd)
-{
-       return fgrpclose(&current->open_files, fd);
-}
-
 int syscreate(char *path, int mode, uint32_t perm)
 {
        ERRSTACK(2);
@@ -1321,43 +1285,6 @@ int sysiounit(int fd)
        return n;
 }
 
-/* Notes on concurrency:
- * - Can't hold spinlocks while we call cclose, since it might sleep eventually.
- * - We're called from proc_destroy, so we could have concurrent openers trying
- *   to add to the group (other syscalls), hence the "closed" flag.
- * - dot and slash chans are dealt with in proc_free.  its difficult to close
- *   and zero those with concurrent syscalls, since those are a source of krefs.
- * - the memory is freed in proc_free().  need to wait to do it, since we can
- *   have concurrent accesses to fgrp before free.
- * - Once we lock and set closed, no further additions can happen.  To simplify
- *   our closes, we also allow multiple calls to this func (though that should
- *   never happen with the current code). */
-void close_9ns_files(struct proc *p, bool only_cloexec)
-{
-       
-       struct fgrp *f = p->open_files.fgrp;
-
-       spin_lock(&f->lock);
-       if (f->closed) {
-               spin_unlock(&f->lock);
-               warn("Unexpected double-close");
-               return;
-       }
-       if (!only_cloexec)
-               f->closed = TRUE;
-       spin_unlock(&f->lock);
-
-       /* maxfd is a legit val, not a +1 */
-       for (int i = 0; i <= f->maxfd; i++) {
-               if (!f->fd[i])
-                       continue;
-               if (only_cloexec && !(f->fd[i]->flag & CCEXEC))
-                       continue;
-               cclose(f->fd[i]);
-               f->fd[i] = 0;
-       }
-}
-
 void print_chaninfo(struct chan *c)
 {
        
@@ -1377,24 +1304,9 @@ void print_chaninfo(struct chan *c)
        printk("\n");
 }
 
-void print_9ns_files(struct proc *p)
-{
-       
-       struct fgrp *f = p->open_files.fgrp;
-       spin_lock(&f->lock);
-       printk("9ns files for proc %d:\n", p->pid);
-       /* maxfd is a legit val, not a +1 */
-       for (int i = 0; i <= f->maxfd; i++) {
-               if (!f->fd[i])
-                       continue;
-               printk("\t9fs %4d, ", i);
-               print_chaninfo(f->fd[i]);
-       }
-       spin_unlock(&f->lock);
-}
-
-/* TODO: 9ns ns inheritance flags: Shared, copied, or empty.  Looks like we're
- * copying the fgrp, and sharing the pgrp. */
+/* TODO: 9ns ns inheritance flags: Shared, copied, or empty.  The old fgrp is
+ * managed by the fd_table, which is handled outside this function.  We share
+ * the pgrp. */
 int plan9setup(struct proc *new_proc, struct proc *parent, int flags)
 {
        
@@ -1408,12 +1320,11 @@ int plan9setup(struct proc *new_proc, struct proc *parent, int flags)
        }
        if (!parent) {
                /* We are probably spawned by the kernel directly, and have no parent to
-                * inherit from.  Be sure to set up fgrp/pgrp before calling namec().
+                * inherit from.
                 *
                 * TODO: One problem is namec wants a current set for things like
                 * genbuf.  So we'll use new_proc for this bootstrapping.  Note
                 * switch_to() also loads the cr3. */
-               new_proc->open_files.fgrp = newfgrp();
                new_proc->pgrp = newpgrp();
                old_current = switch_to(new_proc);
                new_proc->slash = namec("#r", Atodir, 0, 0);
@@ -1427,12 +1338,6 @@ int plan9setup(struct proc *new_proc, struct proc *parent, int flags)
                poperror();
                return 0;
        }
-       /* When we use the old fgrp, we have copy semantics: do not change this
-        * without revisiting proc_destroy, close_9ns_files, and closefgrp. */
-       if (flags & PROC_DUP_FGRP)
-               new_proc->open_files.fgrp = dupfgrp(new_proc, parent->open_files.fgrp);
-       else
-               new_proc->open_files.fgrp = newfgrp();
        /* Shared semantics */
        kref_get(&parent->pgrp->ref, 1);
        new_proc->pgrp = parent->pgrp;
index 3764c19..f7e9059 100644 (file)
@@ -396,8 +396,6 @@ error_t proc_alloc(struct proc **pp, struct proc *parent, int flags)
 
        atomic_inc(&num_envs);
        frontend_proc_init(p);
-       /* this does all the 9ns setup, much of which is done throughout this func
-        * for the VFS, including duping the fgrp */
        plan9setup(p, parent, flags);
        devalarm_init(p);
        TAILQ_INIT(&p->abortable_sleepers);
@@ -465,9 +463,6 @@ static void __proc_free(struct kref *kref)
        cclose(p->dot);
        cclose(p->slash);
        p->dot = p->slash = 0; /* catch bugs */
-       /* can safely free the fgrp, now that no one is accessing it */
-       kfree(p->open_files.fgrp->fd);
-       kfree(p->open_files.fgrp);
        kref_put(&p->fs_env.root->d_kref);
        kref_put(&p->fs_env.pwd->d_kref);
        /* now we'll finally decref files for the file-backed vmrs */
@@ -885,7 +880,6 @@ void proc_destroy(struct proc *p)
         *
         * Also note that any mmap'd files will still be mmapped.  You can close the
         * file after mmapping, with no effect. */
-       close_9ns_files(p, FALSE);
        close_fdt(&p->open_files, FALSE);
        /* Tell the ksched about our death, and which cores we freed up */
        __sched_proc_destroy(p, pc_arr, nr_cores_revoked);
@@ -2355,16 +2349,3 @@ void check_my_owner(void)
                spin_unlock(&pid_hash_lock);
        }
 }
-
-/* Use this via kfunc */
-void print_9ns(void)
-{
-       void print_proc_9ns(void *item)
-       {
-               struct proc *p = (struct proc*)item;
-               print_9ns_files(p);
-       }
-       spin_lock(&pid_hash_lock);
-       hash_for_each(pid_hash, print_proc_9ns);
-       spin_unlock(&pid_hash_lock);
-}
index 1954b94..9927357 100644 (file)
@@ -577,7 +577,6 @@ static int sys_proc_create(struct proc *p, char *path, size_t path_l,
                goto mid_error;
        }
        /* close the CLOEXEC ones, even though this isn't really an exec */
-       close_9ns_files(new_p, TRUE);
        close_fdt(&new_p->open_files, TRUE);
        /* Load the elf. */
        if (load_elf(new_p, program, argc, argv, envc, envp)) {
@@ -842,7 +841,6 @@ static int sys_exec(struct proc *p, char *path, size_t path_l,
        pcpui->cur_kthread->sysc = 0;
        unmap_and_destroy_vmrs(p);
        /* close the CLOEXEC ones */
-       close_9ns_files(p, TRUE);
        close_fdt(&p->open_files, TRUE);
        env_user_mem_free(p, 0, UMAPTOP);
        if (load_elf(p, program, argc, argv, envc, envp)) {
index 666c008..4ff54ca 100644 (file)
@@ -2625,7 +2625,17 @@ int insert_file(struct fd_table *open_files, struct file *file, int low_fd,
 }
 
 /* Closes all open files.  Mostly just a "put" for all files.  If cloexec, it
- * will only close the FDs with FD_CLOEXEC (opened with O_CLOEXEC or fcntld). */
+ * will only close the FDs with FD_CLOEXEC (opened with O_CLOEXEC or fcntld).
+ *
+ * Notes on concurrency:
+ * - Can't hold spinlocks while we call cclose, since it might sleep eventually.
+ * - We're called from proc_destroy, so we could have concurrent openers trying
+ *   to add to the group (other syscalls), hence the "closed" flag.
+ * - dot and slash chans are dealt with in proc_free.  its difficult to close
+ *   and zero those with concurrent syscalls, since those are a source of krefs.
+ * - Once we lock and set closed, no further additions can happen.  To simplify
+ *   our closes, we also allow multiple calls to this func (though that should
+ *   never happen with the current code). */
 void close_fdt(struct fd_table *fdt, bool cloexec)
 {
        struct file *file;