mirror of
https://github.com/trapexit/mergerfs.git
synced 2024-11-29 03:48:23 +08:00
Rework dirents buffer management
This commit is contained in:
parent
6b5c484fbf
commit
4ea0de3ef2
|
@ -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:
|
||||||
*
|
*
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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))
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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