Exemple #1
0
int tty_ioctl(struct inode *inode, struct file *file, int cmd, register char *arg)
{
    register struct tty *tty = determine_tty(inode->i_rdev);
    int ret;

    switch (cmd) {
    case TCGETS:
	ret = verified_memcpy_tofs(arg, &tty->termios, sizeof(struct termios));
	break;
    case TCSETS:
    case TCSETSW:
    case TCSETSF:
	ret = verified_memcpy_fromfs(&tty->termios, arg, sizeof(struct termios));

	/* Inform driver that things have changed */
	if (tty->ops->ioctl != NULL)
	    tty->ops->ioctl(tty, cmd, arg);
	break;
    default:
	ret = (tty->ops->ioctl == NULL)
	    ? -EINVAL
	    : tty->ops->ioctl(tty, cmd, arg);
    }
    return ret;
}
Exemple #2
0
int sys_utimes(char *filename, struct timeval *utimes)
{
    int error;
    struct inode *inode;
    register struct inode *inodep;
    struct iattr newattrs;

    error = namei(filename, &inode, 0, 0);
    inodep = inode;
    if (error)
	return error;
    if (IS_RDONLY(inodep)) {
	iput(inodep);
	return -EROFS;
    }
    /* Don't worry, the checks are done in inode_change_ok() */
    newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
    if (utimes) {
	struct timeval times[2];
	if (error = verified_memcpy_fromfs(&times, utimes, sizeof(times))) {
	    iput(inodep);
	    return error;
	}
	newattrs.ia_atime = times[0].tv_sec;
	newattrs.ia_mtime = times[1].tv_sec;
	newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
    } else if ((error = permission(inodep, MAY_WRITE)) != 0) {
	iput(inodep);
	return error;
    }
    error = notify_change(inodep, &newattrs);
    iput(inodep);
    return error;
}
Exemple #3
0
/* set the time of day */
int sys_settimeofday(register struct timeval *tv, struct timezone *tz)
{
    struct timeval tmp_tv;
    struct timezone tmp_tz;
    jiff_t now;

    /* only user running as root can set the time */
    if (current->euid != 0)
	return -EPERM;

    /* verify we have valid addresses to read from */
    if (tv != NULL) {
	if (verified_memcpy_fromfs(&tmp_tv, tv,
				   sizeof(struct timeval)))
	    return -EFAULT;
	if (((unsigned long) tmp_tv.tv_usec) >= 1000000L)
	    return -EINVAL;
    }

    if (tz != NULL) {
	if (verified_memcpy_fromfs(&tmp_tz, tz,
				   sizeof(struct timezone)))
	    return -EFAULT;
	if (((unsigned int)(tmp_tz.tz_dsttime - DST_NONE))
	    > (DST_AUSTALT - DST_NONE))
	    return -EINVAL;
	/* Setting the timezone is easy, just a straight copy */
	xzone = tmp_tz;
    }

    /* Setting time is a bit tricky, since we don't really keep the time in the xtime
     * structure.  So we need to figure out the offset from the current time and
     * set xtime based on that.
     */
    if (tv != NULL) {
	now = jiffies;
	xtime.tv_sec = tmp_tv.tv_sec - (now / HZ);
	xtime.tv_usec = tmp_tv.tv_usec - ((now % HZ) * (1000000l / HZ));
    }

    /* success */
    return 0;
}
Exemple #4
0
static void do_meta_request(kdev_t device)
{
    struct ud_driver *driver = get_driver(major);
    struct ud_request *udr;
    struct request *req;
    char *buff;
    int major = MAJOR(device);

    printk("do_meta_request %d %x\n", major, blk_dev[major].current_request);
    if (NULL == driver) {
        end_request(0, req->rq_dev);
        return;
    }
    printk("1");
    while (1) {
        req = blk_dev[major].current_request;
        printk("2");
        if (!req || req->rq_dev < 0 || req->rq_sector == -1)
            return;
        printk("5");
        udr = new_request();
        udr->udr_type = UDR_BLK + req->rq_cmd;
        udr->udr_ptr = req->rq_sector;
        udr->udr_minor = MINOR(req->rq_dev);
        printk("6");
        post_request(driver, udr);
        printk("7");

        /* Should really check here whether we have a request */
        if (req->rq_cmd == WRITE) {
            /* Can't do this, copies to the wrong task */
#if 0
            verified_memcpy_tofs(driver->udd_data, buff, BLOCK_SIZE);
            /* FIXME FIXME	*/
            fmemcpy(driver->udd_task->mm.dseg, driver->udd_data, get_ds(),
                    buff, 1024);
#endif
        }
        printk("8");

        /* Wake up the driver so it can deal with the request */
        wake_up(&driver->udd_wait);
        printk("request init: wake driver, sleeping\n");
        sleep_on(&udr->udr_wait);
        printk("request continue\n");

        /* REQUEST HAS BEEN RETURNED BY USER PROGRAM */
        /* request must be dealt with and ended */
        if (udr->udr_status == 1) {
            end_request(0, req->rq_dev);
            udr->udr_status = 0;
            continue;
        }
        udr->udr_status = 0;
        buff = req->rq_buffer;
        if (req->rq_cmd == READ) {
            /* Can't do this, copies from the wrong task */
#if 0
            verified_memcpy_fromfs(buff, driver->udd_data, BLOCK_SIZE);
            /* FIXME FIXME */
            fmemcpy(get_ds(), buff, driver->udd_task->mm.dseg,
                    driver->udd_data, 1024);
#endif
        }
        end_request(1, req->rq_dev);
        wake_up(&udr->udr_wait);
    }
}
Exemple #5
0
static int meta_ioctl(struct inode *inode,
                      struct file *filp, int cmd, char *arg)
{
    struct ud_driver *driver;
    int i, minor = MINOR(inode->i_rdev);

