Please take our Survey
logo       

Choosing A Webhost:
A web hosting service is a type of Internet hosting service that allows individuals and organizations to provide their own website accessible via the World Wide Web. Web hosts are companies that provide space on a server they own for use by their clients as well as providing Internet connectivity, typically in a data center. Web hosts can also provide data center space and connectivity to the Internet for servers they do not own to be located in their data center, called colocation. more...

[SSI] openssi/kernel/fs/devpts root.c,NONE,1.2.2.1 inode.c,NONE,1.2.2.1: msg#00108

Subject: [SSI] openssi/kernel/fs/devpts root.c,NONE,1.2.2.1 inode.c,NONE,1.2.2.1
Update of /cvsroot/ssic-linux/openssi/kernel/fs/devpts
In directory sc8-pr-cvs1:/tmp/cvs-serv32246/openssi/kernel/fs/devpts

Added Files:
      Tag: OPENSSI-RH
        root.c inode.c 
Log Message:
Globalized devpts. pty numbers are now globally unique which should allow
utmp to function properly in the cluster.

M ci/kernel/include/cluster/nsc.h
        Made USHRT_MAX arch-independent.
M ci/kernel/include/cluster/gen/ics_proto_gen.h.list
        Added types.
M openssi/kernel/cluster/ssi/util/Makefile
        Added new files to makefile.
M openssi/kernel/cluster/ssi/util/fifonm.c
M openssi/kernel/cluster/ssi/util/rmtsock.c
        Moved extern of ics_ssidev_chan to header.
M openssi/kernel/cluster/ssi/util/ssidev.c
        Changed the clms_ssidev_server_ready() to ssidev_server_ready() to
        be more consistent.
M openssi/kernel/cluster/ssi/vproc/reopen.c
        Played games in reop_import_path() to import /dev/pts pathnames
        correctly.
M openssi/kernel/drivers/char/tty_io.c
        Added hook to call pty nameserver.
M openssi/kernel/fs/super.c
        Added devpts to list of filesystems that get cluster unique
        unnamed device-numbers.
M openssi/kernel/include/cluster/ssi/ssidev.h
        Added prototypes, externs, etc,
M openssi/kernel.configs/config.i586
M openssi/kernel.configs/kernel-2.4.20-i586-ssi.config
        Added DEVPTS to build configuration.
A openssi/kernel/drivers/char/pty.c
        Added hook to call the nameserver to free a pty number.
A openssi/kernel/cluster/ssi/util/ssipty.c
A openssi/kernel/cluster/ssi/util/ssipty.svc
        Pty nameserver and support routines.
A openssi/kernel/fs/devpts/root.c
A openssi/kernel/fs/devpts/inode.c
        Added hooks.



--- NEW FILE: root.c ---
/* -*- linux-c -*- --------------------------------------------------------- *
 *
 * linux/fs/devpts/root.c
 *
 *  Copyright 1998 H. Peter Anvin -- All Rights Reserved
 *
 * This file is part of the Linux kernel and is made available under
 * the terms of the GNU General Public License, version 2, or at your
 * option, any later version, incorporated herein by reference.
 *
 * ------------------------------------------------------------------------- */

#include <linux/errno.h>
#include <linux/stat.h>
#include <linux/param.h>
#include <linux/string.h>
#include <cluster/ssi/ssidev.h>
#include "devpts_i.h"

static int devpts_root_readdir(struct file *,void *,filldir_t);
static struct dentry *devpts_root_lookup(struct inode *,struct dentry *);
static int devpts_revalidate(struct dentry *, int);

#ifdef CONFIG_SSI
struct ssipty_readdir_cookie {
        int oldpos;
        int start_index;
        int entries_len;
        struct ssipty_entry *entries;
};

static int
devpts_root_release(struct inode *inode, struct file *file)
{
        struct ssipty_readdir_cookie *cp = file->private_data;

        if (cp != NULL) {
                kfree(cp->entries);
                kfree(cp);
        }

        return 0;
}
#endif

struct file_operations devpts_root_operations = {
        read:           generic_read_dir,
        readdir:        devpts_root_readdir,
#ifdef CONFIG_SSI
        release:        devpts_root_release,
#endif
};

struct inode_operations devpts_root_inode_operations = {
        lookup:         devpts_root_lookup,
};

static struct dentry_operations devpts_dentry_operations = {
        d_revalidate:   devpts_revalidate,
};

/*
 * The normal naming convention is simply /dev/pts/<number>; this conforms
 * to the System V naming convention
 */

