示例#1
0
文件: xattr.c 项目: 19Dan01/linux
ssize_t v9fs_fid_xattr_get(struct p9_fid *fid, const char *name,
			   void *buffer, size_t buffer_size)
{
	ssize_t retval;
	u64 attr_size;
	struct p9_fid *attr_fid;
	struct kvec kvec = {.iov_base = buffer, .iov_len = buffer_size};
	struct iov_iter to;
	int err;

	iov_iter_kvec(&to, READ | ITER_KVEC, &kvec, 1, buffer_size);

	attr_fid = p9_client_xattrwalk(fid, name, &attr_size);
	if (IS_ERR(attr_fid)) {
		retval = PTR_ERR(attr_fid);
		p9_debug(P9_DEBUG_VFS, "p9_client_attrwalk failed %zd\n",
			 retval);
		return retval;
	}
	if (attr_size > buffer_size) {
		if (!buffer_size) /* request to get the attr_size */
			retval = attr_size;
		else
			retval = -ERANGE;
	} else {
		iov_iter_truncate(&to, attr_size);
		retval = p9_client_read(attr_fid, 0, &to, &err);
		if (err)
			retval = err;
	}
	p9_client_clunk(attr_fid);
	return retval;
}
示例#2
0
/**
 * v9fs_fid_readn - read from a fid
 * @fid: fid to read
 * @data: data buffer to read data into
 * @udata: user data buffer to read data into
 * @count: size of buffer
 * @offset: offset at which to read data
 *
 */
ssize_t
v9fs_fid_readn(struct p9_fid *fid, char *data, char __user *udata, u32 count,
	       u64 offset)
{
	int n, total, size;

	P9_DPRINTK(P9_DEBUG_VFS, "fid %d offset %llu count %d\n", fid->fid,
		   (long long unsigned) offset, count);
	n = 0;
	total = 0;
	size = fid->iounit ? fid->iounit : fid->clnt->msize - P9_IOHDRSZ;
	do {
		n = p9_client_read(fid, data, udata, offset, count);
		if (n <= 0)
			break;

		if (data)
			data += n;
		if (udata)
			udata += n;

		offset += n;
		count -= n;
		total += n;
	} while (count > 0 && n == size);

	if (n < 0)
		total = n;

	return total;
}
示例#3
0
static int v9fs_dir_readdir(struct file *file, struct dir_context *ctx)
{
	bool over;
	struct p9_wstat st;
	int err = 0;
	struct p9_fid *fid;
	int buflen;
	int reclen = 0;
	struct p9_rdir *rdir;
	struct kvec kvec;

	p9_debug(P9_DEBUG_VFS, "name %pD\n", file);
	fid = file->private_data;

	buflen = fid->clnt->msize - P9_IOHDRSZ;

	rdir = v9fs_alloc_rdir_buf(file, buflen);
	if (!rdir)
		return -ENOMEM;
	kvec.iov_base = rdir->buf;
	kvec.iov_len = buflen;

	while (1) {
		if (rdir->tail == rdir->head) {
			struct iov_iter to;
			int n;
			iov_iter_kvec(&to, READ | ITER_KVEC, &kvec, 1, buflen);
			n = p9_client_read(file->private_data, ctx->pos, &to,
					   &err);
			if (err)
				return err;

			rdir->head = 0;
			rdir->tail = n;
		}
		while (rdir->head < rdir->tail) {
			p9stat_init(&st);
			err = p9stat_read(fid->clnt, rdir->buf + rdir->head,
					  rdir->tail - rdir->head, &st);
			if (err) {
				p9_debug(P9_DEBUG_VFS, "returned %d\n", err);
				p9stat_free(&st);
				return -EIO;
			}
			reclen = st.size+2;

			over = !dir_emit(ctx, st.name, strlen(st.name),
					 v9fs_qid2ino(&st.qid), dt_type(&st));
			p9stat_free(&st);
			if (over)
				return 0;

			rdir->head += reclen;
			ctx->pos += reclen;
		}
	}
}
示例#4
0
ssize_t v9fs_fid_xattr_get(struct p9_fid *fid, const char *name,
                           void *buffer, size_t buffer_size)
{
    ssize_t retval;
    int msize, read_count;
    u64 offset = 0, attr_size;
    struct p9_fid *attr_fid;

    attr_fid = p9_client_xattrwalk(fid, name, &attr_size);
    if (IS_ERR(attr_fid)) {
        retval = PTR_ERR(attr_fid);
        P9_DPRINTK(P9_DEBUG_VFS,
                   "p9_client_attrwalk failed %zd\n", retval);
        attr_fid = NULL;
        goto error;
    }
    if (!buffer_size) {
        /* request to get the attr_size */
        retval = attr_size;
        goto error;
    }
    if (attr_size > buffer_size) {
        retval = -ERANGE;
        goto error;
    }
    msize = attr_fid->clnt->msize;
    while (attr_size) {
        if (attr_size > (msize - P9_IOHDRSZ))
            read_count = msize - P9_IOHDRSZ;
        else
            read_count = attr_size;
        read_count = p9_client_read(attr_fid, ((char *)buffer)+offset,
                                    NULL, offset, read_count);
        if (read_count < 0) {
            /* error in xattr read */
            retval = read_count;
            goto error;
        }
        offset += read_count;
        attr_size -= read_count;
    }
    /* Total read xattr bytes */
    retval = offset;
error:
    if (attr_fid)
        p9_client_clunk(attr_fid);
    return retval;

}
示例#5
0
static ssize_t
v9fs_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
{
	struct p9_fid *fid = iocb->ki_filp->private_data;
	int ret, err = 0;

	p9_debug(P9_DEBUG_VFS, "count %zu offset %lld\n",
		 iov_iter_count(to), iocb->ki_pos);

	ret = p9_client_read(fid, iocb->ki_pos, to, &err);
	if (!ret)
		return err;

	iocb->ki_pos += ret;
	return ret;
}
示例#6
0
文件: vfs_file.c 项目: asdlei00/Ace-i
static ssize_t
v9fs_file_read(struct file *filp, char __user *udata, size_t count,
               loff_t * offset)
{
    int ret;
    struct p9_fid *fid;

    P9_DPRINTK(P9_DEBUG_VFS, "count %zu offset %lld\n", count, *offset);
    fid = filp->private_data;

    if (count > (fid->clnt->msize - P9_IOHDRSZ))
        ret = v9fs_file_readn(filp, NULL, udata, count, *offset);
    else
        ret = p9_client_read(fid, NULL, udata, *offset, count);

    if (ret > 0)
        *offset += ret;

    return ret;
}
示例#7
0
int p9_client_readn(struct p9_fid *fid, char *data, u64 offset, u32 count)
{
    int n, total;

    P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu count %d\n", fid->fid,
               (long long unsigned) offset, count);
    n = 0;
    total = 0;
    while (count) {
        n = p9_client_read(fid, data, offset, count);
        if (n <= 0)
            break;

        data += n;
        offset += n;
        count -= n;
        total += n;
    }

    if (n < 0)
        total = n;

    return total;
}