    printk("meta_ioctl %d %x\n", cmd, inode->i_rdev);
    if (minor == 0) {
        if (cmd != META_CREAT)
            return -EINVAL;
        printk("registering new ");
        for (i = 0; i < MAX_UDD; i++)
            if (drivers[i].udd_type == UDD_NONE) {
                minor = i + 1;
                break;
            }
        if (minor == 0)
            return -ENODEV;
        driver = &drivers[i];
        verified_memcpy_fromfs(driver, arg, sizeof(struct ud_driver_trunc));
        if (driver->udd_type == UDD_CHR_DEV) {
            printk("char ");
            if (register_chrdev(driver->udd_major, "meta", &ucd_fops) < 0) {
                goto reg_err;
            }
        } else if (driver->udd_type == UDD_BLK_DEV) {
            if ((i = verfy_area(driver->udd_data, 1024)) != 0) {
                driver->udd_type = UDD_NONE;
                return i;
            }
            printk("block ");
            /* verify are here on buffer */
            if (register_blkdev(driver->udd_major, "meta", &ubd_fops) < 0) {
                goto reg_err;
            }
            blk_dev[driver->udd_major].request_fn = do_meta_request;
        }
        printk("device\n");
        driver->udd_task = current;
#if 0
        driver->udd_rwait = NULL;	/* FIXME: Not valid */
#endif
        return minor;
reg_err:
        driver->udd_type = UDD_NONE;
        return -ENODEV;
    }