#define genptsname(buf,num) sprintf(buf, "%d", num)

static int devpts_root_readdir(struct file *filp, void *dirent, filldir_t 
filldir)
{
        struct inode * inode = filp->f_dentry->d_inode;
        struct devpts_sb_info * sbi = SBI(filp->f_dentry->d_inode->i_sb);
        off_t nr;
        char numbuf[16];
#ifdef CONFIG_SSI
        struct ssipty_readdir_cookie *cp;
        int ret;
        int ptynr;
        int curpty;
        int idx;
#endif

        nr = filp->f_pos;

        switch(nr)
        {
        case 0:
                if (filldir(dirent, ".", 1, nr, inode->i_ino, DT_DIR) < 0)
                        return 0;
                filp->f_pos = ++nr;
                /* fall through */
        case 1:
                if (filldir(dirent, "..", 2, nr, inode->i_ino, DT_DIR) < 0)
                        return 0;
                filp->f_pos = ++nr;
                /* fall through */
        default:
#ifdef CONFIG_SSI
                cp = filp->private_data;
                if (cp == NULL) {
                        cp = kmalloc(sizeof(struct ssipty_readdir_cookie),
                                     GFP_KERNEL);
                        filp->private_data = cp;
                        if (cp == NULL)
                                return -ENOMEM;
                        cp->oldpos = 0;
                        cp->entries_len = 0;
                        cp->entries = kmalloc(sbi->max_ptys *
                                              sizeof(struct ssipty_entry),
                                              GFP_KERNEL);
                        if (cp->entries == NULL)
                                return -ENOMEM;
                }
                if (nr != cp->oldpos) {
                        cp->start_index = 0;
                        cp->entries_len = sbi->max_ptys;
                        ret = ssipty_readdir(nr - 2, cp->entries,
                                             &cp->entries_len);
                        if (ret < 0) {
                                cp->oldpos = 0;
                                return ret;
                        }
                }
                ptynr = nr - 2;
                for (idx = cp->start_index; idx < cp->entries_len; idx++) {
                        curpty = cp->entries[idx].sp_ptynum;
                        if (curpty < ptynr)
                                continue;
                        genptsname(numbuf, curpty);
                        if ( filldir(dirent, numbuf, strlen(numbuf),
                                     curpty + 2, curpty + 2, DT_CHR) < 0 )
                                return 0;
                        filp->f_pos = curpty + 3;
                }
                cp->oldpos = filp->f_pos;
                cp->start_index = idx;
#else
                while ( nr - 2 < sbi->max_ptys ) {
                        int ptynr = nr - 2;
                        if ( sbi->inodes[ptynr] ) {
                                genptsname(numbuf, ptynr);
                                if ( filldir(dirent, numbuf, strlen(numbuf), 
nr, nr, DT_CHR) < 0 )
                                        return 0;
                        }
                        filp->f_pos = ++nr;
                }
#endif
                break;
        }

        return 0;
}

/*
 * Revalidate is called on every cache lookup.  We use it to check that
 * the pty really does still exist.  Never revalidate negative dentries;
 * for simplicity (fix later?)
 */
static int devpts_revalidate(struct dentry * dentry, int flags)
{
        struct devpts_sb_info *sbi;
#ifdef CONFIG_SSI
        struct inode *ip;
        int ret;
#endif

        if ( !dentry->d_inode )
                return 0;

        sbi = SBI(dentry->d_inode->i_sb);

#ifdef CONFIG_SSI
        ip = sbi->inodes[dentry->d_inode->i_ino - 2];
        if (ip != NULL)
                return (ip == dentry->d_inode);

        ret = ssipty_update_inode(&dentry->d_inode, dentry->d_inode->i_ino - 2);

        return (ret >= 0);
#else
        return ( sbi->inodes[dentry->d_inode->i_ino - 2] == dentry->d_inode );
#endif
}

