NFSv4: Add support for readlink()
Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>libnfs-4.0.0-vitalif
parent
f3211e9be5
commit
5c2d989887
|
@ -486,6 +486,8 @@ int nfs4_open_async(struct nfs_context *nfs, const char *path, int flags,
|
|||
int nfs4_pread_async_internal(struct nfs_context *nfs, struct nfsfh *nfsfh,
|
||||
uint64_t offset, size_t count, nfs_cb cb,
|
||||
void *private_data, int update_pos);
|
||||
int nfs4_readlink_async(struct nfs_context *nfs, const char *path, nfs_cb cb,
|
||||
void *private_data);
|
||||
int nfs4_rmdir_async(struct nfs_context *nfs, const char *path, nfs_cb cb,
|
||||
void *private_data);
|
||||
int nfs4_stat64_async(struct nfs_context *nfs, const char *path,
|
||||
|
|
|
@ -1100,7 +1100,8 @@ nfs_readlink(struct nfs_context *nfs, const char *path, char *buf, int bufsize)
|
|||
cb_data.return_int = bufsize;
|
||||
|
||||
if (nfs_readlink_async(nfs, path, readlink_cb, &cb_data) != 0) {
|
||||
nfs_set_error(nfs, "nfs_readlink_async failed");
|
||||
nfs_set_error(nfs, "nfs_readlink_async failed. %s",
|
||||
nfs_get_error(nfs));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -1343,9 +1343,11 @@ nfs_readlink_async(struct nfs_context *nfs, const char *path, nfs_cb cb,
|
|||
switch (nfs->version) {
|
||||
case NFS_V3:
|
||||
return nfs3_readlink_async(nfs, path, cb, private_data);
|
||||
case NFS_V4:
|
||||
return nfs4_readlink_async(nfs, path, cb, private_data);
|
||||
default:
|
||||
nfs_set_error(nfs, "%s does not support NFSv4",
|
||||
__FUNCTION__);
|
||||
nfs_set_error(nfs, "%s does not support NFSv%d",
|
||||
__FUNCTION__, nfs->version);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
68
lib/nfs_v4.c
68
lib/nfs_v4.c
|
@ -1938,3 +1938,71 @@ nfs4_symlink_async(struct nfs_context *nfs, const char *target,
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
nfs4_readlink_cb(struct rpc_context *rpc, int status, void *command_data,
|
||||
void *private_data)
|
||||
{
|
||||
struct nfs4_cb_data *data = private_data;
|
||||
struct nfs_context *nfs = data->nfs;
|
||||
COMPOUND4res *res = command_data;
|
||||
READLINK4resok *rlresok;
|
||||
int i;
|
||||
|
||||
assert(rpc->magic == RPC_CONTEXT_MAGIC);
|
||||
|
||||
if (check_nfs4_error(nfs, status, data, res, "READLINK")) {
|
||||
free_nfs4_cb_data(data);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((i = nfs4_find_op(nfs, data, res, OP_READLINK, "READLINK")) < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
rlresok = &res->resarray.resarray_val[i].nfs_resop4_u.opreadlink.READLINK4res_u.resok4;
|
||||
|
||||
data->cb(0, nfs, rlresok->link.utf8string_val, data->private_data);
|
||||
free_nfs4_cb_data(data);
|
||||
}
|
||||
|
||||
static void
|
||||
nfs4_populate_readlink(struct nfs4_cb_data *data, nfs_argop4 *op)
|
||||
{
|
||||
op[0].argop = OP_READLINK;
|
||||
}
|
||||
|
||||
int
|
||||
nfs4_readlink_async(struct nfs_context *nfs, const char *path, nfs_cb cb,
|
||||
void *private_data)
|
||||
{
|
||||
struct nfs4_cb_data *data;
|
||||
|
||||
data = malloc(sizeof(*data));
|
||||
if (data == NULL) {
|
||||
nfs_set_error(nfs, "Out of memory. Failed to allocate "
|
||||
"cb data");
|
||||
return -1;
|
||||
}
|
||||
memset(data, 0, sizeof(*data));
|
||||
data->nfs = nfs;
|
||||
data->cb = cb;
|
||||
data->private_data = private_data;
|
||||
data->path = nfs4_resolve_path(nfs, path);
|
||||
|
||||
if (data->path == NULL) {
|
||||
nfs_set_error(nfs, "Out of memory duplicating path");
|
||||
free_nfs4_cb_data(data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
data->filler.func = nfs4_populate_readlink;
|
||||
data->filler.num_op = 1;
|
||||
|
||||
if (nfs4_lookup_path_async(nfs, data, nfs4_readlink_cb) < 0) {
|
||||
free_nfs4_cb_data(data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue