tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Enhance ptyfs to handle multiple instances.



Hello!
Maybe you skipped:
Minor corrections readdir and lookup for multi-mountpoint use.

 ptyfs_vnops.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

Resending.

Also main patch for subject.
I didn't want locate many code in ptm driver, but in real world,
it was the most suitable place(performance, flexible ..).
Most of changes were tied with code refactoring. I had added only one 
ptyfs_getmp().
In the near future we will need only decide how will keep,get list of mount 
points?


 fs/ptyfs/ptyfs_subr.c   |    2 -
 fs/ptyfs/ptyfs_vfsops.c |   15 ++++------
 kern/tty_bsdpty.c       |   18 ++++++------
 kern/tty_ptm.c          |   69 +++++++++++++++++++++++++++++++++++-------------
 kern/tty_pty.c          |   12 ++++++--
 sys/pty.h               |   23 ++++++++++------
 6 files changed, 92 insertions(+), 47 deletions(-)

Ilya.

Index: fs/ptyfs/ptyfs_vnops.c
===================================================================
RCS file: /cvsil/nbcur/src/sys/fs/ptyfs/ptyfs_vnops.c,v
retrieving revision 1.3
diff -u -p -r1.3 ptyfs_vnops.c
--- fs/ptyfs/ptyfs_vnops.c      24 Mar 2014 20:48:09 -0000      1.3
+++ fs/ptyfs/ptyfs_vnops.c      26 Mar 2014 08:49:47 -0000
@@ -616,7 +616,8 @@ ptyfs_lookup(void *v)
 
                pty = atoi(pname, cnp->cn_namelen);
 