static struct dentry *devpts_root_lookup(struct inode * dir, struct dentry * 
dentry)
{
        struct devpts_sb_info *sbi = SBI(dir->i_sb);
        unsigned int entry;
        int i;
        const char *p;
#ifdef CONFIG_SSI
        struct inode *ip;
        int ret;
#endif

        dentry->d_op    = &devpts_dentry_operations;

        if ( dentry->d_name.len == 1 && dentry->d_name.name[0] == '0' ) {
                entry = 0;
        } else if ( dentry->d_name.len < 1 ) {
                return NULL;
        } else {
                p = dentry->d_name.name;
                if ( *p < '1' || *p > '9' )
                        return NULL;
                entry = *p++ - '0';

                for ( i = dentry->d_name.len-1 ; i ; i-- ) {
                        unsigned int nentry = *p++ - '0';
                        if ( nentry > 9 )
                                return NULL;
                        if ( entry >= ~0U/10 )
                                return NULL;
                        entry = nentry + entry * 10;
                }
        }

        if ( entry >= sbi->max_ptys )
                return NULL;

#ifdef CONFIG_SSI
        ret = 0;
        ip = sbi->inodes[entry];
        if (ip != NULL)
                atomic_inc(&ip->i_count);
        else
                ret = ssipty_update_inode(&ip, entry);
        d_add(dentry, ip);

        return ERR_PTR(ret);
#else
        if ( sbi->inodes[entry] )
                atomic_inc(&sbi->inodes[entry]->i_count);
        d_add(dentry, sbi->inodes[entry]);
#endif
        return NULL;
}

--- NEW FILE: inode.c ---
/* -*- linux-c -*- --------------------------------------------------------- *
 *
 * linux/fs/devpts/inode.c
 *
 *  Copyright 1998 H. Peter Anvin -- All Rights Reserved
 *
 * This file is part of the Linux kernel and is made available under
 * the terms of the GNU General Public License, version 2, or at your
 * option, any later version, incorporated herein by reference.
 *
 * ------------------------------------------------------------------------- */

#include <linux/module.h>

#include <linux/string.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/kdev_t.h>
#include <linux/kernel.h>
#include <linux/locks.h>
#include <linux/major.h>
#include <linux/slab.h>
#include <linux/stat.h>
#include <linux/tty.h>
#include <asm/bitops.h>
#include <asm/uaccess.h>
#ifdef CONFIG_SSI
#include <cluster/ssi/ssidev.h>
#endif

#include "devpts_i.h"

static struct vfsmount *devpts_mnt;

static void devpts_put_super(struct super_block *sb)
{
        struct devpts_sb_info *sbi = SBI(sb);
        struct inode *inode;
        int i;

        for ( i = 0 ; i < sbi->max_ptys ; i++ ) {
                if ( (inode = sbi->inodes[i]) ) {
                        if ( atomic_read(&inode->i_count) != 1 )
                                printk("devpts_put_super: badness: entry %d 
count %d\n",
                                       i, atomic_read(&inode->i_count));
                        inode->i_nlink--;
                        iput(inode);
                }
        }
        kfree(sbi->inodes);
        kfree(sbi);
}

static int devpts_statfs(struct super_block *sb, struct statfs *buf);
#ifndef CONFIG_SSI
static int devpts_remount (struct super_block * sb, int * flags, char * data);
#endif

static struct super_operations devpts_sops = {
        put_super:      devpts_put_super,
        statfs:         devpts_statfs,
        remount_fs:     devpts_remount,
};

static int devpts_parse_options(char *options, struct devpts_sb_info *sbi)
{
        int setuid = 0;
        int setgid = 0;
        uid_t uid = 0;
        gid_t gid = 0;
        umode_t mode = 0600;
        char *this_char, *value;

        this_char = NULL;
        if ( options )
                this_char = strtok(options,",");
        for ( ; this_char; this_char = strtok(NULL,",")) {
                if ((value = strchr(this_char,'=')) != NULL)
                        *value++ = 0;
                if (!strcmp(this_char,"uid")) {
                        if (!value || !*value)
                                return 1;
                        uid = simple_strtoul(value,&value,0);
                        if (*value)
                                return 1;
                        setuid = 1;
                }
                else if (!strcmp(this_char,"gid")) {
                        if (!value || !*value)
                                return 1;
                        gid = simple_strtoul(value,&value,0);
                        if (*value)
                                return 1;
                        setgid = 1;
                }
                else if (!strcmp(this_char,"mode")) {
                        if (!value || !*value)
                                return 1;
                        mode = simple_strtoul(value,&value,8);
                        if (*value)
                                return 1;
                }
                else
                        return 1;
        }
        sbi->setuid  = setuid;
        sbi->setgid  = setgid;
        sbi->uid     = uid;
        sbi->gid     = gid;
        sbi->mode    = mode & ~S_IFMT;

        return 0;
}

#ifdef CONFIG_SSI
int _devpts_remount(struct super_block * sb, int * flags, char * data)
#else
static int devpts_remount(struct super_block * sb, int * flags, char * data)
#endif
{
        struct devpts_sb_info *sbi = sb->u.generic_sbp;
        int res = devpts_parse_options(data,sbi);
        if (res) {
                printk("devpts: called with bogus options\n");
                return -EINVAL;
        }
        return 0;
}