    driver = &drivers[minor - 1];
    if (driver->udd_task != current) {
        printk("task mismatch %x %x\n", driver->udd_task, current);
        return -EINVAL;
    }
    switch (cmd) {
    case META_POLL:
        printk("waiting for request\n");
#if 0
        driver->udd_wait = NULL;	/* FIXME: not valid */
#endif
        driver->udd_req = NULL;
        wake_up(&driver->udd_rwait);
        interruptible_sleep_on(&driver->udd_wait);
        printk("Waking up\n");
        if (driver->udd_req != NULL) {
            verified_memcpy_tofs(arg, driver->udd_req,
                                 sizeof(struct ud_request));
            printk("here is the request\n");
            return 0;
        }
        printk("No request! up\n");
        return -EINTR;
        break;
    case META_ACK:
        printk("acknowledge request\n");
        if (driver->udd_req == NULL) {
            printk("No request was pending!\n");
            return -EINVAL;
        }
        verified_memcpy_fromfs(driver->udd_req, arg,
                               sizeof(struct ud_request_trunc));
        wake_up(&driver->udd_req->udr_wait);
#if 0
        driver->udd_req->udr_wait = NULL;	/* FIXME: Not valid */
#endif
        interruptible_sleep_on(&driver->udd_req->udr_wait);
        break;
    default:
        printk("Bad ioctl\n");
        return -EINVAL;
    }
    return 0;
}
Exemple #6
0
int sys_mount(char *dev_name, char *dir_name, char *type)
{
    struct file_system_type *fstype;
    struct inode *inode;
    register struct inode *inodep;
    register struct file_operations *fops;
    kdev_t dev;
    int retval;
    char *t;
    int new_flags = 0;

#ifdef CONFIG_FULL_VFS
    /* FIXME ltype is way too big for our stack goal.. */
    char ltype[16];		/* is enough isn't it? */
#endif

    if (!suser())
	return -EPERM;

#ifdef BLOAT_FS			/* new_flags is set to zero, so this is never true. */
    if ((new_flags & MS_REMOUNT) == MS_REMOUNT) {
	retval = do_remount(dir_name, new_flags & ~MS_REMOUNT, NULL);
	return retval;
    }
#endif

    /*
     *      FIMXE: copy type to user cleanly or use numeric types ??
     */

#ifdef CONFIG_FULL_VFS
    debug("MOUNT: performing type check\n");

    if ((retval = strlen_fromfs(type)) >= 16) {
	debug("MOUNT: type size exceeds 16 characters, trunctating\n");
	retval = 15;
    }

    verified_memcpy_fromfs(ltype, type, retval);
    ltype[retval] = '\0';	/* make asciiz again */

    fstype = get_fs_type(ltype);
    if (!fstype)
	return -ENODEV;
    debug("MOUNT: type check okay\n");
#else
    fstype = file_systems[0];
#endif

    t = fstype->name;
    fops = NULL;

#ifdef BLOAT_FS
    if (fstype->requires_dev) {
#endif

	retval = namei(dev_name, &inode, 0, 0);
	if (retval)
	    return retval;
	inodep = inode;
	debug("MOUNT: made it through namei\n");
	if (!S_ISBLK(inodep->i_mode)) {
	NOTBLK:
	    iput(inodep);
	    return -ENOTBLK;
	}
	if (IS_NODEV(inodep)) {
	    iput(inodep);
	    return -EACCES;
	}
	dev = inodep->i_rdev;
	if (MAJOR(dev) >= MAX_BLKDEV) {
	    iput(inodep);
	    return -ENXIO;
	}
	fops = get_blkfops(MAJOR(dev));
	if (!fops) {
	    goto NOTBLK;
	}
	if (fops->open) {
	    struct file dummy;	/* allows read-write or read-only flag */
	    memset(&dummy, 0, sizeof(dummy));
	    dummy.f_inode = inodep;
	    dummy.f_mode = (new_flags & MS_RDONLY) ? ((mode_t) 1)
						   : ((mode_t) 3);
	    retval = fops->open(inodep, &dummy);
	    if (retval) {
		iput(inodep);
		return retval;
	    }
	}

#ifdef BLOAT_FS
    } else
	printk("unnumbered fs is unsupported.\n");
#endif

    retval = do_mount(dev, dir_name, t, new_flags, NULL);
    if (retval && fops && fops->release)
	fops->release(inodep, NULL);
    iput(inodep);

    return retval;
}