Add nfs_statvfs64()
Add a new function nfs_statvfs64() that returns a struct nfs_statvfs_64 where all fields are uint64_t. Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>libnfs-4.0.0-vitalif
parent
d21b48256e
commit
48a559cb47
|
@ -463,6 +463,8 @@ int nfs3_stat64_async(struct nfs_context *nfs, const char *path,
|
|||
int no_follow, nfs_cb cb, void *private_data);
|
||||
int nfs3_statvfs_async(struct nfs_context *nfs, const char *path, nfs_cb cb,
|
||||
void *private_data);
|
||||
int nfs3_statvfs64_async(struct nfs_context *nfs, const char *path, nfs_cb cb,
|
||||
void *private_data);
|
||||
int nfs3_symlink_async(struct nfs_context *nfs, const char *oldpath,
|
||||
const char *newpath, nfs_cb cb, void *private_data);
|
||||
int nfs3_truncate_async(struct nfs_context *nfs, const char *path,
|
||||
|
@ -540,6 +542,8 @@ int nfs4_stat64_async(struct nfs_context *nfs, const char *path,
|
|||
int no_follow, nfs_cb cb, void *private_data);
|
||||
int nfs4_statvfs_async(struct nfs_context *nfs, const char *path, nfs_cb cb,
|
||||
void *private_data);
|
||||
int nfs4_statvfs64_async(struct nfs_context *nfs, const char *path, nfs_cb cb,
|
||||
void *private_data);
|
||||
int nfs4_symlink_async(struct nfs_context *nfs, const char *oldpath,
|
||||
const char *newpath, nfs_cb cb, void *private_data);
|
||||
int nfs4_truncate_async(struct nfs_context *nfs, const char *path,
|
||||
|
|
|
@ -1292,8 +1292,23 @@ EXTERN void nfs_getcwd(struct nfs_context *nfs, const char **cwd);
|
|||
/*
|
||||
* STATVFS()
|
||||
*/
|
||||
struct nfs_statvfs_64 {
|
||||
uint64_t f_bsize;
|
||||
uint64_t f_frsize;
|
||||
uint64_t f_blocks;
|
||||
uint64_t f_bfree;
|
||||
uint64_t f_bavail;
|
||||
uint64_t f_files;
|
||||
uint64_t f_ffree;
|
||||
uint64_t f_favail;
|
||||
uint64_t f_fsid;
|
||||
uint64_t f_flag;
|
||||
uint64_t f_namemax;
|
||||
};
|
||||
/*
|
||||
* Async statvfs(<dirname>)
|
||||
* This function is deprecated. Use nfs_statvfs64_async() instead.
|
||||
*
|
||||
* Function returns
|
||||
* 0 : The command was queued successfully. The callback will be invoked once
|
||||
* the command completes.
|
||||
|
@ -1311,13 +1326,40 @@ EXTERN int nfs_statvfs_async(struct nfs_context *nfs, const char *path,
|
|||
nfs_cb cb, void *private_data);
|
||||
/*
|
||||
* Sync statvfs(<dirname>)
|
||||
* This function is deprecated. Use nfs_statvfs64() instead.
|
||||
*
|
||||
* Function returns
|
||||
* 0 : The operation was successful.
|
||||
* -errno : The command failed.
|
||||
*/
|
||||
EXTERN int nfs_statvfs(struct nfs_context *nfs, const char *path,
|
||||
struct statvfs *svfs);
|
||||
|
||||
/*
|
||||
* Async statvfs64(<dirname>)
|
||||
*
|
||||
* Function returns
|
||||
* 0 : The command was queued successfully. The callback will be invoked once
|
||||
* the command completes.
|
||||
* <0 : An error occured when trying to queue the command.
|
||||
* The callback will not be invoked.
|
||||
*
|
||||
* When the callback is invoked, status indicates the result:
|
||||
* 0 : Success.
|
||||
* data is struct nfs_statvfs_64 *
|
||||
* -errno : An error occured.
|
||||
* data is the error string.
|
||||
*/
|
||||
EXTERN int nfs_statvfs64_async(struct nfs_context *nfs, const char *path,
|
||||
nfs_cb cb, void *private_data);
|
||||
/*
|
||||
* Sync statvfs64(<dirname>)
|
||||
*
|
||||
* Function returns
|
||||
* 0 : The operation was successful.
|
||||
* -errno : The command failed.
|
||||
*/
|
||||
EXTERN int nfs_statvfs64(struct nfs_context *nfs, const char *path,
|
||||
struct nfs_statvfs_64 *svfs);
|
||||
|
||||
/*
|
||||
* READLINK()
|
||||
|
@ -1338,7 +1380,6 @@ EXTERN int nfs_statvfs(struct nfs_context *nfs, const char *path,
|
|||
* -errno : An error occured.
|
||||
* data is the error string.
|
||||
*/
|
||||
struct statvfs;
|
||||
EXTERN int nfs_readlink_async(struct nfs_context *nfs, const char *path,
|
||||
nfs_cb cb, void *private_data);
|
||||
/*
|
||||
|
|
|
@ -1166,6 +1166,46 @@ nfs_statvfs(struct nfs_context *nfs, const char *path, struct statvfs *svfs)
|
|||
return cb_data.status;
|
||||
}
|
||||
|
||||
/*
|
||||
* statvfs64()
|
||||
*/
|
||||
static void
|
||||
statvfs64_cb(int status, struct nfs_context *nfs, void *data,
|
||||
void *private_data)
|
||||
{
|
||||
struct sync_cb_data *cb_data = private_data;
|
||||
|
||||
cb_data->is_finished = 1;
|
||||
cb_data->status = status;
|
||||
|
||||
if (status < 0) {
|
||||
nfs_set_error(nfs, "statvfs64 call failed with \"%s\"",
|
||||
(char *)data);
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(cb_data->return_data, data, sizeof(struct nfs_statvfs_64));
|
||||
}
|
||||
|
||||
int
|
||||
nfs_statvfs64(struct nfs_context *nfs, const char *path,
|
||||
struct nfs_statvfs_64 *svfs)
|
||||
{
|
||||
struct sync_cb_data cb_data;
|
||||
|
||||
cb_data.is_finished = 0;
|
||||
cb_data.return_data = svfs;
|
||||
|
||||
if (nfs_statvfs64_async(nfs, path, statvfs64_cb, &cb_data) != 0) {
|
||||
nfs_set_error(nfs, "nfs_statvfs64_async failed. %s",
|
||||
nfs_get_error(nfs));
|
||||
return -1;
|
||||
}
|
||||
|
||||
wait_for_nfs_reply(nfs, &cb_data);
|
||||
|
||||
return cb_data.status;
|
||||
}
|
||||
|
||||
/*
|
||||
* readlink()
|
||||
|
|
|
@ -95,6 +95,8 @@ nfs_stat64
|
|||
nfs_stat64_async
|
||||
nfs_statvfs
|
||||
nfs_statvfs_async
|
||||
nfs_statvfs64
|
||||
nfs_statvfs64_async
|
||||
nfs_symlink
|
||||
nfs_symlink_async
|
||||
nfs_truncate
|
||||
|
|
16
lib/libnfs.c
16
lib/libnfs.c
|
@ -1471,6 +1471,22 @@ nfs_statvfs_async(struct nfs_context *nfs, const char *path, nfs_cb cb,
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
nfs_statvfs64_async(struct nfs_context *nfs, const char *path, nfs_cb cb,
|
||||
void *private_data)
|
||||
{
|
||||
switch (nfs->version) {
|
||||
case NFS_V3:
|
||||
return nfs3_statvfs64_async(nfs, path, cb, private_data);
|
||||
case NFS_V4:
|
||||
return nfs4_statvfs64_async(nfs, path, cb, private_data);
|
||||
default:
|
||||
nfs_set_error(nfs, "%s does not support NFSv%d",
|
||||
__FUNCTION__, nfs->version);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
nfs_readlink_async(struct nfs_context *nfs, const char *path, nfs_cb cb,
|
||||
void *private_data)
|
||||
|
|
56
lib/nfs_v3.c
56
lib/nfs_v3.c
|
@ -2272,6 +2272,7 @@ nfs3_statvfs_1_cb(struct rpc_context *rpc, int status, void *command_data,
|
|||
struct nfs_cb_data *data = private_data;
|
||||
struct nfs_context *nfs = data->nfs;
|
||||
struct statvfs svfs;
|
||||
struct nfs_statvfs_64 svfs64;
|
||||
|
||||
assert(rpc->magic == RPC_CONTEXT_MAGIC);
|
||||
|
||||
|
@ -2292,21 +2293,39 @@ nfs3_statvfs_1_cb(struct rpc_context *rpc, int status, void *command_data,
|
|||
return;
|
||||
}
|
||||
|
||||
svfs.f_bsize = NFS_BLKSIZE;
|
||||
svfs.f_frsize = NFS_BLKSIZE;
|
||||
svfs.f_blocks = res->FSSTAT3res_u.resok.tbytes/NFS_BLKSIZE;
|
||||
svfs.f_bfree = res->FSSTAT3res_u.resok.fbytes/NFS_BLKSIZE;
|
||||
svfs.f_bavail = res->FSSTAT3res_u.resok.abytes/NFS_BLKSIZE;
|
||||
svfs.f_files = (uint32_t)res->FSSTAT3res_u.resok.tfiles;
|
||||
svfs.f_ffree = (uint32_t)res->FSSTAT3res_u.resok.ffiles;
|
||||
if (data->continue_int == 0) {
|
||||
/* statvfs */
|
||||
svfs.f_bsize = NFS_BLKSIZE;
|
||||
svfs.f_frsize = NFS_BLKSIZE;
|
||||
svfs.f_blocks = res->FSSTAT3res_u.resok.tbytes/NFS_BLKSIZE;
|
||||
svfs.f_bfree = res->FSSTAT3res_u.resok.fbytes/NFS_BLKSIZE;
|
||||
svfs.f_bavail = res->FSSTAT3res_u.resok.abytes/NFS_BLKSIZE;
|
||||
svfs.f_files = (uint32_t)res->FSSTAT3res_u.resok.tfiles;
|
||||
svfs.f_ffree = (uint32_t)res->FSSTAT3res_u.resok.ffiles;
|
||||
#if !defined(__ANDROID__)
|
||||
svfs.f_favail = (uint32_t)res->FSSTAT3res_u.resok.afiles;
|
||||
svfs.f_fsid = 0;
|
||||
svfs.f_flag = 0;
|
||||
svfs.f_namemax = 256;
|
||||
svfs.f_favail = (uint32_t)res->FSSTAT3res_u.resok.afiles;
|
||||
svfs.f_fsid = 0;
|
||||
svfs.f_flag = 0;
|
||||
svfs.f_namemax = 256;
|
||||
#endif
|
||||
data->cb(0, nfs, &svfs, data->private_data);
|
||||
} else {
|
||||
/* statvfs64 */
|
||||
svfs64.f_bsize = NFS_BLKSIZE;
|
||||
svfs64.f_frsize = NFS_BLKSIZE;
|
||||
svfs64.f_blocks = res->FSSTAT3res_u.resok.tbytes/NFS_BLKSIZE;
|
||||
svfs64.f_bfree = res->FSSTAT3res_u.resok.fbytes/NFS_BLKSIZE;
|
||||
svfs64.f_bavail = res->FSSTAT3res_u.resok.abytes/NFS_BLKSIZE;
|
||||
svfs64.f_files = res->FSSTAT3res_u.resok.tfiles;
|
||||
svfs64.f_ffree = res->FSSTAT3res_u.resok.ffiles;
|
||||
svfs64.f_favail = res->FSSTAT3res_u.resok.afiles;
|
||||
svfs64.f_fsid = 0;
|
||||
svfs64.f_flag = 0;
|
||||
svfs64.f_namemax = 256;
|
||||
|
||||
data->cb(0, nfs, &svfs64, data->private_data);
|
||||
}
|
||||
|
||||
data->cb(0, nfs, &svfs, data->private_data);
|
||||
free_nfs_cb_data(data);
|
||||
}
|
||||
|
||||
|
@ -2344,6 +2363,19 @@ nfs3_statvfs_async(struct nfs_context *nfs, const char *path, nfs_cb cb,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
nfs3_statvfs64_async(struct nfs_context *nfs, const char *path, nfs_cb cb,
|
||||
void *private_data)
|
||||
{
|
||||
if (nfs3_lookuppath_async(nfs, path, 0, cb, private_data,
|
||||
nfs3_statvfs_continue_internal,
|
||||
NULL, NULL, 1) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
nfs3_lseek_1_cb(struct rpc_context *rpc, int status, void *command_data,
|
||||
void *private_data)
|
||||
|
|
132
lib/nfs_v4.c
132
lib/nfs_v4.c
|
@ -141,7 +141,8 @@ struct nfs4_cb_data {
|
|||
/* Do not follow symlinks for the final component on a lookup.
|
||||
* I.e. stat vs lstat
|
||||
*/
|
||||
#define LOOKUP_FLAG_NO_FOLLOW 0x0001
|
||||
#define LOOKUP_FLAG_NO_FOLLOW 0x0001
|
||||
#define LOOKUP_FLAG_IS_STATVFS64 0x0002
|
||||
int flags;
|
||||
|
||||
/* Internal callback for open-with-continuation use */
|
||||
|
@ -4389,6 +4390,83 @@ nfs_parse_statvfs(struct nfs_context *nfs, struct nfs4_cb_data *data,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
nfs_parse_statvfs64(struct nfs_context *nfs, struct nfs4_cb_data *data,
|
||||
struct nfs_statvfs_64 *svfs64, const char *buf, int len)
|
||||
{
|
||||
uint64_t u64;
|
||||
uint32_t u32;
|
||||
|
||||
svfs64->f_bsize = NFS_BLKSIZE;
|
||||
svfs64->f_frsize = NFS_BLKSIZE;
|
||||
svfs64->f_flag = 0;
|
||||
|
||||
/* FSID
|
||||
* NFSv4 FSID is 2*64 bit but statvfs fsid is just an
|
||||
* unsigmed long. Mix the 2*64 bits and hope for the best.
|
||||
*/
|
||||
CHECK_GETATTR_BUF_SPACE(len, 16);
|
||||
memcpy(&u64, buf, 8);
|
||||
svfs64->f_fsid = nfs_ntoh64(u64);
|
||||
buf += 8;
|
||||
len -= 8;
|
||||
memcpy(&u64, buf, 8);
|
||||
svfs64->f_fsid |= nfs_ntoh64(u64);
|
||||
buf += 8;
|
||||
len -= 8;
|
||||
|
||||
/* Files Avail */
|
||||
CHECK_GETATTR_BUF_SPACE(len, 8);
|
||||
memcpy(&u64, buf, 8);
|
||||
svfs64->f_favail = nfs_ntoh64(u64);
|
||||
buf += 8;
|
||||
len -= 8;
|
||||
|
||||
/* Files Free */
|
||||
CHECK_GETATTR_BUF_SPACE(len, 8);
|
||||
memcpy(&u64, buf, 8);
|
||||
svfs64->f_ffree = nfs_ntoh64(u64);
|
||||
buf += 8;
|
||||
len -= 8;
|
||||
|
||||
/* Files Total */
|
||||
CHECK_GETATTR_BUF_SPACE(len, 8);
|
||||
memcpy(&u64, buf, 8);
|
||||
svfs64->f_files = nfs_ntoh64(u64);
|
||||
buf += 8;
|
||||
len -= 8;
|
||||
|
||||
/* Max Name */
|
||||
CHECK_GETATTR_BUF_SPACE(len, 4);
|
||||
memcpy(&u32, buf, 4);
|
||||
svfs64->f_namemax = ntohl(u32);
|
||||
buf += 4;
|
||||
len -= 4;
|
||||
|
||||
/* Space Avail */
|
||||
CHECK_GETATTR_BUF_SPACE(len, 8);
|
||||
memcpy(&u64, buf, 8);
|
||||
svfs64->f_bavail = nfs_ntoh64(u64) / svfs64->f_frsize;
|
||||
buf += 8;
|
||||
len -= 8;
|
||||
|
||||
/* Space Free */
|
||||
CHECK_GETATTR_BUF_SPACE(len, 8);
|
||||
memcpy(&u64, buf, 8);
|
||||
svfs64->f_bfree = nfs_ntoh64(u64) / svfs64->f_frsize;
|
||||
buf += 8;
|
||||
len -= 8;
|
||||
|
||||
/* Space Total */
|
||||
CHECK_GETATTR_BUF_SPACE(len, 8);
|
||||
memcpy(&u64, buf, 8);
|
||||
svfs64->f_blocks = nfs_ntoh64(u64) / svfs64->f_frsize;
|
||||
buf += 8;
|
||||
len -= 8;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
nfs4_statvfs_cb(struct rpc_context *rpc, int status, void *command_data,
|
||||
void *private_data)
|
||||
|
@ -4398,6 +4476,7 @@ nfs4_statvfs_cb(struct rpc_context *rpc, int status, void *command_data,
|
|||
COMPOUND4res *res = command_data;
|
||||
GETATTR4resok *garesok;
|
||||
struct statvfs svfs;
|
||||
struct nfs_statvfs_64 svfs64;
|
||||
int i;
|
||||
|
||||
assert(rpc->magic == RPC_CONTEXT_MAGIC);
|
||||
|
@ -4413,21 +4492,37 @@ nfs4_statvfs_cb(struct rpc_context *rpc, int status, void *command_data,
|
|||
}
|
||||
garesok = &res->resarray.resarray_val[i].nfs_resop4_u.opgetattr.GETATTR4res_u.resok4;
|
||||
|
||||
if (nfs_parse_statvfs(nfs, data, &svfs,
|
||||
if (data->flags & LOOKUP_FLAG_IS_STATVFS64) {
|
||||
/* statvfs64 */
|
||||
if (nfs_parse_statvfs64(nfs, data, &svfs64,
|
||||
garesok->obj_attributes.attr_vals.attrlist4_val,
|
||||
garesok->obj_attributes.attr_vals.attrlist4_len) < 0) {
|
||||
data->cb(-EINVAL, nfs, nfs_get_error(nfs), data->private_data);
|
||||
free_nfs4_cb_data(data);
|
||||
return;
|
||||
data->cb(-EINVAL, nfs, nfs_get_error(nfs), data->private_data);
|
||||
free_nfs4_cb_data(data);
|
||||
return;
|
||||
}
|
||||
|
||||
data->cb(0, nfs, &svfs64, data->private_data);
|
||||
} else {
|
||||
/* statvfs */
|
||||
if (nfs_parse_statvfs(nfs, data, &svfs,
|
||||
garesok->obj_attributes.attr_vals.attrlist4_val,
|
||||
garesok->obj_attributes.attr_vals.attrlist4_len) < 0) {
|
||||
data->cb(-EINVAL, nfs, nfs_get_error(nfs), data->private_data);
|
||||
free_nfs4_cb_data(data);
|
||||
return;
|
||||
}
|
||||
|
||||
data->cb(0, nfs, &svfs, data->private_data);
|
||||
}
|
||||
|
||||
data->cb(0, nfs, &svfs, data->private_data);
|
||||
free_nfs4_cb_data(data);
|
||||
}
|
||||
|
||||
int
|
||||
nfs4_statvfs_async(struct nfs_context *nfs, const char *path, nfs_cb cb,
|
||||
void *private_data)
|
||||
static int
|
||||
nfs4_statvfs_async_internal(struct nfs_context *nfs, const char *path,
|
||||
int is_statvfs64,
|
||||
nfs_cb cb, void *private_data)
|
||||
{
|
||||
struct nfs4_cb_data *data;
|
||||
COMPOUND4args args;
|
||||
|
@ -4445,6 +4540,9 @@ nfs4_statvfs_async(struct nfs_context *nfs, const char *path, nfs_cb cb,
|
|||
data->nfs = nfs;
|
||||
data->cb = cb;
|
||||
data->private_data = private_data;
|
||||
if (is_statvfs64) {
|
||||
data->flags |= LOOKUP_FLAG_IS_STATVFS64;
|
||||
}
|
||||
|
||||
fh.fh.len = nfs->rootfh.len;
|
||||
fh.fh.val = nfs->rootfh.val;
|
||||
|
@ -4465,6 +4563,22 @@ nfs4_statvfs_async(struct nfs_context *nfs, const char *path, nfs_cb cb,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
nfs4_statvfs_async(struct nfs_context *nfs, const char *path, nfs_cb cb,
|
||||
void *private_data)
|
||||
{
|
||||
return nfs4_statvfs_async_internal(nfs, path, 0,
|
||||
cb, private_data);
|
||||
}
|
||||
|
||||
int
|
||||
nfs4_statvfs64_async(struct nfs_context *nfs, const char *path, nfs_cb cb,
|
||||
void *private_data)
|
||||
{
|
||||
return nfs4_statvfs_async_internal(nfs, path, 1,
|
||||
cb, private_data);
|
||||
}
|
||||
|
||||
static void
|
||||
nfs4_chmod_open_cb(struct rpc_context *rpc, int status, void *command_data,
|
||||
void *private_data)
|
||||
|
|
|
@ -40,7 +40,7 @@ int main(int argc, char *argv[])
|
|||
{
|
||||
struct nfs_context *nfs = NULL;
|
||||
struct nfs_url *url = NULL;
|
||||
struct statvfs svfs;
|
||||
struct nfs_statvfs_64 svfs;
|
||||
int ret = 0;
|
||||
|
||||
if (argc != 4) {
|
||||
|
@ -75,23 +75,23 @@ int main(int argc, char *argv[])
|
|||
goto finished;
|
||||
}
|
||||
|
||||
if (nfs_statvfs(nfs, argv[3], &svfs)) {
|
||||
fprintf(stderr, "statvfs failed : %s\n",
|
||||
if (nfs_statvfs64(nfs, argv[3], &svfs)) {
|
||||
fprintf(stderr, "statvfs64 failed : %s\n",
|
||||
nfs_get_error(nfs));
|
||||
ret = 1;
|
||||
goto finished;
|
||||
}
|
||||
|
||||
printf("bsize:%lu\n", svfs.f_bsize);
|
||||
printf("frsize:%lu\n", svfs.f_frsize);
|
||||
printf("blocks:%lu\n", svfs.f_blocks);
|
||||
printf("bfree:%lu\n", svfs.f_bfree);
|
||||
printf("bavail:%lu\n", svfs.f_bavail);
|
||||
printf("files:%lu\n", svfs.f_files);
|
||||
printf("ffree:%lu\n", svfs.f_ffree);
|
||||
printf("favail:%lu\n", svfs.f_favail);
|
||||
printf("fsid:%lu\n", svfs.f_fsid);
|
||||
printf("namemax:%lu\n", svfs.f_namemax);
|
||||
printf("bsize:%" PRIu64 "\n", svfs.f_bsize);
|
||||
printf("frsize:%" PRIu64 "\n", svfs.f_frsize);
|
||||
printf("blocks:%" PRIu64 "\n", svfs.f_blocks);
|
||||
printf("bfree:%" PRIu64 "\n", svfs.f_bfree);
|
||||
printf("bavail:%" PRIu64 "\n", svfs.f_bavail);
|
||||
printf("files:%" PRIu64 "\n", svfs.f_files);
|
||||
printf("ffree:%" PRIu64 "\n", svfs.f_ffree);
|
||||
printf("favail:%" PRIu64 "\n", svfs.f_favail);
|
||||
printf("fsid:%" PRIu64 "\n", svfs.f_fsid);
|
||||
printf("namemax:%" PRIu64 "\n", svfs.f_namemax);
|
||||
|
||||
finished:
|
||||
nfs_destroy_url(url);
|
||||
|
|
Loading…
Reference in New Issue