Exemplo n.º 1
0
__NOMIPS16
#endif 
asmlinkage long sys_utime(char * filename, struct utimbuf * times)
{
	int error;
	struct nameidata nd;
	struct inode * inode;
	struct iattr newattrs;

	error = user_path_walk(filename, &nd);
	if (error)
		goto out;
	inode = nd.dentry->d_inode;

	error = -EROFS;
	if (IS_RDONLY(inode))
		goto dput_and_out;

	/* Don't worry, the checks are done in inode_change_ok() */
	newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
	if (times) {
		error = get_user(newattrs.ia_atime, &times->actime);
		if (!error) 
			error = get_user(newattrs.ia_mtime, &times->modtime);
		if (error)
			goto dput_and_out;

		newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
	} else {
		if (current->fsuid != inode->i_uid &&
		    (error = permission(inode,MAY_WRITE)) != 0)
			goto dput_and_out;
	}
	error = notify_change(nd.dentry, &newattrs);
dput_and_out:
	path_release(&nd);
out:
	return error;
}
Exemplo n.º 2
0
__NOMIPS16
#endif 
asmlinkage long sys_utimes(char * filename, struct timeval * utimes)
{
	int error;
	struct nameidata nd;
	struct inode * inode;
	struct iattr newattrs;

	error = user_path_walk(filename, &nd);

	if (error)
		goto out;
	inode = nd.dentry->d_inode;

	error = -EROFS;
	if (IS_RDONLY(inode))
		goto dput_and_out;

	/* 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];
		error = -EFAULT;
		if (copy_from_user(&times, utimes, sizeof(times)))
			goto dput_and_out;
		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(inode,MAY_WRITE)) != 0)
			goto dput_and_out;
	}
	error = notify_change(nd.dentry, &newattrs);
dput_and_out:
	path_release(&nd);
out:
	return error;
}
Exemplo n.º 3
0
Arquivo: open.c Projeto: 274914765/C
static long do_sys_truncate(const char __user * path, loff_t length)
{
    struct nameidata nd;
    struct inode * inode;
    int error;

    error = -EINVAL;
    if (length < 0)    /* sorry, but loff_t says... */
        goto out;

    error = user_path_walk(path, &nd);
    if (error)
        goto out;
    inode = nd.path.dentry->d_inode;

    /* For directories it's -EISDIR, for other non-regulars - -EINVAL */
    error = -EISDIR;
    if (S_ISDIR(inode->i_mode))
        goto dput_and_out;

    error = -EINVAL;
    if (!S_ISREG(inode->i_mode))
        goto dput_and_out;

    error = mnt_want_write(nd.path.mnt);
    if (error)
        goto dput_and_out;

    error = vfs_permission(&nd, MAY_WRITE);
    if (error)
        goto mnt_drop_write_and_out;

    error = -EPERM;
    if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
        goto mnt_drop_write_and_out;

    error = get_write_access(inode);
    if (error)
        goto mnt_drop_write_and_out;

    /*
     * Make sure that there are no leases.  get_write_access() protects
     * against the truncate racing with a lease-granting setlease().
     */
    error = break_lease(inode, FMODE_WRITE);
    if (error)
        goto put_write_and_out;

    error = locks_verify_truncate(inode, NULL, length);
    if (!error) {
        DQUOT_INIT(inode);
        error = do_truncate(nd.path.dentry, length, 0, NULL);
    }

put_write_and_out:
    put_write_access(inode);
mnt_drop_write_and_out:
    mnt_drop_write(nd.path.mnt);
dput_and_out:
    path_put(&nd.path);
out:
    return error;
}