-               if (pty < 0 || pty >= npty || pty_isfree(pty, 1))
+               if (pty < 0 || pty >= npty || pty_isfree(pty, 1) ||
+                   ptyfs_used_get(PTYFSptc, pty, dvp->v_mount, 0) == NULL)
                        break;
 
                error = ptyfs_allocvp(dvp->v_mount, vpp, PTYFSpts, pty,
@@ -711,7 +712,8 @@ ptyfs_readdir(void *v)
        }
        for (; uio->uio_resid >= UIO_MX && i < npty; i++) {
                /* check for used ptys */
-               if (ptyfs_used_get(PTYFSptc, i - 2, vp->v_mount, 0) == NULL)
+               if (pty_isfree(i - 2, 1) ||
+                   ptyfs_used_get(PTYFSptc, i - 2, vp->v_mount, 0) == NULL)
                        continue;
 
                dp->d_fileno = PTYFS_FILENO(i - 2, PTYFSpts);
Index: fs/ptyfs/ptyfs_subr.c
===================================================================
RCS file: /cvsil/nbcur/src/sys/fs/ptyfs/ptyfs_subr.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -p -r1.4 -r1.5
--- fs/ptyfs/ptyfs_subr.c       26 Mar 2014 10:29:29 -0000      1.4
+++ fs/ptyfs/ptyfs_subr.c       26 Mar 2014 21:32:13 -0000      1.5
@@ -139,7 +139,7 @@ ptyfs_getinfo(struct ptyfsnode *ptyfs, s
                 * from the inode
                 */
                if ((error = (*ptyfs_save_ptm->makename)(
-                       ptyfs_save_ptm, l, ttyname, sizeof(ttyname),
+                       NULL, l, ttyname, sizeof(ttyname),
                        ptyfs->ptyfs_pty, ptyfs->ptyfs_type == PTYFSpts ? 't'
                        : 'p')) != 0)
                                goto out;
Index: fs/ptyfs/ptyfs_vfsops.c
===================================================================
RCS file: /cvsil/nbcur/src/sys/fs/ptyfs/ptyfs_vfsops.c,v
retrieving revision 1.10
diff -u -p -r1.10 ptyfs_vfsops.c
--- fs/ptyfs/ptyfs_vfsops.c     24 Mar 2014 20:48:08 -0000      1.10
+++ fs/ptyfs/ptyfs_vfsops.c     27 Mar 2014 07:53:55 -0000
@@ -72,11 +72,11 @@ VFS_PROTOS(ptyfs);
 
 static struct sysctllog *ptyfs_sysctl_log;
 
-static int ptyfs__allocvp(struct ptm_pty *, struct lwp *, struct vnode **,
+static int ptyfs__allocvp(struct mount *, struct lwp *, struct vnode **,
     dev_t, char);
-static int ptyfs__makename(struct ptm_pty *, struct lwp *, char *, size_t,
+static int ptyfs__makename(struct mount *, struct lwp *, char *, size_t,
     dev_t, char);
-static void ptyfs__getvattr(struct ptm_pty *, struct lwp *, struct vattr *);
+static void ptyfs__getvattr(struct mount *, struct lwp *, struct vattr *);
 
 /*
  * ptm glue: When we mount, we make ptm point to us.
@@ -125,10 +125,9 @@ out:
 }
 
 static int
-ptyfs__makename(struct ptm_pty *pt, struct lwp *l, char *tbuf, size_t bufsiz,
+ptyfs__makename(struct mount *mp, struct lwp *l, char *tbuf, size_t bufsiz,
     dev_t dev, char ms)
 {
-       struct mount *mp = pt->arg;
        size_t len;
        const char *np;
 
@@ -154,10 +153,9 @@ ptyfs__makename(struct ptm_pty *pt, stru
 
 static int
 /*ARGSUSED*/
-ptyfs__allocvp(struct ptm_pty *pt, struct lwp *l, struct vnode **vpp,
+ptyfs__allocvp(struct mount *mp, struct lwp *l, struct vnode **vpp,
     dev_t dev, char ms)
 {
-       struct mount *mp = pt->arg;
        ptyfstype type;
 
        switch (ms) {
@@ -176,9 +174,8 @@ ptyfs__allocvp(struct ptm_pty *pt, struc
 
 
 static void
-ptyfs__getvattr(struct ptm_pty *pt, struct lwp *l, struct vattr *vattr)
+ptyfs__getvattr(struct mount *mp, struct lwp *l, struct vattr *vattr)
 {
-       struct mount *mp = pt->arg;
        struct ptyfsmount *pmnt = VFSTOPTY(mp);
        vattr_null(vattr);
        /* get real uid */
Index: kern/tty_bsdpty.c
===================================================================
RCS file: /cvsil/nbcur/src/sys/kern/tty_bsdpty.c,v
retrieving revision 1.2
diff -u -p -r1.2 tty_bsdpty.c
--- kern/tty_bsdpty.c   26 Mar 2014 10:29:29 -0000      1.2
+++ kern/tty_bsdpty.c   27 Mar 2014 07:53:55 -0000
@@ -31,6 +31,7 @@ __KERNEL_RCSID(0, "$NetBSD: tty_bsdpty.c
 
 #include "opt_ptm.h"
 
+#ifndef NO_DEV_PTM
 #ifdef COMPAT_BSDPTY
 /* bsd tty implementation for pty multiplexor driver /dev/ptm{,x} */
 
@@ -68,11 +69,11 @@ __KERNEL_RCSID(0, "$NetBSD: tty_bsdpty.c
 #define TTY_OLD_SUFFIX  "0123456789abcdef"
 #define TTY_NEW_SUFFIX  "ghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
 
-static int pty_makename(struct ptm_pty *, struct lwp *, char *, size_t, dev_t,
+static int pty_makename(struct mount *, struct lwp *, char *, size_t, dev_t,
     char);
-static int pty_allocvp(struct ptm_pty *, struct lwp *, struct vnode **,
+static int pty_allocvp(struct mount *, struct lwp *, struct vnode **,
     dev_t, char);
-static void pty_getvattr(struct ptm_pty *, struct lwp *, struct vattr *);
+static void pty_getvattr(struct mount *, struct lwp *, struct vattr *);
 
 struct ptm_pty ptm_bsdpty = {
        pty_allocvp,
@@ -83,7 +84,7 @@ struct ptm_pty ptm_bsdpty = {
 
 static int
 /*ARGSUSED*/
-pty_makename(struct ptm_pty *ptm, struct lwp *l, char *bf,
+pty_makename(struct mount *mp, struct lwp *l, char *bf,
     size_t bufsiz, dev_t dev, char c)
 {
        size_t nt;
@@ -113,7 +114,7 @@ pty_makename(struct ptm_pty *ptm, struct
 
 static int
 /*ARGSUSED*/
-pty_allocvp(struct ptm_pty *ptm, struct lwp *l, struct vnode **vp, dev_t dev,
+pty_allocvp(struct mount *mp, struct lwp *l, struct vnode **vp, dev_t dev,
     char ms)
 {
        int error;
@@ -121,7 +122,7 @@ pty_allocvp(struct ptm_pty *ptm, struct 
        struct nameidata nd;
        char name[TTY_NAMESIZE];
 
-       error = pty_makename(ptm, l, name, sizeof(name), dev, ms);
+       error = pty_makename(mp, l, name, sizeof(name), dev, ms);
        if (error)
                return error;
 
@@ -143,7 +144,7 @@ pty_allocvp(struct ptm_pty *ptm, struct 
 
 static void
 /*ARGSUSED*/
-pty_getvattr(struct ptm_pty *ptm, struct lwp *l, struct vattr *vattr)
+pty_getvattr(struct mount *mp, struct lwp *l, struct vattr *vattr)
 {
        vattr_null(vattr);
        /* get real uid */
@@ -151,4 +152,5 @@ pty_getvattr(struct ptm_pty *ptm, struct
        vattr->va_gid = TTY_GID;
        vattr->va_mode = TTY_PERM;
 }
-#endif
+#endif /* COMPAT_BSDPTY */
+#endif /* NO_DEV_PTM */
Index: kern/tty_ptm.c
===================================================================
RCS file: /cvsil/nbcur/src/sys/kern/tty_ptm.c,v
retrieving revision 1.4
diff -u -p -r1.4 tty_ptm.c
--- kern/tty_ptm.c      19 Mar 2014 21:12:32 -0000      1.4
+++ kern/tty_ptm.c      27 Mar 2014 07:53:55 -0000
@@ -45,6 +45,7 @@ __KERNEL_RCSID(0, "$NetBSD: tty_ptm.c,v 
 #include <sys/kernel.h>
 #include <sys/vnode.h>
 #include <sys/namei.h>
+#include <sys/malloc.h>
 #include <sys/signalvar.h>
 #include <sys/filedesc.h>
 #include <sys/conf.h>
@@ -84,11 +85,36 @@ static struct ptm_pty *ptm;
 int pts_major, ptc_major;
 
 static dev_t pty_getfree(void);
-static int pty_alloc_master(struct lwp *, int *, dev_t *);
-static int pty_alloc_slave(struct lwp *, int *, dev_t);
+static int pty_alloc_master(struct lwp *, int *, dev_t *, struct mount *);
+static int pty_alloc_slave(struct lwp *, int *, dev_t, struct mount *);
 
 void ptmattach(int);
 
+int
+ptyfs_getmp(struct lwp *l, struct mount **mpp) {
+       struct cwdinfo *cwdi = l->l_proc->p_cwdi;
+       struct mount *mp;
+
+       if (ptm->arg == NULL) { /* BSDPTY */
+               *mpp = NULL;
+               return 0;
+       }
+
+       mp = ptm->arg;  /* PTYFS */
+
+       if (cwdi->cwdi_rdir == NULL)
+               goto ok;
+
+       if (vn_isunder(mp->mnt_vnodecovered, cwdi->cwdi_rdir, l))
+               goto ok;
+
+       *mpp = NULL;
+       return EOPNOTSUPP;
+ok:
+       *mpp = mp;
+       return 0;
+}
+
 dev_t
 pty_makedev(char ms, int minor)
 {
@@ -140,7 +166,7 @@ pty_vn_open(struct vnode *vp, struct lwp
 }
 
 static int
-pty_alloc_master(struct lwp *l, int *fd, dev_t *dev)
+pty_alloc_master(struct lwp *l, int *fd, dev_t *dev, struct mount *mp)
 {
        int error;
        struct file *fp;
@@ -164,7 +190,7 @@ retry:
                error = EOPNOTSUPP;
                goto bad;
        }
-       if ((error = (*ptm->allocvp)(ptm, l, &vp, *dev, 'p')) != 0) {
+       if ((error = (*ptm->allocvp)(mp, l, &vp, *dev, 'p')) != 0) {
                DPRINTF(("pty_allocvp %d\n", error));
                goto bad;
        }
@@ -197,7 +223,7 @@ bad:
 }
 
 int
-pty_grant_slave(struct lwp *l, dev_t dev)
+pty_grant_slave(struct lwp *l, dev_t dev, struct mount *mp)
 {
        int error;
        struct vnode *vp;
@@ -213,12 +239,12 @@ pty_grant_slave(struct lwp *l, dev_t dev
         */
        if (ptm == NULL)
                return EOPNOTSUPP;
-       if ((error = (*ptm->allocvp)(ptm, l, &vp, dev, 't')) != 0)
+       if ((error = (*ptm->allocvp)(mp, l, &vp, dev, 't')) != 0)
                return error;
 
        if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
                struct vattr vattr;
-               (*ptm->getvattr)(ptm, l, &vattr);
+               (*ptm->getvattr)(mp, l, &vattr);
                /* Do the VOP_SETATTR() as root. */
                error = VOP_SETATTR(vp, &vattr, lwp0.l_cred);
                if (error) {
@@ -239,7 +265,7 @@ pty_grant_slave(struct lwp *l, dev_t dev
 }
 
 static int
-pty_alloc_slave(struct lwp *l, int *fd, dev_t dev)
+pty_alloc_slave(struct lwp *l, int *fd, dev_t dev, struct mount *mp)
 {
        int error;
        struct file *fp;
@@ -256,7 +282,7 @@ pty_alloc_slave(struct lwp *l, int *fd, 
                goto bad;
        }
 
-       if ((error = (*ptm->allocvp)(ptm, l, &vp, dev, 't')) != 0)
+       if ((error = (*ptm->allocvp)(mp, l, &vp, dev, 't')) != 0)
                goto bad;
        if ((error = pty_vn_open(vp, l)) != 0)
                goto bad;
@@ -282,7 +308,7 @@ pty_sethandler(struct ptm_pty *nptm)
 }
 
 int
-pty_fill_ptmget(struct lwp *l, dev_t dev, int cfd, int sfd, void *data)
+pty_fill_ptmget(struct lwp *l, dev_t dev, int cfd, int sfd, void *data, struct 
mount *mp)
 {
        struct ptmget *ptmg = data;
        int error;
@@ -293,11 +319,11 @@ pty_fill_ptmget(struct lwp *l, dev_t dev
        ptmg->cfd = cfd == -1 ? minor(dev) : cfd;
        ptmg->sfd = sfd == -1 ? minor(dev) : sfd;
 
-       error = (*ptm->makename)(ptm, l, ptmg->cn, sizeof(ptmg->cn), dev, 'p');
+       error = (*ptm->makename)(mp, l, ptmg->cn, sizeof(ptmg->cn), dev, 'p');
        if (error)
                return error;
 
-       return (*ptm->makename)(ptm, l, ptmg->sn, sizeof(ptmg->sn), dev, 't');
+       return (*ptm->makename)(mp, l, ptmg->sn, sizeof(ptmg->sn), dev, 't');
 }
 
 void
@@ -322,11 +348,14 @@ ptmopen(dev_t dev, int flag, int mode, s
        int error;
        int fd;
        dev_t ttydev;
+       struct mount *mp;
 
        switch(minor(dev)) {
        case 0:         /* /dev/ptmx */
        case 2:         /* /emul/linux/dev/ptmx */
-               if ((error = pty_alloc_master(l, &fd, &ttydev)) != 0)
+               if ((error = ptyfs_getmp(l, &mp)) != 0)
+                       return error;
+               if ((error = pty_alloc_master(l, &fd, &ttydev, mp)) != 0)
                        return error;
                if (minor(dev) == 2) {
                        /*
@@ -334,7 +363,7 @@ ptmopen(dev_t dev, int flag, int mode, s
                         * Handle this case here, instead of writing
                         * a new linux module.
                         */
-                       if ((error = pty_grant_slave(l, ttydev)) != 0) {
+                       if ((error = pty_grant_slave(l, ttydev, mp)) != 0) {
                                file_t *fp = fd_getfile(fd);
                                if (fp != NULL) {
                                        fd_close(fd);
@@ -367,21 +396,25 @@ ptmioctl(dev_t dev, u_long cmd, void *da
        dev_t newdev;
        int cfd, sfd;
        file_t *fp;
+       struct mount *mp;
 
        error = 0;
        switch (cmd) {
        case TIOCPTMGET:
-               if ((error = pty_alloc_master(l, &cfd, &newdev)) != 0)
+               if ((error = ptyfs_getmp(l, &mp)) != 0)
+                       return error;
+
+               if ((error = pty_alloc_master(l, &cfd, &newdev, mp)) != 0)
                        return error;
 
-               if ((error = pty_grant_slave(l, newdev)) != 0)
+               if ((error = pty_grant_slave(l, newdev, mp)) != 0)
                        goto bad;
 
-               if ((error = pty_alloc_slave(l, &sfd, newdev)) != 0)
+               if ((error = pty_alloc_slave(l, &sfd, newdev, mp)) != 0)
                        goto bad;
 
                /* now, put the indices and names into struct ptmget */
-               if ((error = pty_fill_ptmget(l, newdev, cfd, sfd, data)) != 0)
+               if ((error = pty_fill_ptmget(l, newdev, cfd, sfd, data, mp)) != 
0)
                        goto bad2;
                return 0;
        default:
Index: kern/tty_pty.c
===================================================================
RCS file: /cvsil/nbcur/src/sys/kern/tty_pty.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -u -p -r1.1.1.2 -r1.2
--- kern/tty_pty.c      17 Mar 2014 11:46:10 -0000      1.1.1.2
+++ kern/tty_pty.c      26 Mar 2014 21:32:13 -0000      1.2
@@ -1041,6 +1041,7 @@ ptyioctl(dev_t dev, u_long cmd, void *da
        const struct cdevsw *cdev;
        u_char *cc = tp->t_cc;
        int stop, error, sig;
+       struct mount *mp;
 
        /*
         * IF CONTROLLER STTY THEN MUST FLUSH TO PREVENT A HANG.
@@ -1071,8 +1072,11 @@ ptyioctl(dev_t dev, u_long cmd, void *da
 
 #ifndef NO_DEV_PTM
        /* Allow getting the name from either the master or the slave */
-       if (cmd == TIOCPTSNAME)
-               return pty_fill_ptmget(l, dev, -1, -1, data);
+       if (cmd == TIOCPTSNAME) {
+               if ((error = ptyfs_getmp(l, &mp)) != 0)
+                       return error;
+               return pty_fill_ptmget(l, dev, -1, -1, data, mp);
+       }
 #endif
 
        cdev = cdevsw_lookup(dev);
@@ -1080,7 +1084,9 @@ ptyioctl(dev_t dev, u_long cmd, void *da
                switch (cmd) {
 #ifndef NO_DEV_PTM
                case TIOCGRANTPT:
-                       return pty_grant_slave(l, dev);
+                       if ((error = ptyfs_getmp(l, &mp)) != 0)
+                               return error;
+                       return pty_grant_slave(l, dev, mp);
 #endif
 
                case TIOCGPGRP:
Index: sys/pty.h
===================================================================
RCS file: /cvsil/nbcur/src/sys/sys/pty.h,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 pty.h
--- sys/pty.h   4 Mar 2014 18:16:09 -0000       1.1.1.1
+++ sys/pty.h   27 Mar 2014 07:53:55 -0000
@@ -36,25 +36,32 @@ int pty_check(int);
 
 #ifndef NO_DEV_PTM
 void ptmattach(int);
-int pty_fill_ptmget(struct lwp *, dev_t, int, int, void *);
-int pty_grant_slave(struct lwp *, dev_t);
+int pty_fill_ptmget(struct lwp *, dev_t, int, int, void *, struct mount *);
+int pty_grant_slave(struct lwp *, dev_t, struct mount *);
 dev_t pty_makedev(char, int);
 int pty_vn_open(struct vnode *, struct lwp *);
 struct ptm_pty *pty_sethandler(struct ptm_pty *);
-#endif
+int ptyfs_getmp(struct lwp *, struct mount **);
 
+/*
+ * Ptm_pty is used for switch ptm{x} driver between BSDPTY, PTYFS.
+ * Functions' argument (struct mount *) is used only PTYFS,
+ * in the case BSDPTY can be NULL, and arg must be NULL.
+ */
 struct ptm_pty {
-       int (*allocvp)(struct ptm_pty *, struct lwp *, struct vnode **, dev_t,
+       int (*allocvp)(struct mount *, struct lwp *, struct vnode **, dev_t,
            char);
-       int (*makename)(struct ptm_pty *, struct lwp *, char *, size_t, dev_t, 
char);
-       void (*getvattr)(struct ptm_pty *, struct lwp *, struct vattr *);
+       int (*makename)(struct mount *, struct lwp *, char *, size_t, dev_t, 
char);
+       void (*getvattr)(struct mount *, struct lwp *, struct vattr *);
        void *arg;
 };
 
-extern int npty;
-
 #ifdef COMPAT_BSDPTY
 extern struct ptm_pty ptm_bsdpty;
 #endif
 
+#endif /* NO_DEV_PTM */
+
+extern int npty;
+
 #endif /* _SYS_PTY_H_ */


Home | Main Index | Thread Index | Old Index