X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=lib%2Flibnfs.c;h=eab8fd2d936216408167d6f822604c66f2bc473f;hb=2fa14f9b97e2d20aedca55502ae03cf09dfe23b0;hp=b90205d7778907141051e673e5312ef63ead3c1f;hpb=36f488dc7a5baa0b2e81faf50d76eb8539b4c596;p=deb_libnfs.git diff --git a/lib/libnfs.c b/lib/libnfs.c index b90205d..eab8fd2 100644 --- a/lib/libnfs.c +++ b/lib/libnfs.c @@ -93,6 +93,7 @@ struct nfs_context { struct nfs_fh3 rootfh; uint64_t readmax; uint64_t writemax; + char *cwd; }; void nfs_free_nfsdir(struct nfsdir *nfsdir) @@ -142,7 +143,6 @@ struct nfs_mcb_data { static int nfs_lookup_path_async_internal(struct nfs_context *nfs, struct nfs_cb_data *data, struct nfs_fh3 *fh); - void nfs_set_auth(struct nfs_context *nfs, struct AUTH *auth) { rpc_set_auth(nfs->rpc, auth); @@ -173,14 +173,14 @@ char *nfs_get_error(struct nfs_context *nfs) return rpc_get_error(nfs->rpc); }; -int rpc_set_context_args(struct rpc_context *rpc, char *arg, char *val) +static int nfs_set_context_args(struct nfs_context *nfs, char *arg, char *val) { if (!strncmp(arg, "tcp-syncnt", 10)) { - rpc_set_tcp_syncnt(rpc, atoi(val)); + rpc_set_tcp_syncnt(nfs_get_rpc_context(nfs), atoi(val)); } else if (!strncmp(arg, "uid", 3)) { - rpc_set_uid(rpc, atoi(val)); + rpc_set_uid(nfs_get_rpc_context(nfs), atoi(val)); } else if (!strncmp(arg, "gid", 3)) { - rpc_set_gid(rpc, atoi(val)); + rpc_set_gid(nfs_get_rpc_context(nfs), atoi(val)); } return 0; } @@ -201,6 +201,7 @@ static struct nfs_url *nfs_parse_url(struct nfs_context *nfs, const char *url, i return NULL; } + memset(urls, 0x00, sizeof(struct nfs_url)); urls->server = strdup(url + 6); if (urls->server == NULL) { nfs_destroy_url(urls); @@ -277,11 +278,6 @@ flags: } } - if (urls->server && strlen(urls->server) <= 1) { - free(urls->server); - urls->server = NULL; - } - while (flagsp != NULL && *(flagsp+1) != 0) { strp = flagsp + 1; flagsp = strchr(strp, '&'); @@ -292,11 +288,15 @@ flags: if (strp2) { *strp2 = 0; strp2++; - rpc_set_context_args(nfs_get_rpc_context(nfs), - strp, strp2); + nfs_set_context_args(nfs, strp, strp2); } } + if (urls->server && strlen(urls->server) <= 1) { + free(urls->server); + urls->server = NULL; + } + return urls; } @@ -334,17 +334,15 @@ struct nfs_context *nfs_init_context(void) if (nfs == NULL) { return NULL; } + memset(nfs, 0, sizeof(struct nfs_context)); + nfs->rpc = rpc_init_context(); if (nfs->rpc == NULL) { free(nfs); return NULL; } - nfs->server = NULL; - nfs->export = NULL; - - nfs->rootfh.data.data_len = 0; - nfs->rootfh.data.data_val = NULL; + nfs->cwd = strdup("/"); return nfs; } @@ -364,6 +362,11 @@ void nfs_destroy_context(struct nfs_context *nfs) nfs->export = NULL; } + if (nfs->cwd) { + free(nfs->cwd); + nfs->cwd = NULL; + } + if (nfs->rootfh.data.data_val != NULL) { free(nfs->rootfh.data.data_val); nfs->rootfh.data.data_val = NULL; @@ -379,7 +382,7 @@ struct rpc_cb_data { rpc_cb cb; void *private_data; -}; +}; void free_rpc_cb_data(struct rpc_cb_data *data) { @@ -419,7 +422,7 @@ static void rpc_connect_program_3_cb(struct rpc_context *rpc, int status, void * assert(rpc->magic == RPC_CONTEXT_MAGIC); - if (status == RPC_STATUS_ERROR) { + if (status == RPC_STATUS_ERROR) { data->cb(rpc, status, command_data, data->private_data); free_rpc_cb_data(data); return; @@ -521,27 +524,16 @@ int rpc_connect_program_async(struct rpc_context *rpc, char *server, int program return 0; } -void free_nfs_cb_data(struct nfs_cb_data *data) +static void free_nfs_cb_data(struct nfs_cb_data *data) { - if (data->saved_path != NULL) { - free(data->saved_path); - data->saved_path = NULL; - } - if (data->continue_data != NULL) { + assert(data->free_continue_data); data->free_continue_data(data->continue_data); - data->continue_data = NULL; - } - - if (data->fh.data.data_val != NULL) { - free(data->fh.data.data_val); - data->fh.data.data_val = NULL; } - if (data->buffer != NULL) { - free(data->buffer); - data->buffer = NULL; - } + free(data->saved_path); + free(data->fh.data.data_val); + free(data->buffer); free(data); } @@ -596,8 +588,7 @@ static void nfs_mount_9_cb(struct rpc_context *rpc, int status, void *command_da nfs->writemax = res->FSINFO3res_u.resok.wtmax; memset(&args, 0, sizeof(GETATTR3args)); - args.object.data.data_len = nfs->rootfh.data.data_len; - args.object.data.data_val = nfs->rootfh.data.data_val; + args.object = nfs->rootfh; if (rpc_nfs3_getattr_async(rpc, nfs_mount_10_cb, &args, data) != 0) { data->cb(-ENOMEM, nfs, command_data, data->private_data); @@ -610,6 +601,7 @@ static void nfs_mount_8_cb(struct rpc_context *rpc, int status, void *command_da { struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; + struct FSINFO3args args; assert(rpc->magic == RPC_CONTEXT_MAGIC); @@ -624,7 +616,8 @@ static void nfs_mount_8_cb(struct rpc_context *rpc, int status, void *command_da return; } - if (rpc_nfs_fsinfo_async(rpc, nfs_mount_9_cb, &nfs->rootfh, data) != 0) { + args.fsroot = nfs->rootfh; + if (rpc_nfs3_fsinfo_async(rpc, nfs_mount_9_cb, &args, data) != 0) { data->cb(-ENOMEM, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; @@ -653,7 +646,7 @@ static void nfs_mount_7_cb(struct rpc_context *rpc, int status, void *command_da return; } - if (rpc_nfs_null_async(rpc, nfs_mount_8_cb, data) != 0) { + if (rpc_nfs3_null_async(rpc, nfs_mount_8_cb, data) != 0) { data->cb(-ENOMEM, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; @@ -727,7 +720,7 @@ static void nfs_mount_5_cb(struct rpc_context *rpc, int status, void *command_da return; } - if (rpc_mount_mnt_async(rpc, nfs_mount_6_cb, nfs->export, data) != 0) { + if (rpc_mount3_mnt_async(rpc, nfs_mount_6_cb, nfs->export, data) != 0) { data->cb(-ENOMEM, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; @@ -755,7 +748,7 @@ static void nfs_mount_4_cb(struct rpc_context *rpc, int status, void *command_da return; } - if (rpc_mount_null_async(rpc, nfs_mount_5_cb, data) != 0) { + if (rpc_mount3_null_async(rpc, nfs_mount_5_cb, data) != 0) { data->cb(-ENOMEM, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; @@ -770,7 +763,7 @@ static void nfs_mount_3_cb(struct rpc_context *rpc, int status, void *command_da assert(rpc->magic == RPC_CONTEXT_MAGIC); - if (status == RPC_STATUS_ERROR) { + if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; @@ -931,7 +924,7 @@ static void nfs_lookup_path_1_cb(struct rpc_context *rpc, int status, void *comm static int nfs_lookup_path_async_internal(struct nfs_context *nfs, struct nfs_cb_data *data, struct nfs_fh3 *fh) { - char *path, *str; + char *path, *slash; LOOKUP3args args; while (*data->path == '/') { @@ -939,10 +932,16 @@ static int nfs_lookup_path_async_internal(struct nfs_context *nfs, struct nfs_cb } path = data->path; - str = strchr(path, '/'); - if (str != NULL) { - *str = 0; - data->path = str+1; + slash = strchr(path, '/'); + if (slash != NULL) { + /* Clear slash so that path is a zero terminated string for + * the current path component. Set it back to '/' again later + * when we are finished referencing this component so that + * data->saved_path will still point to the full + * normalized path. + */ + *slash = 0; + data->path = slash+1; } else { while (*data->path != 0) { data->path++; @@ -959,15 +958,17 @@ static int nfs_lookup_path_async_internal(struct nfs_context *nfs, struct nfs_cb return -1; } memcpy(data->fh.data.data_val, fh->data.data_val, data->fh.data.data_len); + if (slash != NULL) { + *slash = '/'; + } data->continue_cb(nfs, data); return 0; } memset(&args, 0, sizeof(LOOKUP3args)); - args.what.dir.data.data_len = fh->data.data_len; - args.what.dir.data.data_val = fh->data.data_val; - args.what.name = path; + args.what.dir = *fh; + args.what.name = path; if (rpc_nfs3_lookup_async(nfs->rpc, nfs_lookup_path_1_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send lookup call for %s", data->path); @@ -975,6 +976,109 @@ static int nfs_lookup_path_async_internal(struct nfs_context *nfs, struct nfs_cb free_nfs_cb_data(data); return -1; } + if (slash != NULL) { + *slash = '/'; + } + return 0; +} + +static int nfs_normalize_path(struct nfs_context *nfs, char *path) +{ + char *str; + int len; + + /* // -> / */ + while ((str = strstr(path, "//"))) { + while(*str) { + *str = *(str + 1); + str++; + } + } + + /* /./ -> / */ + while ((str = strstr(path, "/./"))) { + while(*(str + 1)) { + *str = *(str + 2); + str++; + } + } + + /* ^/../ -> error */ + if (!strncmp(path, "/../", 4)) { + rpc_set_error(nfs->rpc, + "Absolute path starts with '/../' " + "during normalization"); + return -1; + } + + /* ^[^/] -> error */ + if (path[0] != '/') { + rpc_set_error(nfs->rpc, + "Absolute path does not start with '/'"); + return -1; + } + + /* /string/../ -> / */ + while ((str = strstr(path, "/../"))) { + char *tmp; + + if (!strncmp(path, "/../", 4)) { + rpc_set_error(nfs->rpc, + "Absolute path starts with '/../' " + "during normalization"); + return -1; + } + + tmp = str - 1; + while (*tmp != '/') { + tmp--; + } + str += 3; + while((*(tmp++) = *(str++)) != '\0') + ; + } + + /* /$ -> \0 */ + len = strlen(path); + if (len >= 1) { + if (path[len - 1] == '/') { + path[len - 1] = '\0'; + len--; + } + } + if (path[0] == '\0') { + rpc_set_error(nfs->rpc, + "Absolute path became '' " + "during normalization"); + return -1; + } + + /* /.$ -> \0 */ + if (len >= 2) { + if (!strcmp(&path[len - 2], "/.")) { + path[len - 2] = '\0'; + len -= 2; + } + } + + /* ^/..$ -> error */ + if (!strcmp(path, "/..")) { + rpc_set_error(nfs->rpc, + "Absolute path is '/..' " + "during normalization"); + return -1; + } + + /* /string/..$ -> / */ + if (len >= 3) { + if (!strcmp(&path[len - 3], "/..")) { + char *tmp = &path[len - 3]; + while (*--tmp != '/') + ; + *tmp = '\0'; + } + } + return 0; } @@ -982,14 +1086,16 @@ static int nfs_lookuppath_async(struct nfs_context *nfs, const char *path, nfs_c { struct nfs_cb_data *data; - if (path[0] != 0 && path[0] != '/') { - rpc_set_error(nfs->rpc, "Pathname is not absolute %s", path); - return -1; + if (path[0] == '\0') { + path = "."; } data = malloc(sizeof(struct nfs_cb_data)); if (data == NULL) { - rpc_set_error(nfs->rpc, "out of memory: failed to allocate nfs_cb_data structure"); + rpc_set_error(nfs->rpc, "out of memory: failed to allocate " + "nfs_cb_data structure"); + if (free_continue_data) + free_continue_data(continue_data); return -1; } memset(data, 0, sizeof(struct nfs_cb_data)); @@ -1000,12 +1106,29 @@ static int nfs_lookuppath_async(struct nfs_context *nfs, const char *path, nfs_c data->free_continue_data = free_continue_data; data->continue_int = continue_int; data->private_data = private_data; - data->saved_path = strdup(path); + if (path[0] == '/') { + data->saved_path = strdup(path); + } else { + data->saved_path = malloc(strlen(path) + strlen(nfs->cwd) + 2); + if (data->saved_path == NULL) { + rpc_set_error(nfs->rpc, "out of memory: failed to " + "malloc path string"); + free_nfs_cb_data(data); + return -1; + } + sprintf(data->saved_path, "%s/%s", nfs->cwd, path); + } + if (data->saved_path == NULL) { rpc_set_error(nfs->rpc, "out of memory: failed to copy path string"); free_nfs_cb_data(data); return -1; } + if (nfs_normalize_path(nfs, data->saved_path) != 0) { + free_nfs_cb_data(data); + return -1; + } + data->path = data->saved_path; if (nfs_lookup_path_async_internal(nfs, data, &nfs->rootfh) != 0) { @@ -1027,7 +1150,11 @@ static void nfs_stat_1_cb(struct rpc_context *rpc, int status, void *command_dat GETATTR3res *res; struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; +#ifdef WIN32 + struct __stat64 st; +#else struct stat st; +#endif assert(rpc->magic == RPC_CONTEXT_MAGIC); @@ -1067,7 +1194,7 @@ static void nfs_stat_1_cb(struct rpc_context *rpc, int status, void *command_dat #ifndef WIN32 st.st_blksize = 4096; st.st_blocks = res->GETATTR3res_u.resok.obj_attributes.size / 4096; -#endif//WIN32 +#endif//WIN32 st.st_atime = res->GETATTR3res_u.resok.obj_attributes.atime.seconds; st.st_mtime = res->GETATTR3res_u.resok.obj_attributes.mtime.seconds; st.st_ctime = res->GETATTR3res_u.resok.obj_attributes.ctime.seconds; @@ -1081,8 +1208,7 @@ static int nfs_stat_continue_internal(struct nfs_context *nfs, struct nfs_cb_dat struct GETATTR3args args; memset(&args, 0, sizeof(GETATTR3args)); - args.object.data.data_len = data->fh.data.data_len; - args.object.data.data_val = data->fh.data.data_val; + args.object = data->fh; if (rpc_nfs3_getattr_async(nfs->rpc, nfs_stat_1_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send STAT GETATTR call for %s", data->path); @@ -1105,11 +1231,58 @@ int nfs_stat_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *p - - /* * Async open() */ +static void nfs_open_trunc_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; + struct nfsfh *nfsfh; + SETATTR3res *res; + + 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: Setattr failed with %s(%d)", 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; + } + + nfsfh = malloc(sizeof(struct nfsfh)); + if (nfsfh == NULL) { + rpc_set_error(nfs->rpc, "NFS: Failed to allocate nfsfh structure"); + data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); + free_nfs_cb_data(data); + return; + } + memset(nfsfh, 0, sizeof(struct nfsfh)); + + if (data->continue_int & O_SYNC) { + nfsfh->is_sync = 1; + } + + /* steal the filehandle */ + nfsfh->fh = data->fh; + data->fh.data.data_val = NULL; + + data->cb(0, nfs, nfsfh, data->private_data); + free_nfs_cb_data(data); +} + static void nfs_open_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { ACCESS3res *res; @@ -1163,6 +1336,28 @@ static void nfs_open_cb(struct rpc_context *rpc, int status, void *command_data, return; } + /* Try to truncate it if we were requested to */ + if ((data->continue_int & O_TRUNC) && + (data->continue_int & (O_RDWR|O_WRONLY))) { + SETATTR3args args; + + memset(&args, 0, sizeof(SETATTR3args)); + args.object = data->fh; + args.new_attributes.size.set_it = 1; + args.new_attributes.size.set_size3_u.size = 0; + + if (rpc_nfs3_setattr_async(nfs->rpc, nfs_open_trunc_cb, &args, + data) != 0) { + rpc_set_error(nfs->rpc, "RPC error: Failed to send " + "SETATTR call for %s", data->path); + data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), + data->private_data); + free_nfs_cb_data(data); + return; + } + return; + } + nfsfh = malloc(sizeof(struct nfsfh)); if (nfsfh == NULL) { rpc_set_error(nfs->rpc, "NFS: Failed to allocate nfsfh structure"); @@ -1177,8 +1372,7 @@ static void nfs_open_cb(struct rpc_context *rpc, int status, void *command_data, } /* steal the filehandle */ - nfsfh->fh.data.data_len = data->fh.data.data_len; - nfsfh->fh.data.data_val = data->fh.data.data_val; + nfsfh->fh = data->fh; data->fh.data.data_val = NULL; data->cb(0, nfs, nfsfh, data->private_data); @@ -1201,22 +1395,23 @@ static int nfs_open_continue_internal(struct nfs_context *nfs, struct nfs_cb_dat } memset(&args, 0, sizeof(ACCESS3args)); - args.object.data.data_len = data->fh.data.data_len; - args.object.data.data_val = data->fh.data.data_val; + args.object = data->fh; args.access = nfsmode; if (rpc_nfs3_access_async(nfs->rpc, nfs_open_cb, &args, data) != 0) { - rpc_set_error(nfs->rpc, "RPC error: Failed to send OPEN ACCESS call for %s", data->path); - data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); + rpc_set_error(nfs->rpc, "RPC error: Failed to send OPEN ACCESS " + "call for %s", data->path); + data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), + data->private_data); free_nfs_cb_data(data); return -1; } return 0; } -int nfs_open_async(struct nfs_context *nfs, const char *path, int mode, nfs_cb cb, void *private_data) +int nfs_open_async(struct nfs_context *nfs, const char *path, int flags, nfs_cb cb, void *private_data) { - if (nfs_lookuppath_async(nfs, path, cb, private_data, nfs_open_continue_internal, NULL, NULL, mode) != 0) { + if (nfs_lookuppath_async(nfs, path, cb, private_data, nfs_open_continue_internal, NULL, NULL, flags) != 0) { rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); return -1; } @@ -1225,7 +1420,31 @@ int nfs_open_async(struct nfs_context *nfs, const char *path, int mode, nfs_cb c } +/* + * Async chdir() + */ +static int nfs_chdir_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data) +{ + /* steal saved_path */ + free(nfs->cwd); + nfs->cwd = data->saved_path; + data->saved_path = NULL; + + data->cb(0, nfs, NULL, data->private_data); + free_nfs_cb_data(data); + return 0; +} + +int nfs_chdir_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data) +{ + if (nfs_lookuppath_async(nfs, path, cb, private_data, nfs_chdir_continue_internal, NULL, NULL, 0) != 0) { + rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); + return -1; + } + + return 0; +} /* @@ -1346,8 +1565,7 @@ int nfs_pread_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offse READ3args args; memset(&args, 0, sizeof(READ3args)); - args.file.data.data_len = nfsfh->fh.data.data_len; - args.file.data.data_val = nfsfh->fh.data.data_val; + args.file = nfsfh->fh; args.offset = offset; args.count = count; @@ -1395,8 +1613,7 @@ int nfs_pread_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offse mdata->count = readcount; memset(&args, 0, sizeof(READ3args)); - args.file.data.data_len = nfsfh->fh.data.data_len; - args.file.data.data_val = nfsfh->fh.data.data_val; + args.file = nfsfh->fh; args.offset = offset; args.count = readcount; @@ -1542,8 +1759,7 @@ int nfs_pwrite_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offs WRITE3args args; memset(&args, 0, sizeof(WRITE3args)); - args.file.data.data_len = nfsfh->fh.data.data_len; - args.file.data.data_val = nfsfh->fh.data.data_val; + args.file = nfsfh->fh; args.offset = offset; args.count = count; args.stable = nfsfh->is_sync?FILE_SYNC:UNSTABLE; @@ -1586,8 +1802,7 @@ int nfs_pwrite_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offs mdata->count = writecount; memset(&args, 0, sizeof(WRITE3args)); - args.file.data.data_len = nfsfh->fh.data.data_len; - args.file.data.data_val = nfsfh->fh.data.data_val; + args.file = nfsfh->fh; args.offset = offset; args.count = writecount; args.stable = nfsfh->is_sync?FILE_SYNC:UNSTABLE; @@ -1623,7 +1838,7 @@ int nfs_write_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t count /* * close */ - + int nfs_close_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, void *private_data) { if (nfsfh->fh.data.data_val != NULL){ @@ -1659,8 +1874,7 @@ int nfs_fstat_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, voi data->private_data = private_data; memset(&args, 0, sizeof(GETATTR3args)); - args.object.data.data_len = nfsfh->fh.data.data_len; - args.object.data.data_val = nfsfh->fh.data.data_val; + args.object = nfsfh->fh; if (rpc_nfs3_getattr_async(nfs->rpc, nfs_stat_1_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send STAT GETATTR call for %s", data->path); @@ -1710,6 +1924,7 @@ static void nfs_fsync_cb(struct rpc_context *rpc, int status, void *command_data int nfs_fsync_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, void *private_data) { struct nfs_cb_data *data; + struct COMMIT3args args; data = malloc(sizeof(struct nfs_cb_data)); if (data == NULL) { @@ -1721,7 +1936,10 @@ int nfs_fsync_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, voi data->cb = cb; data->private_data = private_data; - if (rpc_nfs_commit_async(nfs->rpc, nfs_fsync_cb, &nfsfh->fh, data) != 0) { + args.file = nfsfh->fh; + args.offset = 0; + args.count = 0; + if (rpc_nfs3_commit_async(nfs->rpc, nfs_fsync_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send COMMIT call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -1783,12 +2001,11 @@ int nfs_ftruncate_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t l data->private_data = private_data; memset(&args, 0, sizeof(SETATTR3args)); - args.object.data.data_len = nfsfh->fh.data.data_len; - args.object.data.data_val = nfsfh->fh.data.data_val; + args.object = nfsfh->fh; args.new_attributes.size.set_it = 1; args.new_attributes.size.set_size3_u.size = length; - if (rpc_nfs_setattr_async(nfs->rpc, nfs_ftruncate_cb, &args, data) != 0) { + if (rpc_nfs3_setattr_async(nfs->rpc, nfs_ftruncate_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send SETATTR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -1806,8 +2023,7 @@ static int nfs_truncate_continue_internal(struct nfs_context *nfs, struct nfs_cb uint64_t offset = data->continue_int; struct nfsfh nfsfh; - nfsfh.fh.data.data_val = data->fh.data.data_val; - nfsfh.fh.data.data_len = data->fh.data.data_len; + nfsfh.fh = data->fh; if (nfs_ftruncate_async(nfs, &nfsfh, offset, data->cb, data->private_data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send SETATTR call for %s", data->path); @@ -1845,7 +2061,7 @@ static void nfs_mkdir_cb(struct rpc_context *rpc, int status, void *command_data struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; char *str = data->continue_data; - + assert(rpc->magic == RPC_CONTEXT_MAGIC); str = &str[strlen(str) + 1]; @@ -1881,13 +2097,12 @@ static int nfs_mkdir_continue_internal(struct nfs_context *nfs, struct nfs_cb_da str = &str[strlen(str) + 1]; memset(&args, 0, sizeof(MKDIR3args)); - args.where.dir.data.data_len = data->fh.data.data_len; - args.where.dir.data.data_val = data->fh.data.data_val; + args.where.dir = data->fh; args.where.name = str; args.attributes.mode.set_it = 1; args.attributes.mode.set_mode3_u.mode = 0755; - if (rpc_nfs_mkdir_async(nfs->rpc, nfs_mkdir_cb, &args, data) != 0) { + if (rpc_nfs3_mkdir_async(nfs->rpc, nfs_mkdir_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send MKDIR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -1936,7 +2151,7 @@ static void nfs_rmdir_cb(struct rpc_context *rpc, int status, void *command_data struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; char *str = data->continue_data; - + assert(rpc->magic == RPC_CONTEXT_MAGIC); str = &str[strlen(str) + 1]; @@ -1967,10 +2182,13 @@ static void nfs_rmdir_cb(struct rpc_context *rpc, int status, void *command_data static int nfs_rmdir_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data) { char *str = data->continue_data; - + RMDIR3args args; + str = &str[strlen(str) + 1]; - if (rpc_nfs_rmdir_async(nfs->rpc, nfs_rmdir_cb, &data->fh, str, data) != 0) { + args.object.dir = data->fh; + args.object.name = str; + if (rpc_nfs3_rmdir_async(nfs->rpc, nfs_rmdir_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send RMDIR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -2093,9 +2311,8 @@ static void nfs_creat_1_cb(struct rpc_context *rpc, int status, void *command_da } memset(&args, 0, sizeof(LOOKUP3args)); - args.what.dir.data.data_len = data->fh.data.data_len; - args.what.dir.data.data_val = data->fh.data.data_val; - args.what.name = str; + args.what.dir = data->fh; + args.what.name = str; if (rpc_nfs3_lookup_async(nfs->rpc, nfs_create_2_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send lookup call for %s/%s", data->saved_path, str); @@ -2114,14 +2331,13 @@ static int nfs_creat_continue_internal(struct nfs_context *nfs, struct nfs_cb_da str = &str[strlen(str) + 1]; memset(&args, 0, sizeof(CREATE3args)); - args.where.dir.data.data_len = data->fh.data.data_len; - args.where.dir.data.data_val = data->fh.data.data_val; + args.where.dir = data->fh; args.where.name = str; args.how.mode = UNCHECKED; args.how.createhow3_u.obj_attributes.mode.set_it = 1; args.how.createhow3_u.obj_attributes.mode.set_mode3_u.mode = data->continue_int; - if (rpc_nfs_create_async(nfs->rpc, nfs_creat_1_cb, &args, data) != 0) { + if (rpc_nfs3_create_async(nfs->rpc, nfs_creat_1_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send CREATE call for %s/%s", data->path, str); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -2144,6 +2360,7 @@ int nfs_creat_async(struct nfs_context *nfs, const char *path, int mode, nfs_cb ptr = strrchr(new_path, '/'); if (ptr == NULL) { rpc_set_error(nfs->rpc, "Invalid path %s", path); + free(new_path); return -1; } *ptr = 0; @@ -2169,7 +2386,7 @@ static void nfs_unlink_cb(struct rpc_context *rpc, int status, void *command_dat struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; char *str = data->continue_data; - + assert(rpc->magic == RPC_CONTEXT_MAGIC); str = &str[strlen(str) + 1]; @@ -2200,10 +2417,13 @@ static void nfs_unlink_cb(struct rpc_context *rpc, int status, void *command_dat static int nfs_unlink_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data) { char *str = data->continue_data; - + struct REMOVE3args args; + str = &str[strlen(str) + 1]; - if (rpc_nfs_remove_async(nfs->rpc, nfs_unlink_cb, &data->fh, str, data) != 0) { + args.object.dir = data->fh; + args.object.name = str; + if (rpc_nfs3_remove_async(nfs->rpc, nfs_unlink_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send REMOVE call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -2264,7 +2484,7 @@ static void nfs_mknod_cb(struct rpc_context *rpc, int status, void *command_data struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; char *str = data->continue_data; - + assert(rpc->magic == RPC_CONTEXT_MAGIC); str = &str[strlen(str) + 1]; @@ -2296,10 +2516,44 @@ static int nfs_mknod_continue_internal(struct nfs_context *nfs, struct nfs_cb_da { struct mknod_cb_data *cb_data = data->continue_data; char *str = cb_data->path; - + MKNOD3args args; + str = &str[strlen(str) + 1]; - if (rpc_nfs_mknod_async(nfs->rpc, nfs_mknod_cb, &data->fh, str, cb_data->mode, cb_data->major, cb_data->minor, data) != 0) { + args.where.dir = data->fh; + args.where.name = str; + switch (cb_data->mode & S_IFMT) { + case S_IFCHR: + args.what.type = NF3CHR; + args.what.mknoddata3_u.chr_device.dev_attributes.mode.set_it = 1; + args.what.mknoddata3_u.chr_device.dev_attributes.mode.set_mode3_u.mode = cb_data->mode & (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH); + args.what.mknoddata3_u.chr_device.spec.specdata1 = cb_data->major; + args.what.mknoddata3_u.chr_device.spec.specdata2 = cb_data->minor; + break; + case S_IFBLK: + args.what.type = NF3BLK; + args.what.mknoddata3_u.blk_device.dev_attributes.mode.set_it = 1; + args.what.mknoddata3_u.blk_device.dev_attributes.mode.set_mode3_u.mode = cb_data->mode & (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH); + args.what.mknoddata3_u.blk_device.spec.specdata1 = cb_data->major; + args.what.mknoddata3_u.blk_device.spec.specdata2 = cb_data->minor; + case S_IFSOCK: + args.what.type = NF3SOCK; + args.what.mknoddata3_u.sock_attributes.mode.set_it = 1; + args.what.mknoddata3_u.sock_attributes.mode.set_mode3_u.mode = cb_data->mode & (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH); + break; + case S_IFIFO: + args.what.type = NF3FIFO; + args.what.mknoddata3_u.pipe_attributes.mode.set_it = 1; + args.what.mknoddata3_u.pipe_attributes.mode.set_mode3_u.mode = cb_data->mode & (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH); + break; + default: + rpc_set_error(nfs->rpc, "Invalid file type for NFS3/MKNOD call"); + data->cb(-EINVAL, nfs, rpc_get_error(nfs->rpc), data->private_data); + free_nfs_cb_data(data); + return -1; + } + + if (rpc_nfs3_mknod_async(nfs->rpc, nfs_mknod_cb, &args, data) != 0) { data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return -1; @@ -2321,13 +2575,14 @@ int nfs_mknod_async(struct nfs_context *nfs, const char *path, int mode, int dev cb_data->path = strdup(path); if (cb_data->path == NULL) { rpc_set_error(nfs->rpc, "Out of memory, failed to allocate mode buffer for path"); - free(cb_data); + free(cb_data); return -1; } ptr = strrchr(cb_data->path, '/'); if (ptr == NULL) { rpc_set_error(nfs->rpc, "Invalid path %s", path); + free_mknod_cb_data(cb_data); return -1; } *ptr = 0; @@ -2403,6 +2658,8 @@ static void nfs_opendir3_cb(struct rpc_context *rpc, int status, void *command_d nfsdirent->mtime.tv_usec = attributes->mtime.nseconds/1000; nfsdirent->ctime.tv_sec = attributes->ctime.seconds; nfsdirent->ctime.tv_usec = attributes->ctime.nseconds/1000; + nfsdirent->uid = attributes->uid; + nfsdirent->gid = attributes->gid; } } @@ -2428,9 +2685,9 @@ static void nfs_opendir2_cb(struct rpc_context *rpc, int status, void *command_d struct nfsdir *nfsdir = data->continue_data; struct nfsdirent *nfsdirent; struct entry3 *entry; - uint64_t cookie; + uint64_t cookie = 0; struct rdpe_cb_data *rdpe_cb_data; - + assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) { @@ -2487,7 +2744,14 @@ static void nfs_opendir2_cb(struct rpc_context *rpc, int status, void *command_d } if (res->READDIR3res_u.resok.reply.eof == 0) { - if (rpc_nfs_readdir_async(nfs->rpc, nfs_opendir2_cb, &data->fh, cookie, res->READDIR3res_u.resok.cookieverf, 8192, data) != 0) { + READDIR3args args; + + args.dir = data->fh; + args.cookie = cookie; + memcpy(&args.cookieverf, res->READDIR3res_u.resok.cookieverf, sizeof(cookieverf3)); + args.count = 8192; + + if (rpc_nfs3_readdir_async(nfs->rpc, nfs_opendir2_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send READDIR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); nfs_free_nfsdir(nfsdir); @@ -2514,9 +2778,8 @@ static void nfs_opendir2_cb(struct rpc_context *rpc, int status, void *command_d rdpe_lookup_cb_data->nfsdirent = nfsdirent; memset(&args, 0, sizeof(LOOKUP3args)); - args.what.dir.data.data_len = data->fh.data.data_len; - args.what.dir.data.data_val = data->fh.data.data_val; - args.what.name = nfsdirent->name; + args.what.dir = data->fh; + args.what.name = nfsdirent->name; if (rpc_nfs3_lookup_async(nfs->rpc, nfs_opendir3_cb, &args, rdpe_lookup_cb_data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send READDIR LOOKUP call"); @@ -2550,14 +2813,19 @@ static void nfs_opendir_cb(struct rpc_context *rpc, int status, void *command_da struct nfs_context *nfs = data->nfs; struct nfsdir *nfsdir = data->continue_data; struct entryplus3 *entry; - uint64_t cookie; - + uint64_t cookie = 0; + assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR || (status == RPC_STATUS_SUCCESS && res->status == NFS3ERR_NOTSUPP) ){ - cookieverf3 cv; + READDIR3args args; + + args.dir = data->fh; + args.cookie = cookie; + memset(&args.cookieverf, 0, sizeof(cookieverf3)); + args.count = 8192; - if (rpc_nfs_readdir_async(nfs->rpc, nfs_opendir2_cb, &data->fh, 0, (char *)&cv, 8192, data) != 0) { + if (rpc_nfs3_readdir_async(nfs->rpc, nfs_opendir2_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send READDIR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); nfs_free_nfsdir(nfsdir); @@ -2601,6 +2869,7 @@ static void nfs_opendir_cb(struct rpc_context *rpc, int status, void *command_da nfsdirent->name = strdup(entry->name); if (nfsdirent->name == NULL) { data->cb(-ENOMEM, nfs, "Failed to allocate dirent->name", data->private_data); + free(nfsdirent); nfs_free_nfsdir(nfsdir); data->continue_data = NULL; free_nfs_cb_data(data); @@ -2618,6 +2887,8 @@ static void nfs_opendir_cb(struct rpc_context *rpc, int status, void *command_da nfsdirent->mtime.tv_usec = entry->name_attributes.post_op_attr_u.attributes.mtime.nseconds/1000; nfsdirent->ctime.tv_sec = entry->name_attributes.post_op_attr_u.attributes.ctime.seconds; nfsdirent->ctime.tv_usec = entry->name_attributes.post_op_attr_u.attributes.ctime.nseconds/1000; + nfsdirent->uid = entry->name_attributes.post_op_attr_u.attributes.uid; + nfsdirent->gid = entry->name_attributes.post_op_attr_u.attributes.gid; } nfsdirent->next = nfsdir->entries; @@ -2628,7 +2899,15 @@ static void nfs_opendir_cb(struct rpc_context *rpc, int status, void *command_da } 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) { + READDIRPLUS3args args; + + args.dir = data->fh; + args.cookie = cookie; + memcpy(&args.cookieverf, res->READDIRPLUS3res_u.resok.cookieverf, sizeof(cookieverf3)); + args.dircount = 8192; + args.maxcount = 8192; + + if (rpc_nfs3_readdirplus_async(nfs->rpc, nfs_opendir_cb, &args, 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); @@ -2649,10 +2928,14 @@ static void nfs_opendir_cb(struct rpc_context *rpc, int status, void *command_da static int nfs_opendir_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data) { - cookieverf3 cv; + READDIRPLUS3args args; - memset(cv, 0, sizeof(cookieverf3)); - if (rpc_nfs_readdirplus_async(nfs->rpc, nfs_opendir_cb, &data->fh, 0, (char *)&cv, 8192, data) != 0) { + args.dir = data->fh; + args.cookie = 0; + memset(&args.cookieverf, 0, sizeof(cookieverf3)); + args.dircount = 8192; + args.maxcount = 8192; + if (rpc_nfs3_readdirplus_async(nfs->rpc, nfs_opendir_cb, &args, 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); @@ -2692,15 +2975,24 @@ struct nfsdirent *nfs_readdir(struct nfs_context *nfs _U_, struct nfsdir *nfsdir } +/* + * closedir() + */ void nfs_closedir(struct nfs_context *nfs _U_, struct nfsdir *nfsdir) { nfs_free_nfsdir(nfsdir); } - - - +/* + * getcwd() + */ +void nfs_getcwd(struct nfs_context *nfs, const char **cwd) +{ + if (cwd) { + *cwd = nfs->cwd; + } +} /* @@ -2775,8 +3067,7 @@ int nfs_lseek_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offse data->private_data = private_data; memset(&args, 0, sizeof(GETATTR3args)); - args.object.data.data_len = nfsfh->fh.data.data_len; - args.object.data.data_val = nfsfh->fh.data.data_val; + args.object = nfsfh->fh; if (rpc_nfs3_getattr_async(nfs->rpc, nfs_lseek_1_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send LSEEK GETATTR call"); @@ -2840,7 +3131,10 @@ static void nfs_statvfs_1_cb(struct rpc_context *rpc, int status, void *command_ static int nfs_statvfs_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data) { - if (rpc_nfs_fsstat_async(nfs->rpc, nfs_statvfs_1_cb, &data->fh, data) != 0) { + FSSTAT3args args; + + args.fsroot = data->fh; + if (rpc_nfs3_fsstat_async(nfs->rpc, nfs_statvfs_1_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send FSSTAT call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -2892,7 +3186,7 @@ static void nfs_readlink_1_cb(struct rpc_context *rpc, int status, void *command return; } - + data->cb(0, nfs, res->READLINK3res_u.resok.data, data->private_data); free_nfs_cb_data(data); } @@ -2901,10 +3195,9 @@ static int nfs_readlink_continue_internal(struct nfs_context *nfs, struct nfs_cb { READLINK3args args; - args.symlink.data.data_len = data->fh.data.data_len; - args.symlink.data.data_val = data->fh.data.data_val; + args.symlink = data->fh; - if (rpc_nfs_readlink_async(nfs->rpc, nfs_readlink_1_cb, &args, data) != 0) { + if (rpc_nfs3_readlink_async(nfs->rpc, nfs_readlink_1_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send READLINK call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -2965,12 +3258,11 @@ static int nfs_chmod_continue_internal(struct nfs_context *nfs, struct nfs_cb_da SETATTR3args args; memset(&args, 0, sizeof(SETATTR3args)); - args.object.data.data_len = data->fh.data.data_len; - args.object.data.data_val = data->fh.data.data_val; + args.object = data->fh; args.new_attributes.mode.set_it = 1; args.new_attributes.mode.set_mode3_u.mode = data->continue_int; - if (rpc_nfs_setattr_async(nfs->rpc, nfs_chmod_cb, &args, data) != 0) { + if (rpc_nfs3_setattr_async(nfs->rpc, nfs_chmod_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send SETATTR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -3071,8 +3363,7 @@ static int nfs_chown_continue_internal(struct nfs_context *nfs, struct nfs_cb_da struct nfs_chown_data *chown_data = data->continue_data; memset(&args, 0, sizeof(SETATTR3args)); - args.object.data.data_len = data->fh.data.data_len; - args.object.data.data_val = data->fh.data.data_val; + args.object = data->fh; if (chown_data->uid != (uid_t)-1) { args.new_attributes.uid.set_it = 1; args.new_attributes.uid.set_uid3_u.uid = chown_data->uid; @@ -3082,7 +3373,7 @@ static int nfs_chown_continue_internal(struct nfs_context *nfs, struct nfs_cb_da args.new_attributes.gid.set_gid3_u.gid = chown_data->gid; } - if (rpc_nfs_setattr_async(nfs->rpc, nfs_chown_cb, &args, data) != 0) { + if (rpc_nfs3_setattr_async(nfs->rpc, nfs_chown_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send SETATTR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -3131,10 +3422,10 @@ int nfs_fchown_async(struct nfs_context *nfs, struct nfsfh *nfsfh, int uid, int chown_data->uid = uid; chown_data->gid = gid; - data = malloc(sizeof(struct nfs_cb_data)); if (data == NULL) { rpc_set_error(nfs->rpc, "out of memory. failed to allocate memory for fchown data"); + free(chown_data); return -1; } memset(data, 0, sizeof(struct nfs_cb_data)); @@ -3142,6 +3433,7 @@ int nfs_fchown_async(struct nfs_context *nfs, struct nfsfh *nfsfh, int uid, int data->cb = cb; data->private_data = private_data; data->continue_data = chown_data; + data->free_continue_data = free; data->fh.data.data_len = nfsfh->fh.data.data_len; data->fh.data.data_val = malloc(data->fh.data.data_len); if (data->fh.data.data_val == NULL) { @@ -3151,7 +3443,6 @@ 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) { free_nfs_cb_data(data); return -1; @@ -3204,8 +3495,7 @@ static int nfs_utimes_continue_internal(struct nfs_context *nfs, struct nfs_cb_d struct timeval *utimes_data = data->continue_data; memset(&args, 0, sizeof(SETATTR3args)); - args.object.data.data_len = data->fh.data.data_len; - args.object.data.data_val = data->fh.data.data_val; + args.object = data->fh; if (utimes_data != NULL) { args.new_attributes.atime.set_it = SET_TO_CLIENT_TIME; args.new_attributes.atime.set_atime_u.atime.seconds = utimes_data[0].tv_sec; @@ -3218,7 +3508,7 @@ static int nfs_utimes_continue_internal(struct nfs_context *nfs, struct nfs_cb_d args.new_attributes.mtime.set_it = SET_TO_SERVER_TIME; } - if (rpc_nfs_setattr_async(nfs->rpc, nfs_utimes_cb, &args, data) != 0) { + if (rpc_nfs3_setattr_async(nfs->rpc, nfs_utimes_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send SETATTR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -3353,8 +3643,7 @@ static int nfs_access_continue_internal(struct nfs_context *nfs, struct nfs_cb_d } memset(&args, 0, sizeof(ACCESS3args)); - args.object.data.data_len = data->fh.data.data_len; - args.object.data.data_val = data->fh.data.data_val; + args.object = data->fh; args.access = nfsmode; if (rpc_nfs3_access_async(nfs->rpc, nfs_access_cb, &args, data) != 0) { @@ -3409,7 +3698,7 @@ static void nfs_symlink_cb(struct rpc_context *rpc, int status, void *command_da struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; struct nfs_symlink_data *symlink_data = data->continue_data; - + assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) { @@ -3438,17 +3727,16 @@ static void nfs_symlink_cb(struct rpc_context *rpc, int status, void *command_da static int nfs_symlink_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data) { struct nfs_symlink_data *symlink_data = data->continue_data; - SYMLINK3args sa; + SYMLINK3args args; - memset(&sa, 0, sizeof(SYMLINK3args)); - sa.where.dir.data.data_len = data->fh.data.data_len; - sa.where.dir.data.data_val = data->fh.data.data_val; - sa.where.name = symlink_data->newpathobject; - sa.symlink.symlink_attributes.mode.set_it = 1; - sa.symlink.symlink_attributes.mode.set_mode3_u.mode = S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH; - sa.symlink.symlink_data = symlink_data->oldpath; + memset(&args, 0, sizeof(SYMLINK3args)); + args.where.dir = data->fh; + args.where.name = symlink_data->newpathobject; + args.symlink.symlink_attributes.mode.set_it = 1; + args.symlink.symlink_attributes.mode.set_mode3_u.mode = S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH; + args.symlink.symlink_data = symlink_data->oldpath; - if (rpc_nfs_symlink_async(nfs->rpc, nfs_symlink_cb, &sa, data) != 0) { + if (rpc_nfs3_symlink_async(nfs->rpc, nfs_symlink_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send SYMLINK call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -3546,7 +3834,7 @@ static void nfs_rename_cb(struct rpc_context *rpc, int status, void *command_dat struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; struct nfs_rename_data *rename_data = data->continue_data; - + assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) { @@ -3575,13 +3863,17 @@ static void nfs_rename_cb(struct rpc_context *rpc, int status, void *command_dat static int nfs_rename_continue_2_internal(struct nfs_context *nfs, struct nfs_cb_data *data) { struct nfs_rename_data *rename_data = data->continue_data; + RENAME3args args; /* steal the filehandle */ - rename_data->newdir.data.data_len = data->fh.data.data_len; - rename_data->newdir.data.data_val = data->fh.data.data_val; + rename_data->newdir = data->fh; data->fh.data.data_val = NULL; - if (rpc_nfs_rename_async(nfs->rpc, nfs_rename_cb, &rename_data->olddir, rename_data->oldobject, &rename_data->newdir, rename_data->newobject, data) != 0) { + args.from.dir = rename_data->olddir; + args.from.name = rename_data->oldobject; + args.to.dir = rename_data->newdir; + args.to.name = rename_data->newobject; + if (rpc_nfs3_rename_async(nfs->rpc, nfs_rename_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send RENAME call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -3596,8 +3888,7 @@ static int nfs_rename_continue_1_internal(struct nfs_context *nfs, struct nfs_cb struct nfs_rename_data *rename_data = data->continue_data; /* steal the filehandle */ - rename_data->olddir.data.data_len = data->fh.data.data_len; - rename_data->olddir.data.data_val = data->fh.data.data_val; + rename_data->olddir = data->fh; data->fh.data.data_val = NULL; if (nfs_lookuppath_async(nfs, rename_data->newpath, data->cb, data->private_data, nfs_rename_continue_2_internal, rename_data, free_nfs_rename_data, 0) != 0) { @@ -3704,7 +3995,7 @@ static void nfs_link_cb(struct rpc_context *rpc, int status, void *command_data, struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; struct nfs_link_data *link_data = data->continue_data; - + assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) { @@ -3733,13 +4024,17 @@ static void nfs_link_cb(struct rpc_context *rpc, int status, void *command_data, static int nfs_link_continue_2_internal(struct nfs_context *nfs, struct nfs_cb_data *data) { struct nfs_link_data *link_data = data->continue_data; + LINK3args args; /* steal the filehandle */ - link_data->newdir.data.data_len = data->fh.data.data_len; - link_data->newdir.data.data_val = data->fh.data.data_val; + link_data->newdir = data->fh; data->fh.data.data_val = NULL; - if (rpc_nfs_link_async(nfs->rpc, nfs_link_cb, &link_data->oldfh, &link_data->newdir, link_data->newobject, data) != 0) { + memset(&args, 0, sizeof(LINK3args)); + args.file = link_data->oldfh; + args.link.dir = link_data->newdir; + args.link.name = link_data->newobject; + if (rpc_nfs3_link_async(nfs->rpc, nfs_link_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send LINK call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -3754,8 +4049,7 @@ static int nfs_link_continue_1_internal(struct nfs_context *nfs, struct nfs_cb_d struct nfs_link_data *link_data = data->continue_data; /* steal the filehandle */ - link_data->oldfh.data.data_len = data->fh.data.data_len; - link_data->oldfh.data.data_val = data->fh.data.data_val; + link_data->oldfh = data->fh; data->fh.data.data_val = NULL; if (nfs_lookuppath_async(nfs, link_data->newpath, data->cb, data->private_data, nfs_link_continue_2_internal, link_data, free_nfs_link_data, 0) != 0) { @@ -3840,6 +4134,18 @@ uint64_t nfs_get_writemax(struct nfs_context *nfs) return nfs->writemax; } +void nfs_set_tcp_syncnt(struct nfs_context *nfs, int v) { + rpc_set_tcp_syncnt(nfs->rpc, v); +} + +void nfs_set_uid(struct nfs_context *nfs, int uid) { + rpc_set_uid(nfs->rpc, uid); +} + +void nfs_set_gid(struct nfs_context *nfs, int gid) { + rpc_set_gid(nfs->rpc, gid); +} + void nfs_set_error(struct nfs_context *nfs, char *error_string, ...) { va_list ap; @@ -3852,7 +4158,7 @@ void nfs_set_error(struct nfs_context *nfs, char *error_string, ...) free(nfs->rpc->error_string); } nfs->rpc->error_string = str; - va_end(ap); + va_end(ap); } @@ -3906,7 +4212,7 @@ static void mount_export_4_cb(struct rpc_context *rpc, int status, void *command /* Dont want any more callbacks even if the socket is closed */ rpc->connect_cb = NULL; - if (status == RPC_STATUS_ERROR) { + if (status == RPC_STATUS_ERROR) { data->cb(rpc, -EFAULT, command_data, data->private_data); free_mount_cb_data(data); return; @@ -3917,7 +4223,7 @@ static void mount_export_4_cb(struct rpc_context *rpc, int status, void *command return; } - if (rpc_mount_export_async(rpc, mount_export_5_cb, data) != 0) { + if (rpc_mount3_export_async(rpc, mount_export_5_cb, data) != 0) { data->cb(rpc, -ENOMEM, command_data, data->private_data); free_mount_cb_data(data); return; @@ -4026,7 +4332,7 @@ int mount_getexports_async(struct rpc_context *rpc, const char *server, rpc_cb c if (data->server == NULL) { free_mount_cb_data(data); return -1; - } + } if (rpc_connect_async(rpc, data->server, 111, mount_export_1_cb, data) != 0) { free_mount_cb_data(data); return -1;