From 4ea0de3ef22a516be31605915497177b5b76bd85 Mon Sep 17 00:00:00 2001 From: Antonio SJ Musumeci Date: Sat, 18 Sep 2021 22:22:47 -0400 Subject: [PATCH] Rework dirents buffer management --- libfuse/include/fuse.h | 4 +- libfuse/include/fuse_dirents.h | 12 ++--- libfuse/include/kvec.h | 4 ++ libfuse/lib/fuse.c | 17 ++++--- libfuse/lib/fuse_dirents.c | 62 +++++++++-------------- libfuse/lib/kvec.h | 92 ---------------------------------- 6 files changed, 46 insertions(+), 145 deletions(-) delete mode 100644 libfuse/lib/kvec.h diff --git a/libfuse/include/fuse.h b/libfuse/include/fuse.h index bb4ea1c3..74691926 100644 --- a/libfuse/include/fuse.h +++ b/libfuse/include/fuse.h @@ -25,7 +25,6 @@ #include "extern_c.h" #include "fuse_common.h" -#include "fuse_dirents.h" #include #include @@ -47,6 +46,9 @@ struct fuse; /** Structure containing a raw command */ struct fuse_cmd; +struct fuse_dirents_t; +typedef struct fuse_dirents_t fuse_dirents_t; + /** * The file system operations: * diff --git a/libfuse/include/fuse_dirents.h b/libfuse/include/fuse_dirents.h index 92920141..25abf198 100644 --- a/libfuse/include/fuse_dirents.h +++ b/libfuse/include/fuse_dirents.h @@ -43,14 +43,12 @@ enum fuse_dirents_type_e }; typedef enum fuse_dirents_type_e fuse_dirents_type_t; -typedef struct fuse_dirents_s fuse_dirents_t; -struct fuse_dirents_s +typedef struct fuse_dirents_t fuse_dirents_t; +struct fuse_dirents_t { - char *buf; - uint64_t buf_len; - uint64_t data_len; - kvec_t(uint32_t) offs; - fuse_dirents_type_t type; + kvec_t(char) data; + kvec_t(uint32_t) offs; + fuse_dirents_type_t type; }; int fuse_dirents_init(fuse_dirents_t *d); diff --git a/libfuse/include/kvec.h b/libfuse/include/kvec.h index 038de9e7..e600b8e6 100644 --- a/libfuse/include/kvec.h +++ b/libfuse/include/kvec.h @@ -59,6 +59,10 @@ #define kv_pop(v) ((v).a[--(v).n]) #define kv_size(v) ((v).n) #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)) diff --git a/libfuse/lib/fuse.c b/libfuse/lib/fuse.c index 2908c1d2..a0c033d3 100644 --- a/libfuse/lib/fuse.c +++ b/libfuse/lib/fuse.c @@ -1981,7 +1981,8 @@ fuse_lib_init(void *data, void fuse_fs_destroy(struct fuse_fs *fs) { - fs->op.destroy(); + if(fs->op.destroy) + fs->op.destroy(); free(fs); } @@ -2844,8 +2845,8 @@ readdir_buf_size(fuse_dirents_t *d_, { if(off_ >= kv_size(d_->offs)) return 0; - if((kv_A(d_->offs,off_) + size_) > d_->data_len) - return (d_->data_len - kv_A(d_->offs,off_)); + if((kv_A(d_->offs,off_) + size_) > kv_size(d_->data)) + return (kv_size(d_->data) - kv_A(d_->offs,off_)); return size_; } @@ -2854,7 +2855,11 @@ char* readdir_buf(fuse_dirents_t *d_, 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 @@ -2878,7 +2883,7 @@ fuse_lib_readdir(fuse_req_t req_, pthread_mutex_lock(&dh->lock); 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); if(rv) @@ -2918,7 +2923,7 @@ fuse_lib_readdir_plus(fuse_req_t req_, pthread_mutex_lock(&dh->lock); 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); if(rv) diff --git a/libfuse/lib/fuse_dirents.c b/libfuse/lib/fuse_dirents.c index 7a710b08..c8e9fc66 100644 --- a/libfuse/lib/fuse_dirents.c +++ b/libfuse/lib/fuse_dirents.c @@ -65,20 +65,15 @@ int fuse_dirents_buf_resize(fuse_dirents_t *d_, uint64_t size_) { - char *p; - - if((d_->data_len + size_) >= d_->buf_len) + if((kv_size(d_->data) + size_) >= kv_max(d_->data)) { uint64_t new_size; - new_size = round_up((d_->data_len + 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; + new_size = round_up((kv_size(d_->data) + size_),DEFAULT_SIZE); - d_->buf = p; - d_->buf_len = new_size; + kv_resize(char,d_->data,new_size); + if(d_->data.a == NULL) + return -ENOMEM; } return 0; @@ -99,9 +94,8 @@ fuse_dirents_dirent_alloc(fuse_dirents_t *d_, if(rv) return NULL; - d = (fuse_dirent_t*)&d_->buf[d_->data_len]; - - d_->data_len += size; + d = (fuse_dirent_t*)&kv_end(d_->data); + kv_size(d_->data) += size; return d; } @@ -121,9 +115,8 @@ fuse_dirents_direntplus_alloc(fuse_dirents_t *d_, if(rv) return NULL; - d = (fuse_dirent_t*)&d_->buf[d_->data_len]; - - d_->data_len += size; + d = (fuse_dirent_t*)&kv_end(d_->data); + kv_size(d_->data) += size; return d; } @@ -182,8 +175,8 @@ fuse_dirent_find(fuse_dirents_t *d_, if(d_->type != NORMAL) return NULL; - cur = (fuse_dirent_t*)&d_->buf[0]; - end = (fuse_dirent_t*)&d_->buf[d_->data_len]; + cur = (fuse_dirent_t*)&kv_first(d_->data); + end = (fuse_dirent_t*)&kv_end(d_->data); while(cur < end) { if(cur->ino == ino_) @@ -205,8 +198,8 @@ fuse_direntplus_find(fuse_dirents_t *d_, if(d_->type != PLUS) return NULL; - cur = (fuse_direntplus_t*)&d_->buf[0]; - end = (fuse_direntplus_t*)&d_->buf[d_->data_len]; + cur = (fuse_direntplus_t*)&kv_first(d_->data); + end = (fuse_direntplus_t*)&kv_end(d_->data); while(cur < end) { if(cur->dirent.ino == ino_) @@ -263,7 +256,7 @@ fuse_dirents_add(fuse_dirents_t *d_, return -ENOMEM; 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->namelen = namelen_; d->type = dirent_->d_type; @@ -297,7 +290,7 @@ fuse_dirents_add_plus(fuse_dirents_t *d_, return -ENOMEM; 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.namelen = namelen_; d->dirent.type = dirent_->d_type; @@ -333,7 +326,7 @@ fuse_dirents_add_linux(fuse_dirents_t *d_, return -ENOMEM; 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->namelen = namelen_; d->type = dirent_->type; @@ -367,7 +360,7 @@ fuse_dirents_add_linux_plus(fuse_dirents_t *d_, return -ENOMEM; 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.namelen = namelen_; d->dirent.type = dirent_->type; @@ -383,25 +376,21 @@ fuse_dirents_add_linux_plus(fuse_dirents_t *d_, void fuse_dirents_reset(fuse_dirents_t *d_) { - d_->data_len = 0; d_->type = UNSET; + kv_size(d_->data) = 0; kv_size(d_->offs) = 1; } int fuse_dirents_init(fuse_dirents_t *d_) { - void *buf; + d_->type = UNSET; - buf = calloc(1,DEFAULT_SIZE); - if(buf == NULL) + kv_init(d_->data); + kv_resize(char,d_->data,DEFAULT_SIZE); + if(d_->data.a == NULL) return -ENOMEM; - d_->buf = buf; - d_->buf_len = DEFAULT_SIZE; - d_->data_len = 0; - d_->type = UNSET; - kv_init(d_->offs); kv_resize(uint32_t,d_->offs,64); kv_push(uint32_t,d_->offs,0); @@ -412,11 +401,6 @@ fuse_dirents_init(fuse_dirents_t *d_) void fuse_dirents_free(fuse_dirents_t *d_) { - d_->buf_len = 0; - d_->data_len = 0; - d_->type = UNSET; - + kv_destroy(d_->data); kv_destroy(d_->offs); - - free(d_->buf); } diff --git a/libfuse/lib/kvec.h b/libfuse/lib/kvec.h deleted file mode 100644 index 6dc66f3d..00000000 --- a/libfuse/lib/kvec.h +++ /dev/null @@ -1,92 +0,0 @@ -/* The MIT License - - Copyright (c) 2008, by Attractive Chaos - - 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 - -#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