Rework dirents buffer management

This commit is contained in:
Antonio SJ Musumeci 2021-09-18 22:22:47 -04:00
parent 6b5c484fbf
commit 4ea0de3ef2
6 changed files with 46 additions and 145 deletions

View File

@ -25,7 +25,6 @@
#include "extern_c.h" #include "extern_c.h"
#include "fuse_common.h" #include "fuse_common.h"
#include "fuse_dirents.h"
#include <fcntl.h> #include <fcntl.h>
#include <time.h> #include <time.h>
@ -47,6 +46,9 @@ struct fuse;
/** Structure containing a raw command */ /** Structure containing a raw command */
struct fuse_cmd; struct fuse_cmd;
struct fuse_dirents_t;
typedef struct fuse_dirents_t fuse_dirents_t;
/** /**
* The file system operations: * The file system operations:
* *

View File

@ -43,12 +43,10 @@ enum fuse_dirents_type_e
}; };
typedef enum fuse_dirents_type_e fuse_dirents_type_t; typedef enum fuse_dirents_type_e fuse_dirents_type_t;
typedef struct fuse_dirents_s fuse_dirents_t; typedef struct fuse_dirents_t fuse_dirents_t;
struct fuse_dirents_s struct fuse_dirents_t
{ {
char *buf; kvec_t(char) data;
uint64_t buf_len;
uint64_t data_len;
kvec_t(uint32_t) offs; kvec_t(uint32_t) offs;
fuse_dirents_type_t type; fuse_dirents_type_t type;
}; };

View File

@ -59,6 +59,10 @@
#define kv_pop(v) ((v).a[--(v).n]) #define kv_pop(v) ((v).a[--(v).n])
#define kv_size(v) ((v).n) #define kv_size(v) ((v).n)
#define kv_max(v) ((v).m) #define kv_max(v) ((v).m)
#define kv_first(v) (kv_A(v,0))
#define kv_last(v) (kv_A(v,kv_size(v)-1))
#define kv_end(v) (kv_A(v,kv_size(v)))
#define kv_delete(v,i) (kv_A(v,i) = kv_pop(v))
#define kv_resize(type, v, s) ((v).m = (s), (v).a = (type*)realloc((v).a, sizeof(type) * (v).m)) #define kv_resize(type, v, s) ((v).m = (s), (v).a = (type*)realloc((v).a, sizeof(type) * (v).m))

View File

@ -1981,6 +1981,7 @@ fuse_lib_init(void *data,
void void
fuse_fs_destroy(struct fuse_fs *fs) fuse_fs_destroy(struct fuse_fs *fs)
{ {
if(fs->op.destroy)
fs->op.destroy(); fs->op.destroy();
free(fs); free(fs);
} }
@ -2844,8 +2845,8 @@ readdir_buf_size(fuse_dirents_t *d_,
{ {
if(off_ >= kv_size(d_->offs)) if(off_ >= kv_size(d_->offs))
return 0; return 0;
if((kv_A(d_->offs,off_) + size_) > d_->data_len) if((kv_A(d_->offs,off_) + size_) > kv_size(d_->data))
return (d_->data_len - kv_A(d_->offs,off_)); return (kv_size(d_->data) - kv_A(d_->offs,off_));
return size_; return size_;
} }
@ -2854,7 +2855,11 @@ char*
readdir_buf(fuse_dirents_t *d_, readdir_buf(fuse_dirents_t *d_,
off_t off_) off_t off_)
{ {
return &d_->buf[kv_A(d_->offs,off_)]; size_t i;
i = kv_A(d_->offs,off_);
return &kv_A(d_->data,i);
} }
static static
@ -2878,7 +2883,7 @@ fuse_lib_readdir(fuse_req_t req_,
pthread_mutex_lock(&dh->lock); pthread_mutex_lock(&dh->lock);
rv = 0; rv = 0;
if((off_ == 0) || (d->data_len == 0)) if((off_ == 0) || (kv_size(d->data) == 0))
rv = fuse_fs_readdir(f->fs,&fi,d); rv = fuse_fs_readdir(f->fs,&fi,d);
if(rv) if(rv)
@ -2918,7 +2923,7 @@ fuse_lib_readdir_plus(fuse_req_t req_,
pthread_mutex_lock(&dh->lock); pthread_mutex_lock(&dh->lock);
rv = 0; rv = 0;
if((off_ == 0) || (d->data_len == 0)) if((off_ == 0) || (kv_size(d->data) == 0))
rv = fuse_fs_readdir_plus(f->fs,&fi,d); rv = fuse_fs_readdir_plus(f->fs,&fi,d);
if(rv) if(rv)

View File

@ -65,20 +65,15 @@ int
fuse_dirents_buf_resize(fuse_dirents_t *d_, fuse_dirents_buf_resize(fuse_dirents_t *d_,
uint64_t size_) uint64_t size_)
{ {
char *p; if((kv_size(d_->data) + size_) >= kv_max(d_->data))
if((d_->data_len + size_) >= d_->buf_len)
{ {
uint64_t new_size; uint64_t new_size;
new_size = round_up((d_->data_len + size_),DEFAULT_SIZE); new_size = round_up((kv_size(d_->data) + size_),DEFAULT_SIZE);
p = realloc(d_->buf,new_size);
memset(&p[d_->data_len],0,new_size - d_->data_len);
if(p == NULL)
return -errno;
d_->buf = p; kv_resize(char,d_->data,new_size);
d_->buf_len = new_size; if(d_->data.a == NULL)
return -ENOMEM;
} }
return 0; return 0;
@ -99,9 +94,8 @@ fuse_dirents_dirent_alloc(fuse_dirents_t *d_,
if(rv) if(rv)
return NULL; return NULL;
d = (fuse_dirent_t*)&d_->buf[d_->data_len]; d = (fuse_dirent_t*)&kv_end(d_->data);
kv_size(d_->data) += size;
d_->data_len += size;
return d; return d;
} }
@ -121,9 +115,8 @@ fuse_dirents_direntplus_alloc(fuse_dirents_t *d_,
if(rv) if(rv)
return NULL; return NULL;
d = (fuse_dirent_t*)&d_->buf[d_->data_len]; d = (fuse_dirent_t*)&kv_end(d_->data);
kv_size(d_->data) += size;
d_->data_len += size;
return d; return d;
} }
@ -182,8 +175,8 @@ fuse_dirent_find(fuse_dirents_t *d_,
if(d_->type != NORMAL) if(d_->type != NORMAL)
return NULL; return NULL;
cur = (fuse_dirent_t*)&d_->buf[0]; cur = (fuse_dirent_t*)&kv_first(d_->data);
end = (fuse_dirent_t*)&d_->buf[d_->data_len]; end = (fuse_dirent_t*)&kv_end(d_->data);
while(cur < end) while(cur < end)
{ {
if(cur->ino == ino_) if(cur->ino == ino_)
@ -205,8 +198,8 @@ fuse_direntplus_find(fuse_dirents_t *d_,
if(d_->type != PLUS) if(d_->type != PLUS)
return NULL; return NULL;
cur = (fuse_direntplus_t*)&d_->buf[0]; cur = (fuse_direntplus_t*)&kv_first(d_->data);
end = (fuse_direntplus_t*)&d_->buf[d_->data_len]; end = (fuse_direntplus_t*)&kv_end(d_->data);
while(cur < end) while(cur < end)
{ {
if(cur->dirent.ino == ino_) if(cur->dirent.ino == ino_)
@ -263,7 +256,7 @@ fuse_dirents_add(fuse_dirents_t *d_,
return -ENOMEM; return -ENOMEM;
d->off = kv_size(d_->offs); d->off = kv_size(d_->offs);
kv_push(uint32_t,d_->offs,d_->data_len); kv_push(uint32_t,d_->offs,kv_size(d_->data));
d->ino = dirent_->d_ino; d->ino = dirent_->d_ino;
d->namelen = namelen_; d->namelen = namelen_;
d->type = dirent_->d_type; d->type = dirent_->d_type;
@ -297,7 +290,7 @@ fuse_dirents_add_plus(fuse_dirents_t *d_,
return -ENOMEM; return -ENOMEM;
d->dirent.off = kv_size(d_->offs); d->dirent.off = kv_size(d_->offs);
kv_push(uint32_t,d_->offs,d_->data_len); kv_push(uint32_t,d_->offs,kv_size(d_->data));
d->dirent.ino = dirent_->d_ino; d->dirent.ino = dirent_->d_ino;
d->dirent.namelen = namelen_; d->dirent.namelen = namelen_;
d->dirent.type = dirent_->d_type; d->dirent.type = dirent_->d_type;
@ -333,7 +326,7 @@ fuse_dirents_add_linux(fuse_dirents_t *d_,
return -ENOMEM; return -ENOMEM;
d->off = kv_size(d_->offs); d->off = kv_size(d_->offs);
kv_push(uint32_t,d_->offs,d_->data_len); kv_push(uint32_t,d_->offs,kv_size(d_->data));
d->ino = dirent_->ino; d->ino = dirent_->ino;
d->namelen = namelen_; d->namelen = namelen_;
d->type = dirent_->type; d->type = dirent_->type;
@ -367,7 +360,7 @@ fuse_dirents_add_linux_plus(fuse_dirents_t *d_,
return -ENOMEM; return -ENOMEM;
d->dirent.off = kv_size(d_->offs); d->dirent.off = kv_size(d_->offs);
kv_push(uint32_t,d_->offs,d_->data_len); kv_push(uint32_t,d_->offs,kv_size(d_->data));
d->dirent.ino = dirent_->ino; d->dirent.ino = dirent_->ino;
d->dirent.namelen = namelen_; d->dirent.namelen = namelen_;
d->dirent.type = dirent_->type; d->dirent.type = dirent_->type;
@ -383,25 +376,21 @@ fuse_dirents_add_linux_plus(fuse_dirents_t *d_,
void void
fuse_dirents_reset(fuse_dirents_t *d_) fuse_dirents_reset(fuse_dirents_t *d_)
{ {
d_->data_len = 0;
d_->type = UNSET; d_->type = UNSET;
kv_size(d_->data) = 0;
kv_size(d_->offs) = 1; kv_size(d_->offs) = 1;
} }
int int
fuse_dirents_init(fuse_dirents_t *d_) fuse_dirents_init(fuse_dirents_t *d_)
{ {
void *buf;
buf = calloc(1,DEFAULT_SIZE);
if(buf == NULL)
return -ENOMEM;
d_->buf = buf;
d_->buf_len = DEFAULT_SIZE;
d_->data_len = 0;
d_->type = UNSET; d_->type = UNSET;
kv_init(d_->data);
kv_resize(char,d_->data,DEFAULT_SIZE);
if(d_->data.a == NULL)
return -ENOMEM;
kv_init(d_->offs); kv_init(d_->offs);
kv_resize(uint32_t,d_->offs,64); kv_resize(uint32_t,d_->offs,64);
kv_push(uint32_t,d_->offs,0); kv_push(uint32_t,d_->offs,0);
@ -412,11 +401,6 @@ fuse_dirents_init(fuse_dirents_t *d_)
void void
fuse_dirents_free(fuse_dirents_t *d_) fuse_dirents_free(fuse_dirents_t *d_)
{ {
d_->buf_len = 0; kv_destroy(d_->data);
d_->data_len = 0;
d_->type = UNSET;
kv_destroy(d_->offs); kv_destroy(d_->offs);
free(d_->buf);
} }

View File

@ -1,92 +0,0 @@
/* The MIT License
Copyright (c) 2008, by Attractive Chaos <attractor@live.co.uk>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
/*
An example:
#include "kvec.h"
int main() {
kvec_t(int) array;
kv_init(array);
kv_push(int, array, 10); // append
kv_a(int, array, 20) = 5; // dynamic
kv_A(array, 20) = 4; // static
kv_destroy(array);
return 0;
}
*/
/*
2008-09-22 (0.1.0):
* The initial version.
*/
#ifndef AC_KVEC_H
#define AC_KVEC_H
#include <stdlib.h>
#define kv_roundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x))
#define kvec_t(type) struct { size_t n, m; type *a; }
#define kv_init(v) ((v).n = (v).m = 0, (v).a = 0)
#define kv_destroy(v) free((v).a)
#define kv_A(v, i) ((v).a[(i)])
#define kv_pop(v) ((v).a[--(v).n])
#define kv_size(v) ((v).n)
#define kv_max(v) ((v).m)
#define kv_end(v) (kv_A(v,kv_size(v)-1))
#define kv_delete(v,i) (kv_A(v,i) = kv_pop(v))
#define kv_resize(type, v, s) ((v).m = (s), (v).a = (type*)realloc((v).a, sizeof(type) * (v).m))
#define kv_copy(type, v1, v0) do { \
if ((v1).m < (v0).n) kv_resize(type, v1, (v0).n); \
(v1).n = (v0).n; \
memcpy((v1).a, (v0).a, sizeof(type) * (v0).n); \
} while (0) \
#define kv_push(type, v, x) do { \
if ((v).n == (v).m) { \
(v).m = (v).m? (v).m<<1 : 2; \
(v).a = (type*)realloc((v).a, sizeof(type) * (v).m); \
} \
(v).a[(v).n++] = (x); \
} while (0)
#define kv_pushp(type, v) (((v).n == (v).m)? \
((v).m = ((v).m? (v).m<<1 : 2), \
(v).a = (type*)realloc((v).a, sizeof(type) * (v).m), 0) \
: 0), ((v).a + ((v).n++))
#define kv_a(type, v, i) (((v).m <= (size_t)(i)? \
((v).m = (v).n = (i) + 1, kv_roundup32((v).m), \
(v).a = (type*)realloc((v).a, sizeof(type) * (v).m), 0) \
: (v).n <= (size_t)(i)? (v).n = (i) + 1 \
: 0), (v).a[(i)])
#endif