#ifdef CONFIG_SSI
struct super_block *_devpts_read_super(struct super_block *s, void *data,
                                      int silent)
#else
struct super_block *devpts_read_super(struct super_block *s, void *data,
                                      int silent)
#endif
{
        struct inode * inode;
        struct devpts_sb_info *sbi;

        sbi = (struct devpts_sb_info *) kmalloc(sizeof(struct devpts_sb_info), 
GFP_KERNEL);
        if ( !sbi )
                goto fail;

        sbi->magic  = DEVPTS_SBI_MAGIC;
        sbi->max_ptys = unix98_max_ptys;
        sbi->inodes = kmalloc(sizeof(struct inode *) * sbi->max_ptys, 
GFP_KERNEL);
        if ( !sbi->inodes )
                goto fail_free;
        memset(sbi->inodes, 0, sizeof(struct inode *) * sbi->max_ptys);

        if ( devpts_parse_options(data,sbi) && !silent) {
                printk("devpts: called with bogus options\n");
                goto fail_free;
        }

        inode = new_inode(s);
        if (!inode)
                goto fail_free;
        inode->i_ino = 1;
        inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
        inode->i_blocks = 0;
        inode->i_blksize = 1024;
        inode->i_uid = inode->i_gid = 0;
        inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR;
        inode->i_op = &devpts_root_inode_operations;
        inode->i_fop = &devpts_root_operations;
        inode->i_nlink = 2;

        s->u.generic_sbp = (void *) sbi;
        s->s_blocksize = 1024;
        s->s_blocksize_bits = 10;
        s->s_magic = DEVPTS_SUPER_MAGIC;
        s->s_op = &devpts_sops;
#ifdef CONFIG_SSI
        s->s_mnt_op = &devpts_mnt_ops;
#endif /* CONFIG_SSI */
        s->s_root = d_alloc_root(inode);
        if (s->s_root)
                return s;
        
        printk("devpts: get root dentry failed\n");
        iput(inode);
fail_free:
        kfree(sbi);
fail:
        return NULL;
}

static int devpts_statfs(struct super_block *sb, struct statfs *buf)
{
        buf->f_type = DEVPTS_SUPER_MAGIC;
        buf->f_bsize = 1024;
        buf->f_namelen = NAME_MAX;
        return 0;
}

static DECLARE_FSTYPE(devpts_fs_type, "devpts", devpts_read_super, FS_SINGLE);

void devpts_pty_new(int number, kdev_t device)
{
        struct super_block *sb = devpts_mnt->mnt_sb;
        struct devpts_sb_info *sbi = SBI(sb);
        struct inode *inode;
                
        if ( sbi->inodes[number] )
                return; /* Already registered, this does happen */
                
        inode = new_inode(sb);
        if (!inode)
                return;
        inode->i_ino = number+2;
        inode->i_blocks = 0;
        inode->i_blksize = 1024;
        inode->i_uid = sbi->setuid ? sbi->uid : current->fsuid;
        inode->i_gid = sbi->setgid ? sbi->gid : current->fsgid;
        inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
#ifdef CONFIG_SSI
        inode->u.generic_ip = (void *)this_node;
#endif
        init_special_inode(inode, S_IFCHR|sbi->mode, kdev_t_to_nr(device));

        if ( sbi->inodes[number] ) {
                iput(inode);
                return;
        }
        sbi->inodes[number] = inode;
}

#ifdef CONFIG_SSI
static int
ssipty_remote_open(struct inode *inode, struct file *file)
{
        return rmtfb_ropen(file, (clusternode_t)inode->u.generic_ip);
}

static struct file_operations
ssipty_remote_fops = {
        open:   ssipty_remote_open,
};

struct inode *
ssipty_init_inode(struct inode *inode, int number, clusternode_t svr)
{
        struct super_block *sb = devpts_mnt->mnt_sb;
        struct devpts_sb_info *sbi = SBI(sb);
        kdev_t device;

        if (inode == NULL) {
                inode = new_inode(sb);
                if (inode == NULL)
                        return NULL;
        }

        device = MKDEV(pts_driver[number / NR_PTYS].major,
                       pts_driver[number / NR_PTYS].minor_start +
                       number % NR_PTYS);
        inode->i_ino = number + 2;
        inode->i_blocks = 0;
        inode->i_blksize = 1024;
        init_special_inode(inode, S_IFCHR | sbi->mode, kdev_t_to_nr(device));
        inode->i_fop = &ssipty_remote_fops;
        inode->u.generic_ip = (void *)svr;

        return inode;
}

