libnfs.c: always pass the attributes to the callback for recursive lookups
Always pass a fattr3 structure to the callbacks for the internal function to perform recursive lookups : nfs_lookuppath_async(). This will allow us to access for example the mtime for an object before we start performing any expensive functions. Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>libnfs-4.0.0-vitalif
parent
c63ba81eeb
commit
20379f03fc
135
lib/libnfs.c
135
lib/libnfs.c
|
@ -112,7 +112,8 @@ void nfs_free_nfsdir(struct nfsdir *nfsdir)
|
|||
}
|
||||
|
||||
struct nfs_cb_data;
|
||||
typedef int (*continue_func)(struct nfs_context *nfs, struct nfs_cb_data *data);
|
||||
typedef int (*continue_func)(struct nfs_context *nfs, fattr3 *attr,
|
||||
struct nfs_cb_data *data);
|
||||
|
||||
struct nfs_cb_data {
|
||||
struct nfs_context *nfs;
|
||||
|
@ -147,7 +148,7 @@ struct nfs_mcb_data {
|
|||
int update_pos;
|
||||
};
|
||||
|
||||
static int nfs_lookup_path_async_internal(struct nfs_context *nfs, struct nfs_cb_data *data, struct nfs_fh3 *fh);
|
||||
static int nfs_lookup_path_async_internal(struct nfs_context *nfs, fattr3 *attr, struct nfs_cb_data *data, struct nfs_fh3 *fh);
|
||||
|
||||
void nfs_set_auth(struct nfs_context *nfs, struct AUTH *auth)
|
||||
{
|
||||
|
@ -640,9 +641,6 @@ static void free_nfs_cb_data(struct nfs_cb_data *data)
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void nfs_mount_10_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data)
|
||||
{
|
||||
struct nfs_cb_data *data = private_data;
|
||||
|
@ -848,6 +846,7 @@ static void nfs_lookup_path_1_cb(struct rpc_context *rpc, int status, void *comm
|
|||
struct nfs_cb_data *data = private_data;
|
||||
struct nfs_context *nfs = data->nfs;
|
||||
LOOKUP3res *res;
|
||||
fattr3 *attr;
|
||||
|
||||
assert(rpc->magic == RPC_CONTEXT_MAGIC);
|
||||
|
||||
|
@ -870,15 +869,17 @@ static void nfs_lookup_path_1_cb(struct rpc_context *rpc, int status, void *comm
|
|||
return;
|
||||
}
|
||||
|
||||
if (nfs_lookup_path_async_internal(nfs, data, &res->LOOKUP3res_u.resok.object) != 0) {
|
||||
rpc_set_error(nfs->rpc, "Failed to create lookup pdu");
|
||||
data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data);
|
||||
free_nfs_cb_data(data);
|
||||
return;
|
||||
}
|
||||
attr = res->LOOKUP3res_u.resok.obj_attributes.attributes_follow ?
|
||||
&res->LOOKUP3res_u.resok.obj_attributes.post_op_attr_u.attributes :
|
||||
NULL;
|
||||
|
||||
/* This function will always invoke the callback and cleanup
|
||||
* for failures. So no need to check the return value.
|
||||
*/
|
||||
nfs_lookup_path_async_internal(nfs, attr, data, &res->LOOKUP3res_u.resok.object);
|
||||
}
|
||||
|
||||
static int nfs_lookup_path_async_internal(struct nfs_context *nfs, struct nfs_cb_data *data, struct nfs_fh3 *fh)
|
||||
static int nfs_lookup_path_async_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data, struct nfs_fh3 *fh)
|
||||
{
|
||||
char *path, *slash;
|
||||
LOOKUP3args args;
|
||||
|
@ -917,11 +918,10 @@ static int nfs_lookup_path_async_internal(struct nfs_context *nfs, struct nfs_cb
|
|||
if (slash != NULL) {
|
||||
*slash = '/';
|
||||
}
|
||||
data->continue_cb(nfs, data);
|
||||
data->continue_cb(nfs, attr, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
memset(&args, 0, sizeof(LOOKUP3args));
|
||||
args.what.dir = *fh;
|
||||
args.what.name = path;
|
||||
|
@ -1038,9 +1038,45 @@ static int nfs_normalize_path(struct nfs_context *nfs, char *path)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void nfs_lookup_path_getattr_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data)
|
||||
{
|
||||
struct nfs_cb_data *data = private_data;
|
||||
struct nfs_context *nfs = data->nfs;
|
||||
GETATTR3res *res;
|
||||
fattr3 *attr;
|
||||
|
||||
assert(rpc->magic == RPC_CONTEXT_MAGIC);
|
||||
|
||||
if (status == RPC_STATUS_ERROR) {
|
||||
data->cb(-EFAULT, nfs, command_data, data->private_data);
|
||||
free_nfs_cb_data(data);
|
||||
return;
|
||||
}
|
||||
if (status == RPC_STATUS_CANCEL) {
|
||||
data->cb(-EINTR, nfs, "Command was cancelled", data->private_data);
|
||||
free_nfs_cb_data(data);
|
||||
return;
|
||||
}
|
||||
|
||||
res = command_data;
|
||||
if (res->status != NFS3_OK) {
|
||||
rpc_set_error(nfs->rpc, "NFS: GETATTR of %s failed with %s(%d)", data->saved_path, nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status));
|
||||
data->cb(nfsstat3_to_errno(res->status), nfs, rpc_get_error(nfs->rpc), data->private_data);
|
||||
free_nfs_cb_data(data);
|
||||
return;
|
||||
}
|
||||
|
||||
attr = &res->GETATTR3res_u.resok.obj_attributes;
|
||||
/* This function will always invoke the callback and cleanup
|
||||
* for failures. So no need to check the return value.
|
||||
*/
|
||||
nfs_lookup_path_async_internal(nfs, attr, data, &nfs->rootfh);
|
||||
}
|
||||
|
||||
static int nfs_lookuppath_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data, continue_func continue_cb, void *continue_data, void (*free_continue_data)(void *), int continue_int)
|
||||
{
|
||||
struct nfs_cb_data *data;
|
||||
struct GETATTR3args args;
|
||||
|
||||
if (path[0] == '\0') {
|
||||
path = ".";
|
||||
|
@ -1086,16 +1122,25 @@ static int nfs_lookuppath_async(struct nfs_context *nfs, const char *path, nfs_c
|
|||
}
|
||||
|
||||
data->path = data->saved_path;
|
||||
|
||||
if (nfs_lookup_path_async_internal(nfs, data, &nfs->rootfh) != 0) {
|
||||
/* return 0 here since the callback will be invoked if there is a failure */
|
||||
return 0;
|
||||
}
|
||||
if (data->path[0]) {
|
||||
/* This function will always invoke the callback and cleanup
|
||||
* for failures. So no need to check the return value.
|
||||
*/
|
||||
nfs_lookup_path_async_internal(nfs, NULL, data, &nfs->rootfh);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* We have a request for "", so just perform a GETATTR3 so we can
|
||||
* return the attributes to the caller.
|
||||
*/
|
||||
memset(&args, 0, sizeof(GETATTR3args));
|
||||
args.object = nfs->rootfh;
|
||||
if (rpc_nfs3_getattr_async(nfs->rpc, nfs_lookup_path_getattr_cb, &args, data) != 0) {
|
||||
free_nfs_cb_data(data);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
@ -1159,7 +1204,7 @@ static void nfs_stat_1_cb(struct rpc_context *rpc, int status, void *command_dat
|
|||
free_nfs_cb_data(data);
|
||||
}
|
||||
|
||||
static int nfs_stat_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data)
|
||||
static int nfs_stat_continue_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data)
|
||||
{
|
||||
struct GETATTR3args args;
|
||||
|
||||
|
@ -1239,7 +1284,7 @@ static void nfs_stat64_1_cb(struct rpc_context *rpc, int status, void *command_d
|
|||
free_nfs_cb_data(data);
|
||||
}
|
||||
|
||||
static int nfs_stat64_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data)
|
||||
static int nfs_stat64_continue_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data)
|
||||
{
|
||||
struct GETATTR3args args;
|
||||
|
||||
|
@ -1419,7 +1464,7 @@ static void nfs_open_cb(struct rpc_context *rpc, int status, void *command_data,
|
|||
free_nfs_cb_data(data);
|
||||
}
|
||||
|
||||
static int nfs_open_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data)
|
||||
static int nfs_open_continue_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data)
|
||||
{
|
||||
int nfsmode = 0;
|
||||
ACCESS3args args;
|
||||
|
@ -1463,7 +1508,7 @@ int nfs_open_async(struct nfs_context *nfs, const char *path, int flags, nfs_cb
|
|||
/*
|
||||
* Async chdir()
|
||||
*/
|
||||
static int nfs_chdir_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data)
|
||||
static int nfs_chdir_continue_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data)
|
||||
{
|
||||
/* steal saved_path */
|
||||
free(nfs->cwd);
|
||||
|
@ -2127,7 +2172,7 @@ int nfs_ftruncate_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t l
|
|||
/*
|
||||
* Async truncate()
|
||||
*/
|
||||
static int nfs_truncate_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data)
|
||||
static int nfs_truncate_continue_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data)
|
||||
{
|
||||
uint64_t offset = data->continue_int;
|
||||
struct nfsfh nfsfh;
|
||||
|
@ -2198,7 +2243,7 @@ static void nfs_mkdir_cb(struct rpc_context *rpc, int status, void *command_data
|
|||
free_nfs_cb_data(data);
|
||||
}
|
||||
|
||||
static int nfs_mkdir_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data)
|
||||
static int nfs_mkdir_continue_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data)
|
||||
{
|
||||
char *str = data->continue_data;
|
||||
MKDIR3args args;
|
||||
|
@ -2289,7 +2334,7 @@ static void nfs_rmdir_cb(struct rpc_context *rpc, int status, void *command_data
|
|||
free_nfs_cb_data(data);
|
||||
}
|
||||
|
||||
static int nfs_rmdir_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data)
|
||||
static int nfs_rmdir_continue_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data)
|
||||
{
|
||||
char *str = data->continue_data;
|
||||
RMDIR3args args;
|
||||
|
@ -2434,7 +2479,7 @@ static void nfs_creat_1_cb(struct rpc_context *rpc, int status, void *command_da
|
|||
return;
|
||||
}
|
||||
|
||||
static int nfs_creat_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data)
|
||||
static int nfs_creat_continue_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data)
|
||||
{
|
||||
char *str = data->continue_data;
|
||||
CREATE3args args;
|
||||
|
@ -2525,7 +2570,7 @@ static void nfs_unlink_cb(struct rpc_context *rpc, int status, void *command_dat
|
|||
free_nfs_cb_data(data);
|
||||
}
|
||||
|
||||
static int nfs_unlink_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data)
|
||||
static int nfs_unlink_continue_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data)
|
||||
{
|
||||
char *str = data->continue_data;
|
||||
struct REMOVE3args args;
|
||||
|
@ -2624,7 +2669,7 @@ static void nfs_mknod_cb(struct rpc_context *rpc, int status, void *command_data
|
|||
free_nfs_cb_data(data);
|
||||
}
|
||||
|
||||
static int nfs_mknod_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data)
|
||||
static int nfs_mknod_continue_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data)
|
||||
{
|
||||
struct mknod_cb_data *cb_data = data->continue_data;
|
||||
char *str = cb_data->path;
|
||||
|
@ -3046,7 +3091,7 @@ static void nfs_opendir_cb(struct rpc_context *rpc, int status, void *command_da
|
|||
free_nfs_cb_data(data);
|
||||
}
|
||||
|
||||
static int nfs_opendir_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data)
|
||||
static int nfs_opendir_continue_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data)
|
||||
{
|
||||
READDIRPLUS3args args;
|
||||
|
||||
|
@ -3267,7 +3312,7 @@ static void nfs_statvfs_1_cb(struct rpc_context *rpc, int status, void *command_
|
|||
free_nfs_cb_data(data);
|
||||
}
|
||||
|
||||
static int nfs_statvfs_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data)
|
||||
static int nfs_statvfs_continue_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data)
|
||||
{
|
||||
FSSTAT3args args;
|
||||
|
||||
|
@ -3329,7 +3374,7 @@ static void nfs_readlink_1_cb(struct rpc_context *rpc, int status, void *command
|
|||
free_nfs_cb_data(data);
|
||||
}
|
||||
|
||||
static int nfs_readlink_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data)
|
||||
static int nfs_readlink_continue_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data)
|
||||
{
|
||||
READLINK3args args;
|
||||
|
||||
|
@ -3391,7 +3436,7 @@ static void nfs_chmod_cb(struct rpc_context *rpc, int status, void *command_data
|
|||
free_nfs_cb_data(data);
|
||||
}
|
||||
|
||||
static int nfs_chmod_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data)
|
||||
static int nfs_chmod_continue_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data)
|
||||
{
|
||||
SETATTR3args args;
|
||||
|
||||
|
@ -3446,7 +3491,7 @@ int nfs_fchmod_async(struct nfs_context *nfs, struct nfsfh *nfsfh, int mode, nfs
|
|||
}
|
||||
memcpy(data->fh.data.data_val, nfsfh->fh.data.data_val, data->fh.data.data_len);
|
||||
|
||||
if (nfs_chmod_continue_internal(nfs, data) != 0) {
|
||||
if (nfs_chmod_continue_internal(nfs, NULL, data) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -3494,7 +3539,7 @@ struct nfs_chown_data {
|
|||
gid_t gid;
|
||||
};
|
||||
|
||||
static int nfs_chown_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data)
|
||||
static int nfs_chown_continue_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data)
|
||||
{
|
||||
SETATTR3args args;
|
||||
struct nfs_chown_data *chown_data = data->continue_data;
|
||||
|
@ -3580,7 +3625,7 @@ int nfs_fchown_async(struct nfs_context *nfs, struct nfsfh *nfsfh, int uid, int
|
|||
}
|
||||
memcpy(data->fh.data.data_val, nfsfh->fh.data.data_val, data->fh.data.data_len);
|
||||
|
||||
if (nfs_chown_continue_internal(nfs, data) != 0) {
|
||||
if (nfs_chown_continue_internal(nfs, NULL, data) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -3625,7 +3670,7 @@ static void nfs_utimes_cb(struct rpc_context *rpc, int status, void *command_dat
|
|||
free_nfs_cb_data(data);
|
||||
}
|
||||
|
||||
static int nfs_utimes_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data)
|
||||
static int nfs_utimes_continue_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data)
|
||||
{
|
||||
SETATTR3args args;
|
||||
struct timeval *utimes_data = data->continue_data;
|
||||
|
@ -3763,7 +3808,7 @@ static void nfs_access_cb(struct rpc_context *rpc, int status, void *command_dat
|
|||
free_nfs_cb_data(data);
|
||||
}
|
||||
|
||||
static int nfs_access_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data)
|
||||
static int nfs_access_continue_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data)
|
||||
{
|
||||
int nfsmode = 0;
|
||||
ACCESS3args args;
|
||||
|
@ -3860,7 +3905,7 @@ static void nfs_symlink_cb(struct rpc_context *rpc, int status, void *command_da
|
|||
free_nfs_cb_data(data);
|
||||
}
|
||||
|
||||
static int nfs_symlink_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data)
|
||||
static int nfs_symlink_continue_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data)
|
||||
{
|
||||
struct nfs_symlink_data *symlink_data = data->continue_data;
|
||||
SYMLINK3args args;
|
||||
|
@ -3996,7 +4041,7 @@ static void nfs_rename_cb(struct rpc_context *rpc, int status, void *command_dat
|
|||
free_nfs_cb_data(data);
|
||||
}
|
||||
|
||||
static int nfs_rename_continue_2_internal(struct nfs_context *nfs, struct nfs_cb_data *data)
|
||||
static int nfs_rename_continue_2_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data)
|
||||
{
|
||||
struct nfs_rename_data *rename_data = data->continue_data;
|
||||
RENAME3args args;
|
||||
|
@ -4019,7 +4064,7 @@ static int nfs_rename_continue_2_internal(struct nfs_context *nfs, struct nfs_cb
|
|||
}
|
||||
|
||||
|
||||
static int nfs_rename_continue_1_internal(struct nfs_context *nfs, struct nfs_cb_data *data)
|
||||
static int nfs_rename_continue_1_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data)
|
||||
{
|
||||
struct nfs_rename_data *rename_data = data->continue_data;
|
||||
char* newpath = strdup(rename_data->newpath);
|
||||
|
@ -4166,7 +4211,7 @@ static void nfs_link_cb(struct rpc_context *rpc, int status, void *command_data,
|
|||
free_nfs_cb_data(data);
|
||||
}
|
||||
|
||||
static int nfs_link_continue_2_internal(struct nfs_context *nfs, struct nfs_cb_data *data)
|
||||
static int nfs_link_continue_2_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data)
|
||||
{
|
||||
struct nfs_link_data *link_data = data->continue_data;
|
||||
LINK3args args;
|
||||
|
@ -4189,7 +4234,7 @@ static int nfs_link_continue_2_internal(struct nfs_context *nfs, struct nfs_cb_d
|
|||
}
|
||||
|
||||
|
||||
static int nfs_link_continue_1_internal(struct nfs_context *nfs, struct nfs_cb_data *data)
|
||||
static int nfs_link_continue_1_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data)
|
||||
{
|
||||
struct nfs_link_data *link_data = data->continue_data;
|
||||
|
||||
|
|
Loading…
Reference in New Issue