Ejemplo n.º 1
0
Archivo: super.c Proyecto: lithoxs/elks
int sys_umount(char *name)
{
    struct inode *inode;
    register struct inode *inodep;
    kdev_t dev;
    int retval;
    struct inode dummy_inode;

    if (!suser())
	return -EPERM;
    retval = namei(name, &inode, 0, 0);
    if (retval) {
	retval = lnamei(name, &inode);
	if (retval)
	    return retval;
    }
    inodep = inode;
    if (S_ISBLK(inodep->i_mode)) {
	dev = inodep->i_rdev;
	if (IS_NODEV(inodep)) {
	    iput(inodep);
	    return -EACCES;
	}
    } else {
	register struct super_block *sb = inodep->i_sb;
	if (!sb || inodep != sb->s_mounted) {
	    iput(inodep);
	    return -EINVAL;
	}
	dev = sb->s_dev;
	iput(inodep);
	memset(&dummy_inode, 0, sizeof(dummy_inode));
	dummy_inode.i_rdev = dev;
	inodep = &dummy_inode;
    }
    if (MAJOR(dev) >= MAX_BLKDEV) {
	iput(inodep);
	return -ENXIO;
    }
    if (!(retval = do_umount(dev)) && dev != ROOT_DEV) {
	register struct file_operations *fops;
	fops = get_blkfops(MAJOR(dev));
	if (fops && fops->release)
	    fops->release(inodep, NULL);

#ifdef NOT_YET
	if (MAJOR(dev) == UNNAMED_MAJOR)
	    put_unnamed_dev(dev);
#endif

    }
    if (inodep != &dummy_inode)
	iput(inodep);
    if (retval)
	return retval;
    fsync_dev(dev);
    return 0;
}
Ejemplo n.º 2
0
asmlinkage int sys_chown(const char * filename, uid_t user, gid_t group)
{
	struct inode * inode;
	int error;
	struct iattr newattrs;

	error = lnamei(filename,&inode);
	if (error)
		return error;
	if (IS_RDONLY(inode)) {
		iput(inode);
		return -EROFS;
	}
	if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
		iput(inode);
		return -EPERM;
	}
	if (user == (uid_t) -1)
		user = inode->i_uid;
	if (group == (gid_t) -1)
		group = inode->i_gid;
	newattrs.ia_mode = inode->i_mode;
	newattrs.ia_uid = user;
	newattrs.ia_gid = group;
	newattrs.ia_valid =  ATTR_UID | ATTR_GID | ATTR_CTIME;
	/*
	 * If the owner has been changed, remove the setuid bit
	 */
	if (inode->i_mode & S_ISUID) {
		newattrs.ia_mode &= ~S_ISUID;
		newattrs.ia_valid |= ATTR_MODE;
	}
	/*
	 * If the group has been changed, remove the setgid bit
	 *
	 * Don't remove the setgid bit if no group execute bit.
	 * This is a file marked for mandatory locking.
	 */
	if (((inode->i_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) {
		newattrs.ia_mode &= ~S_ISGID;
		newattrs.ia_valid |= ATTR_MODE;
	}
	inode->i_dirt = 1;
	if (inode->i_sb->dq_op) {
		inode->i_sb->dq_op->initialize(inode, -1);
		if (inode->i_sb->dq_op->transfer(inode, &newattrs, 0))
			return -EDQUOT;
		error = notify_change(inode, &newattrs);
		if (error)
			inode->i_sb->dq_op->transfer(inode, &newattrs, 1);
	} else
		error = notify_change(inode, &newattrs);
	iput(inode);
	return(error);
}
Ejemplo n.º 3
0
Archivo: super.c Proyecto: drewt/Telos
long sys_umount(const char *name, size_t name_len)
{
	struct inode * inode;
	dev_t dev;
	int retval, error;
	struct inode dummy_inode;
	struct file_operations * fops;

	error = verify_user_string(name, name_len);
	if (error)
		return error;
	//if (!suser())
	//	return -EPERM;
	retval = namei(name,&inode);
	if (retval) {
		retval = lnamei(name,&inode);
		if (retval)
			return retval;
	}
	if (S_ISBLK(inode->i_mode)) {
		dev = inode->i_rdev;
		if (IS_NODEV(inode)) {
			iput(inode);
			return -EACCES;
		}
	} else {
		if (!inode || !inode->i_sb || inode != inode->i_sb->s_mounted) {
			iput(inode);
			return -EINVAL;
		}
		dev = inode->i_sb->s_dev;
		iput(inode);
		memset(&dummy_inode, 0, sizeof(dummy_inode));
		dummy_inode.i_dev = dev;
		inode = &dummy_inode;
	}
	if (major(dev) >= MAX_BLKDEV) {
		iput(inode);
		return -ENXIO;
	}
	if (!(retval = do_umount(dev)) && dev != ROOT_DEV) {
		fops = get_blkfops(major(dev));
		if (fops && fops->release)
			fops->release(inode,NULL);
		if (major(dev) == UNNAMED_MAJOR)
			put_unnamed_dev(dev);
	}
	if (inode != &dummy_inode)
		iput(inode);
	if (retval)
		return retval;
	//fsync_dev(dev);
	return 0;
}
Ejemplo n.º 4
0
int sys_newlstat(char * filename, struct new_stat * statbuf)
{
	struct inode * inode;
	int error;

	error = lnamei(filename,&inode);
	if (error)
		return error;
	cp_new_stat(inode,statbuf);
	iput(inode);
	return 0;
}
Ejemplo n.º 5
0
int sys_chown(char *filename, uid_t user, gid_t group)
{
    struct inode *inode;
    int error;

    error = lnamei(filename, &inode);
    if (!error) {
	error = do_chown(inode, user, group);
	iput(inode);
    }
    return error;
}
Ejemplo n.º 6
0
asmlinkage int sys_umount(char * name)
{
	struct inode * inode;
	kdev_t dev;
	int retval;
	struct inode dummy_inode;

	if (!suser())
		return -EPERM;
	retval = namei(name, &inode);
	if (retval) {
		retval = lnamei(name, &inode);
		if (retval)
			return retval;
	}
	if (S_ISBLK(inode->i_mode)) {
		dev = inode->i_rdev;
		if (IS_NODEV(inode)) {
			iput(inode);
			return -EACCES;
		}
	} else {
		if (!inode->i_sb || inode != inode->i_sb->s_mounted) {
			iput(inode);
			return -EINVAL;
		}
		dev = inode->i_sb->s_dev;
		iput(inode);
		memset(&dummy_inode, 0, sizeof(dummy_inode));
		dummy_inode.i_rdev = dev;
		inode = &dummy_inode;
	}
	if (MAJOR(dev) >= MAX_BLKDEV) {
		iput(inode);
		return -ENXIO;
	}
	retval = do_umount(dev,0);
	if (!retval) {
		fsync_dev(dev);
		if (dev != ROOT_DEV) {
			blkdev_release (inode);
			if (MAJOR(dev) == UNNAMED_MAJOR)
				put_unnamed_dev(dev);
		}
	}
	if (inode != &dummy_inode)
		iput(inode);
	if (retval)
		return retval;
	fsync_dev(dev);
	return 0;
}
Ejemplo n.º 7
0
asmlinkage int sys_newlstat(char * filename, struct new_stat * statbuf)
{
	struct inode * inode;
	int error;

	error = verify_area(VERIFY_WRITE,statbuf,sizeof (*statbuf));
	if (error)
		return error;
	error = lnamei(filename,&inode);
	if (error)
		return error;
	cp_new_stat(inode,statbuf);
	iput(inode);
	return 0;
}
Ejemplo n.º 8
0
int sys_readlink(const char * path, char * buf, int bufsiz)
{
	struct inode * inode;
	int error;

	if (bufsiz <= 0)
		return -EINVAL;
	verify_area(buf,bufsiz);
	error = lnamei(path,&inode);
	if (error)
		return error;
	if (!inode->i_op || !inode->i_op->readlink) {
		iput(inode);
		return -EINVAL;
	}
	return inode->i_op->readlink(inode,buf,bufsiz);
}
Ejemplo n.º 9
0
int
osi_lookupname(char *aname, uio_seg_t seg, int followlink, struct dentry **dpp)
{
    struct dentry *dp = NULL;
    int code;

    code = ENOENT;
    if (seg == AFS_UIOUSER) {
        dp = followlink ? namei(aname) : lnamei(aname);
    } else {
        dp = lookup_dentry(aname, NULL, followlink ? 1 : 0);
    }

    if (dp && !IS_ERR(dp)) {
        if (dp->d_inode) {
            *dpp = dp;
            code = 0;
        } else
            dput(dp);
    }

    return code;
}