int
ssipty_get_iattr(int ptynum, struct iattr *iattr)
{
        struct super_block *sb = devpts_mnt->mnt_sb;
        struct devpts_sb_info *sbi = SBI(sb);
        struct inode *inode;

        inode = sbi->inodes[ptynum];
        if (inode == NULL)
                return -ENOENT;

        iattr->ia_uid = inode->i_uid;
        iattr->ia_gid = inode->i_gid;
        iattr->ia_atime = inode->i_atime;
        iattr->ia_mtime = inode->i_mtime;
        iattr->ia_ctime = inode->i_ctime;
        iattr->ia_mode = inode->i_mode;

        return 0;
}

void
ssipty_get_mntopts(int *setuid, uid_t *uid, int *setgid, gid_t *gid,
                   umode_t *mode)
{
        struct super_block *sb = devpts_mnt->mnt_sb;
        struct devpts_sb_info *sbi = SBI(sb);

        *setuid = sbi->setuid;
        *uid    = sbi->uid;
        *setgid = sbi->setgid;
        *gid    = sbi->gid;
        *mode   = sbi->mode;
}

#endif

void devpts_pty_kill(int number)
{
        struct super_block *sb = devpts_mnt->mnt_sb;
        struct devpts_sb_info *sbi = SBI(sb);
        struct inode *inode = sbi->inodes[number];

        if ( inode ) {
                sbi->inodes[number] = NULL;
                inode->i_nlink--;
                iput(inode);
        }
}

static int __init init_devpts_fs(void)
{
        int err = register_filesystem(&devpts_fs_type);
        if (!err) {
                devpts_mnt = kern_mount(&devpts_fs_type);
                err = PTR_ERR(devpts_mnt);
                if (!IS_ERR(devpts_mnt))
                        err = 0;
#ifdef MODULE
                if ( !err ) {
                        devpts_upcall_new  = devpts_pty_new;
                        devpts_upcall_kill = devpts_pty_kill;
                }
#endif
        }
        return err;
}

static void __exit exit_devpts_fs(void)
{
#ifdef MODULE
        devpts_upcall_new  = NULL;
        devpts_upcall_kill = NULL;
#endif
        unregister_filesystem(&devpts_fs_type);
        kern_umount(devpts_mnt);
}

module_init(init_devpts_fs)
module_exit(exit_devpts_fs)
MODULE_LICENSE("GPL");





-------------------------------------------------------
This SF.net email is sponsored by: IBM Linux Tutorials.
Become an expert in LINUX or just sharpen your skills.  Sign up for IBM's
Free Linux Tutorials.  Learn everything from the bash shell to sys admin.
Click now! http://ads.osdn.com/?ad_id=1278&alloc_id=3371&op=click


<Prev in Thread] Current Thread [Next in Thread>
Google Custom Search

Recently Viewed:
hardware.arm.at...    cms.citadel.dev...    video.gstreamer...    java.facelets.u...    misc.basics.qna...    web.wiki.instik...    network.uip.use...    xdg.devel/2003-...    tex.bibtex.bibd...    finance.quotesp...    ietf.zeroconf/2...    redhat.blinux.g...    suse.db2/2003-0...    php.phpesp/2004...    uml.devel/2003-...    gnome.labyrinth...    qnx.openqnx.dev...    boot-loaders.gr...    db.dataperfect....    audio.audacity....    linux.uclinux.m...    editors.j.devel...    os.openbsd.tech...    kde.users.multi...   
Home | advertise | OSDir is an inevitable website. super tiny logo

Free Magazines

Cisco News
Receive a free quarterly e-newsletter with exclusive articles on how Cisco IT uses its own products and solutions to enable the business.
subscribe

Systems Management News, the newspaper for IT systems administration and data center managers! Each issue of Systems Management News is chock-full of news and analysis to help you understand what's happening in your field.
subscribe

The Enterprise Newsweekly eWeek is the essential technology information source for builders of e-business.
subscribe

Oracle Magazine Oracle Magazine contains technology strategy articles, sample code, tips, Oracle and partner news, how to articles for developers and DBAs, and more. Oracle (NASDAQ: ORCL) is the world's largest enterprise software company.
subscribe

Total Telecom Total Telecom is "The Economist of the communications industry".
subscribe

Navigation