lkml.org 
[lkml]   [2002]   [Jun]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [PATCH] Futex Asynchronous Interface
    On Thu, 6 Jun 2002 09:36:23 -0700 (PDT)
    Linus Torvalds <torvalds@transmeta.com> wrote:
    > You already have to have a system call to bind the particular fd to the
    > futex _anyway_, so do the only sane thing, and allocate the fd _there_,

    But Ma, I don't *want* to write a filesystem!

    Linus, Al, is there an easier way to do this? I stole this from sockfs,
    but I balked at another 50 lines for a proper inode creation, so I just use
    the same dentry and inode over and over.

    It's still an awful lot of irrelevant code: what can I cut?

    /* Everyone needs a dentry and inode */
    static struct dentry *futex_dentry;

    /* Signal allows caller to avoid the race which would occur if they
    set the sigio stuff up afterwards. */
    static int futex_fd(struct list_head *head,
    struct page *page,
    int offset,
    int signal)
    {
    int fd;
    struct futex_q *q;
    struct file *filp;

    if (signal < 0 || signal > _NSIG)
    return -EINVAL;

    fd = get_unused_fd();
    if (fd < 0)
    return fd;
    filp = get_empty_filp();
    if (!filp) {
    put_unused_fd(fd);
    return -ENFILE;
    }
    filp->f_op = &futex_fops;
    filp->f_dentry = dget(futex_dentry);

    if (signal) {
    filp->f_owner.pid = current->pid;
    filp->f_owner.uid = current->uid;
    filp->f_owner.euid = current->euid;
    filp->f_owner.signum = signal;
    }

    q = kmalloc(sizeof(*q), GFP_KERNEL);
    if (!q) {
    put_unused_fd(fd);
    put_filp(filp);
    return -ENOMEM;
    }

    /* Initialize queue structure */
    init_waitqueue_head(&q->waiters);
    filp->private_data = q;

    /* Go for it... */
    queue_me(head, q, page, offset, fd, filp);

    /* Now we map fd to filp, so userspace can access it */
    fd_install(fd, filp);
    return 0;
    }

    /* Oh yeah, makes sense to write a filesystem... */
    static struct super_operations futexfs_ops = {
    statfs: simple_statfs,
    };

    static int futexfs_fill_super(struct super_block *sb, void *data, int silent)
    {
    struct inode *root;
    sb->s_blocksize = 1024;
    sb->s_blocksize_bits = 10;
    sb->s_magic = 0xFBAD1DEA;
    sb->s_op = &futexfs_ops;
    root = new_inode(sb);
    if (!root)
    return -ENOMEM;
    root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR;
    root->i_uid = root->i_gid = 0;
    root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME;
    sb->s_root = d_alloc(NULL, &(const struct qstr) { "futex", 5, 0 });
    if (!sb->s_root) {
    iput(root);
    return -ENOMEM;
    }
    sb->s_root->d_sb = sb;
    sb->s_root->d_parent = sb->s_root;
    d_instantiate(sb->s_root, root);
    return 0;
    }

    static struct super_block *
    futexfs_get_sb(struct file_system_type *fs_type,
    int flags, char *dev_name, void *data)
    {
    return get_sb_nodev(fs_type, flags, data, futexfs_fill_super);
    }

    static struct file_system_type futex_fs_type = {
    name: "futexfs",
    get_sb: futexfs_get_sb,
    kill_sb: kill_anon_super,
    fs_flags: FS_NOMOUNT,
    };

    static int __init init(void)
    {
    unsigned int i;
    struct qstr name = { .name = "futex", .len = 5, .hash = 0 };
    struct vfsmount *futex_mnt;

    register_filesystem(&futex_fs_type);
    futex_mnt = kern_mount(&futex_fs_type);
    futex_dentry = d_alloc(NULL, &name);
    futex_dentry->d_inode = new_inode(futex_mnt->mnt_sb);

    for (i = 0; i < ARRAY_SIZE(futex_queues); i++)
    INIT_LIST_HEAD(&futex_queues[i]);
    return 0;
    }
    __initcall(init);

    --
    there are those who do and those who hang on and you don't see too
    many doers quoting their contemporaries. -- Larry McVoy
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-03-22 13:26    [W:5.190 / U:0.036 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site