nfs_opendir() switch to using READDIRPLUS3 instead of READDIR3 when reading directories.
parent
e02614571c
commit
f390f18157
|
@ -444,7 +444,7 @@ int rpc_nfs_remove_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh,
|
|||
|
||||
|
||||
/*
|
||||
* Call NFS/REMOVE
|
||||
* Call NFS/READDIR
|
||||
* Function returns
|
||||
* 0 : The call was initiated. The callback will be invoked when the call completes.
|
||||
* <0 : An error occured when trying to set up the call. The callback will not be invoked.
|
||||
|
@ -459,6 +459,22 @@ int rpc_nfs_remove_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh,
|
|||
*/
|
||||
int rpc_nfs_readdir_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, uint64_t cookie, char *cookieverf, int count, void *private_data);
|
||||
|
||||
/*
|
||||
* Call NFS/READDIRPLUS
|
||||
* Function returns
|
||||
* 0 : The call was initiated. The callback will be invoked when the call completes.
|
||||
* <0 : An error occured when trying to set up the call. The callback will not be invoked.
|
||||
*
|
||||
* When the callback is invoked, status indicates the result:
|
||||
* RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon.
|
||||
* data is READDIRPLUS3res *
|
||||
* RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon.
|
||||
* data is the error string.
|
||||
* RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete.
|
||||
* data is NULL.
|
||||
*/
|
||||
int rpc_nfs_readdirplus_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, uint64_t cookie, char *cookieverf, int count, void *private_data);
|
||||
|
||||
/*
|
||||
* Call NFS/FSSTAT
|
||||
* Function returns
|
||||
|
|
16
lib/libnfs.c
16
lib/libnfs.c
|
@ -1651,11 +1651,11 @@ int nfs_unlink_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void
|
|||
*/
|
||||
static void nfs_opendir_cb(struct rpc_context *rpc _U_, int status, void *command_data, void *private_data)
|
||||
{
|
||||
READDIR3res *res;
|
||||
READDIRPLUS3res *res;
|
||||
struct nfs_cb_data *data = private_data;
|
||||
struct nfs_context *nfs = data->nfs;
|
||||
struct nfsdir *nfsdir = data->continue_data;;
|
||||
struct entry3 *entry;
|
||||
struct entryplus3 *entry;
|
||||
uint64_t cookie;
|
||||
|
||||
if (status == RPC_STATUS_ERROR) {
|
||||
|
@ -1683,7 +1683,7 @@ static void nfs_opendir_cb(struct rpc_context *rpc _U_, int status, void *comman
|
|||
return;
|
||||
}
|
||||
|
||||
entry =res->READDIR3res_u.resok.reply.entries;
|
||||
entry =res->READDIRPLUS3res_u.resok.reply.entries;
|
||||
while (entry != NULL) {
|
||||
struct nfsdirent *nfsdirent;
|
||||
|
||||
|
@ -1712,9 +1712,9 @@ static void nfs_opendir_cb(struct rpc_context *rpc _U_, int status, void *comman
|
|||
entry = entry->nextentry;
|
||||
}
|
||||
|
||||
if (res->READDIR3res_u.resok.reply.eof == 0) {
|
||||
if (rpc_nfs_readdir_async(nfs->rpc, nfs_opendir_cb, &data->fh, cookie, res->READDIR3res_u.resok.cookieverf, 20000, data) != 0) {
|
||||
rpc_set_error(nfs->rpc, "RPC error: Failed to send READDIR call for %s", data->path);
|
||||
if (res->READDIRPLUS3res_u.resok.reply.eof == 0) {
|
||||
if (rpc_nfs_readdirplus_async(nfs->rpc, nfs_opendir_cb, &data->fh, cookie, res->READDIRPLUS3res_u.resok.cookieverf, 8192, data) != 0) {
|
||||
rpc_set_error(nfs->rpc, "RPC error: Failed to send READDIRPLUS call for %s", data->path);
|
||||
data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data);
|
||||
nfs_free_nfsdir(nfsdir);
|
||||
data->continue_data = NULL;
|
||||
|
@ -1737,8 +1737,8 @@ static int nfs_opendir_continue_internal(struct nfs_context *nfs, struct nfs_cb_
|
|||
cookieverf3 cv;
|
||||
|
||||
bzero(cv, sizeof(cookieverf3));
|
||||
if (rpc_nfs_readdir_async(nfs->rpc, nfs_opendir_cb, &data->fh, 0, (char *)&cv, 20000, data) != 0) {
|
||||
rpc_set_error(nfs->rpc, "RPC error: Failed to send READDIR call for %s", data->path);
|
||||
if (rpc_nfs_readdirplus_async(nfs->rpc, nfs_opendir_cb, &data->fh, 0, (char *)&cv, 8192, data) != 0) {
|
||||
rpc_set_error(nfs->rpc, "RPC error: Failed to send READDIRPLUS call for %s", data->path);
|
||||
data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data);
|
||||
free_nfs_cb_data(data);
|
||||
return -1;
|
||||
|
|
35
nfs/nfs.c
35
nfs/nfs.c
|
@ -476,7 +476,6 @@ int rpc_nfs_remove_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh,
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int rpc_nfs_readdir_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, uint64_t cookie, char *cookieverf, int count, void *private_data)
|
||||
{
|
||||
struct rpc_pdu *pdu;
|
||||
|
@ -510,6 +509,40 @@ int rpc_nfs_readdir_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh
|
|||
return 0;
|
||||
}
|
||||
|
||||
int rpc_nfs_readdirplus_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, uint64_t cookie, char *cookieverf, int count, void *private_data)
|
||||
{
|
||||
struct rpc_pdu *pdu;
|
||||
READDIRPLUS3args args;
|
||||
|
||||
pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_READDIRPLUS, cb, private_data, (xdrproc_t)xdr_READDIRPLUS3res, sizeof(READDIRPLUS3res));
|
||||
if (pdu == NULL) {
|
||||
rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nfs/readdirplus call");
|
||||
return -1;
|
||||
}
|
||||
|
||||
bzero(&args, sizeof(READDIRPLUS3args));
|
||||
args.dir.data.data_len = fh->data.data_len;
|
||||
args.dir.data.data_val = fh->data.data_val;
|
||||
args.cookie = cookie;
|
||||
memcpy(&args.cookieverf, cookieverf, sizeof(cookieverf3));
|
||||
args.dircount = count;
|
||||
args.maxcount = count;
|
||||
|
||||
if (xdr_READDIRPLUS3args(&pdu->xdr, &args) == 0) {
|
||||
rpc_set_error(rpc, "XDR error: Failed to encode READDIRPLUS3args");
|
||||
rpc_free_pdu(rpc, pdu);
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (rpc_queue_pdu(rpc, pdu) != 0) {
|
||||
rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nfs/readdirplus call");
|
||||
rpc_free_pdu(rpc, pdu);
|
||||
return -3;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rpc_nfs_fsstat_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, void *private_data)
|
||||
{
|
||||
struct rpc_pdu *pdu;
|
||||
|
|
Loading…
Reference in New Issue