Ejemplo n.º 1
0
Archivo: namei.c Proyecto: foolsh/elks
int minix_symlink(struct inode *dir, char *name, size_t len, char *symname)
{
    int error;
    register struct inode *inode;
    register struct buffer_head *bh;
    struct minix_dir_entry *de;

    error = -EEXIST;
    bh = minix_find_entry(dir, name, len, &de);
    if (bh) {
	unmap_brelse(bh);
	goto symlink2;
    }
    error = -ENOSPC;
    inode = minix_new_inode(dir, S_IFLNK);
    if (!inode)
	goto symlink2;
/*----------------------------------------------------------------------*/
    bh = minix_bread(inode, 0, 1);
    if (!bh)
	goto symlink1;
    map_buffer(bh);
    if((error = strlen_fromfs(symname)) > 1023)
	error = 1023;
    memcpy_fromfs(bh->b_data, symname, error);
    bh->b_data[error] = 0;
    inode->i_size = (__u32) error;
    mark_buffer_dirty(bh, 1);
    unmap_brelse(bh);
/*----------------------------------------------------------------------*/
    error = minix_add_entry(dir, name, len, inode->i_ino);
    if (error) {
      symlink1:
	inode->i_nlink--;
	inode->i_dirt = 1;
    }
    iput(inode);
 symlink2:
    iput(dir);
    return error;
}
Ejemplo n.º 2
0
Archivo: super.c Proyecto: lithoxs/elks
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;
}