Пример #1
0
long name_to_handle_at(int dfd, const char __user * name,
                       struct file_handle __user * handle, int flag)
{

    int follow;
    long ret = -EINVAL;
    struct nameidata nd;
    struct file *file = NULL;

    if(!capable(CAP_DAC_OVERRIDE))
        {
            ret = -EPERM;
            goto err_out;
        }
    if((flag & ~AT_SYMLINK_FOLLOW) != 0)
        goto err_out;

    if(name == NULL && dfd != AT_FDCWD)
        {
            file = fget(dfd);

            if(file)
                nd.dentry = file->f_dentry;
            else
                {
                    ret = -EBADF;
                    goto err_out;
                }
        }
    else
        {
            follow = (flag & AT_SYMLINK_FOLLOW) ? LOOKUP_FOLLOW : 0;
            ret = __user_walk_fd(dfd, name, follow, &nd);
            if(ret)
                goto err_out;
        }
    ret = do_sys_name_to_handle(&nd, handle);
    if(file)
        fput(file);
    else
        path_release(&nd);

err_out:
    return ret;
}
Пример #2
0
/**
 * sys_name_to_handle_at: convert name to handle
 * @dfd: directory relative to which name is interpreted if not absolute
 * @name: name that should be converted to handle.
 * @handle: resulting file handle
 * @mnt_id: mount id of the file system containing the file
 * @flag: flag value to indicate whether to follow symlink or not
 *
 * @handle->handle_size indicate the space available to store the
 * variable part of the file handle in bytes. If there is not
 * enough space, the field is updated to return the minimum
 * value required.
 */
SYSCALL_DEFINE5(name_to_handle_at, int, dfd, const char __user *, name,
		struct file_handle __user *, handle, int __user *, mnt_id,
		int, flag)
{
	struct path path;
	int lookup_flags;
	int err;

	if ((flag & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH)) != 0)
		return -EINVAL;

	lookup_flags = (flag & AT_SYMLINK_FOLLOW) ? LOOKUP_FOLLOW : 0;
	if (flag & AT_EMPTY_PATH)
		lookup_flags |= LOOKUP_EMPTY;
	err = user_path_at(dfd, name, lookup_flags, &path);
	if (!err) {
		err = do_sys_name_to_handle(&path, handle, mnt_id);
		path_put(&path);
	}
	return err;
}