mirror of
https://github.com/trapexit/mergerfs.git
synced 2024-11-25 09:41:43 +08:00
Rework dirents buffer management
This commit is contained in:
parent
6b5c484fbf
commit
4ea0de3ef2
|
@ -25,7 +25,6 @@
|
|||
|
||||
#include "extern_c.h"
|
||||
#include "fuse_common.h"
|
||||
#include "fuse_dirents.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
|
@ -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:
|
||||
*
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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))
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue
Block a user