mirror of
https://github.com/trapexit/mergerfs.git
synced 2024-11-22 11:39:52 +08:00
fix getdent name length calculation
This commit is contained in:
parent
b5fae4b356
commit
698c4147fc
2
Makefile
2
Makefile
|
@ -40,7 +40,7 @@ USE_XATTR = 1
|
|||
UGID_USE_RWLOCK = 0
|
||||
|
||||
ifeq ($(DEBUG),1)
|
||||
DEBUG_FLAGS := -g
|
||||
DEBUG_FLAGS := -O0 -g
|
||||
else
|
||||
DEBUG_FLAGS :=
|
||||
endif
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
VERSION = 2.9.7-mergerfs_2.29.0
|
||||
|
||||
ifeq ($(DEBUG),1)
|
||||
DEBUG_FLAGS := -g
|
||||
DEBUG_FLAGS := -O0 -g
|
||||
else
|
||||
DEBUG_FLAGS :=
|
||||
endif
|
||||
|
|
|
@ -25,6 +25,7 @@ extern "C" {
|
|||
#include "fuse_dirent.h"
|
||||
#include "fuse_direntplus.h"
|
||||
#include "fuse_entry.h"
|
||||
#include "linux_dirent64.h"
|
||||
|
||||
#include <dirent.h>
|
||||
#include <stdint.h>
|
||||
|
@ -55,20 +56,21 @@ void fuse_dirents_free(fuse_dirents_t *d);
|
|||
void fuse_dirents_reset(fuse_dirents_t *d);
|
||||
|
||||
int fuse_dirents_add(fuse_dirents_t *d,
|
||||
const struct dirent *de);
|
||||
const struct dirent *de,
|
||||
const uint64_t namelen);
|
||||
int fuse_dirents_add_plus(fuse_dirents_t *d,
|
||||
const struct dirent *de,
|
||||
const uint64_t namelen,
|
||||
const fuse_entry_t *entry,
|
||||
const struct stat *st);
|
||||
#ifdef __linux__
|
||||
struct linux_dirent64;
|
||||
int fuse_dirents_add_linux(fuse_dirents_t *d,
|
||||
const struct linux_dirent64 *de);
|
||||
int fuse_dirents_add_linux(fuse_dirents_t *d,
|
||||
const struct linux_dirent64 *de,
|
||||
const uint64_t namelen);
|
||||
int fuse_dirents_add_linux_plus(fuse_dirents_t *d,
|
||||
const struct linux_dirent64 *de,
|
||||
const uint64_t namelen,
|
||||
const fuse_entry_t *entry,
|
||||
const struct stat *st);
|
||||
#endif
|
||||
|
||||
void *fuse_dirents_find(fuse_dirents_t *d,
|
||||
const uint64_t ino);
|
||||
|
|
12
libfuse/include/linux_dirent64.h
Normal file
12
libfuse/include/linux_dirent64.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct linux_dirent64
|
||||
{
|
||||
uint64_t d_ino;
|
||||
int64_t d_off;
|
||||
uint16_t d_reclen;
|
||||
uint8_t d_type;
|
||||
char d_name[];
|
||||
};
|
|
@ -5,6 +5,7 @@
|
|||
#include "fuse_direntplus.h"
|
||||
#include "fuse_dirents.h"
|
||||
#include "fuse_entry.h"
|
||||
#include "linux_dirent64.h"
|
||||
#include "stat_utils.h"
|
||||
|
||||
#include <dirent.h>
|
||||
|
@ -17,26 +18,6 @@
|
|||
|
||||
#define DEFAULT_SIZE (1024 * 16)
|
||||
|
||||
static
|
||||
uint64_t
|
||||
dirent_exact_namelen(const struct dirent *d_)
|
||||
{
|
||||
#ifdef _D_EXACT_NAMELEN
|
||||
return _D_EXACT_NAMELEN(d_);
|
||||
#elif defined _DIRENT_HAVE_D_NAMLEN
|
||||
return d_->d_namlen;
|
||||
#else
|
||||
return strlen(d_->d_name);
|
||||
#endif
|
||||
}
|
||||
|
||||
static
|
||||
uint64_t
|
||||
dirent_alloc_namelen(const struct dirent *d_)
|
||||
{
|
||||
return (dirent_exact_namelen(d_) + 1);
|
||||
}
|
||||
|
||||
static
|
||||
uint64_t
|
||||
align_uint64_t(uint64_t v_)
|
||||
|
@ -254,10 +235,10 @@ fuse_dirents_convert_plus2normal(fuse_dirents_t *d_)
|
|||
|
||||
int
|
||||
fuse_dirents_add(fuse_dirents_t *d_,
|
||||
const struct dirent *dirent_)
|
||||
const struct dirent *dirent_,
|
||||
const uint64_t namelen_)
|
||||
{
|
||||
uint64_t size;
|
||||
uint64_t namelen;
|
||||
fuse_dirent_t *d;
|
||||
|
||||
switch(d_->type)
|
||||
|
@ -271,8 +252,7 @@ fuse_dirents_add(fuse_dirents_t *d_,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
namelen = dirent_alloc_namelen(dirent_);
|
||||
size = fuse_dirent_size(namelen);
|
||||
size = fuse_dirent_size(namelen_);
|
||||
|
||||
d = fuse_dirents_alloc(d_,size);
|
||||
if(d == NULL)
|
||||
|
@ -280,9 +260,9 @@ fuse_dirents_add(fuse_dirents_t *d_,
|
|||
|
||||
d->ino = dirent_->d_ino;
|
||||
d->off = d_->data_len;
|
||||
d->namelen = namelen;
|
||||
d->namelen = namelen_;
|
||||
d->type = dirent_->d_type;
|
||||
memcpy(d->name,dirent_->d_name,namelen);
|
||||
memcpy(d->name,dirent_->d_name,namelen_);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -290,11 +270,11 @@ fuse_dirents_add(fuse_dirents_t *d_,
|
|||
int
|
||||
fuse_dirents_add_plus(fuse_dirents_t *d_,
|
||||
const struct dirent *dirent_,
|
||||
const uint64_t namelen_,
|
||||
const fuse_entry_t *entry_,
|
||||
const struct stat *st_)
|
||||
{
|
||||
uint64_t size;
|
||||
uint64_t namelen;
|
||||
fuse_direntplus_t *d;
|
||||
|
||||
switch(d_->type)
|
||||
|
@ -308,8 +288,7 @@ fuse_dirents_add_plus(fuse_dirents_t *d_,
|
|||
break;
|
||||
}
|
||||
|
||||
namelen = dirent_alloc_namelen(dirent_);
|
||||
size = fuse_direntplus_size(namelen);
|
||||
size = fuse_direntplus_size(namelen_);
|
||||
|
||||
d = fuse_dirents_alloc(d_,size);
|
||||
if(d == NULL)
|
||||
|
@ -317,9 +296,9 @@ fuse_dirents_add_plus(fuse_dirents_t *d_,
|
|||
|
||||
d->dirent.ino = dirent_->d_ino;
|
||||
d->dirent.off = d_->data_len;
|
||||
d->dirent.namelen = namelen;
|
||||
d->dirent.namelen = namelen_;
|
||||
d->dirent.type = dirent_->d_type;
|
||||
memcpy(d->dirent.name,dirent_->d_name,namelen);
|
||||
memcpy(d->dirent.name,dirent_->d_name,namelen_);
|
||||
|
||||
d->entry = *entry_;
|
||||
|
||||
|
@ -328,22 +307,12 @@ fuse_dirents_add_plus(fuse_dirents_t *d_,
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
struct linux_dirent64
|
||||
{
|
||||
uint64_t d_ino;
|
||||
int64_t d_off;
|
||||
uint16_t d_reclen;
|
||||
uint8_t d_type;
|
||||
char d_name[];
|
||||
};
|
||||
|
||||
int
|
||||
fuse_dirents_add_linux(fuse_dirents_t *d_,
|
||||
const struct linux_dirent64 *dirent_)
|
||||
const struct linux_dirent64 *dirent_,
|
||||
const uint64_t namelen_)
|
||||
{
|
||||
uint64_t size;
|
||||
uint64_t namelen;
|
||||
fuse_dirent_t *d;
|
||||
|
||||
switch(d_->type)
|
||||
|
@ -357,8 +326,7 @@ fuse_dirents_add_linux(fuse_dirents_t *d_,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
namelen = (dirent_->d_reclen - offsetof(struct linux_dirent64,d_name));
|
||||
size = fuse_dirent_size(namelen);
|
||||
size = fuse_dirent_size(namelen_);
|
||||
|
||||
d = fuse_dirents_alloc(d_,size);
|
||||
if(d == NULL)
|
||||
|
@ -366,9 +334,9 @@ fuse_dirents_add_linux(fuse_dirents_t *d_,
|
|||
|
||||
d->ino = dirent_->d_ino;
|
||||
d->off = d_->data_len;
|
||||
d->namelen = namelen;
|
||||
d->namelen = namelen_;
|
||||
d->type = dirent_->d_type;
|
||||
memcpy(d->name,dirent_->d_name,namelen);
|
||||
memcpy(d->name,dirent_->d_name,namelen_);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -376,11 +344,11 @@ fuse_dirents_add_linux(fuse_dirents_t *d_,
|
|||
int
|
||||
fuse_dirents_add_linux_plus(fuse_dirents_t *d_,
|
||||
const struct linux_dirent64 *dirent_,
|
||||
const uint64_t namelen_,
|
||||
const fuse_entry_t *entry_,
|
||||
const struct stat *st_)
|
||||
{
|
||||
uint64_t size;
|
||||
uint64_t namelen;
|
||||
fuse_direntplus_t *d;
|
||||
|
||||
switch(d_->type)
|
||||
|
@ -394,8 +362,7 @@ fuse_dirents_add_linux_plus(fuse_dirents_t *d_,
|
|||
break;
|
||||
}
|
||||
|
||||
namelen = (dirent_->d_reclen - offsetof(struct linux_dirent64,d_name));
|
||||
size = fuse_direntplus_size(namelen);
|
||||
size = fuse_direntplus_size(namelen_);
|
||||
|
||||
d = fuse_dirents_alloc(d_,size);
|
||||
if(d == NULL)
|
||||
|
@ -403,9 +370,9 @@ fuse_dirents_add_linux_plus(fuse_dirents_t *d_,
|
|||
|
||||
d->dirent.ino = dirent_->d_ino;
|
||||
d->dirent.off = d_->data_len;
|
||||
d->dirent.namelen = namelen;
|
||||
d->dirent.namelen = namelen_;
|
||||
d->dirent.type = dirent_->d_type;
|
||||
memcpy(d->dirent.name,dirent_->d_name,namelen);
|
||||
memcpy(d->dirent.name,dirent_->d_name,namelen_);
|
||||
|
||||
d->entry = *entry_;
|
||||
|
||||
|
@ -413,7 +380,6 @@ fuse_dirents_add_linux_plus(fuse_dirents_t *d_,
|
|||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
fuse_dirents_reset(fuse_dirents_t *d_)
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "fs_inode.hpp"
|
||||
#include "fs_path.hpp"
|
||||
#include "hashset.hpp"
|
||||
#include "linux_dirent64.h"
|
||||
#include "mempools.hpp"
|
||||
#include "rwlock.hpp"
|
||||
#include "ugid.hpp"
|
||||
|
@ -42,15 +43,6 @@
|
|||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
struct linux_dirent64
|
||||
{
|
||||
uint64_t d_ino;
|
||||
int64_t d_off;
|
||||
uint16_t d_reclen;
|
||||
uint8_t d_type;
|
||||
char d_name[];
|
||||
};
|
||||
|
||||
namespace l
|
||||
{
|
||||
static
|
||||
|
@ -84,6 +76,7 @@ namespace l
|
|||
char *buf;
|
||||
HashSet names;
|
||||
string basepath;
|
||||
uint64_t namelen;
|
||||
struct linux_dirent64 *d;
|
||||
|
||||
buf = (char*)g_DENTS_BUF_POOL.alloc();
|
||||
|
@ -116,14 +109,15 @@ namespace l
|
|||
for(int64_t pos = 0; pos < nread; pos += d->d_reclen)
|
||||
{
|
||||
d = (struct linux_dirent64*)(buf + pos);
|
||||
namelen = (strlen(d->d_name) + 1);
|
||||
|
||||
rv = names.put(d->d_name);
|
||||
rv = names.put(d->d_name,namelen);
|
||||
if(rv == 0)
|
||||
continue;
|
||||
|
||||
d->d_ino = fs::inode::recompute(d->d_ino,dev);
|
||||
|
||||
rv = fuse_dirents_add_linux(buf_,d);
|
||||
rv = fuse_dirents_add_linux(buf_,d,namelen);
|
||||
if(rv)
|
||||
return close_free_ret_enomem(dirfd,buf);
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "fs_inode.hpp"
|
||||
#include "fs_path.hpp"
|
||||
#include "hashset.hpp"
|
||||
#include "linux_dirent64.h"
|
||||
#include "mempools.hpp"
|
||||
#include "rwlock.hpp"
|
||||
#include "ugid.hpp"
|
||||
|
@ -43,15 +44,6 @@
|
|||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
struct linux_dirent64
|
||||
{
|
||||
uint64_t d_ino;
|
||||
int64_t d_off;
|
||||
uint16_t d_reclen;
|
||||
uint8_t d_type;
|
||||
char d_name[];
|
||||
};
|
||||
|
||||
namespace l
|
||||
{
|
||||
static
|
||||
|
@ -84,6 +76,7 @@ namespace l
|
|||
char *buf;
|
||||
HashSet names;
|
||||
string basepath;
|
||||
uint64_t namelen;
|
||||
struct stat st;
|
||||
fuse_entry_t entry;
|
||||
struct linux_dirent64 *d;
|
||||
|
@ -122,8 +115,9 @@ namespace l
|
|||
for(int64_t pos = 0; pos < nread; pos += d->d_reclen)
|
||||
{
|
||||
d = (struct linux_dirent64*)(buf + pos);
|
||||
namelen = (strlen(d->d_name) + 1);
|
||||
|
||||
rv = names.put(d->d_name);
|
||||
rv = names.put(d->d_name,namelen);
|
||||
if(rv == 0)
|
||||
continue;
|
||||
|
||||
|
@ -134,7 +128,7 @@ namespace l
|
|||
d->d_ino = fs::inode::recompute(d->d_ino,dev);
|
||||
st.st_ino = d->d_ino;
|
||||
|
||||
rv = fuse_dirents_add_linux_plus(buf_,d,&entry,&st);
|
||||
rv = fuse_dirents_add_linux_plus(buf_,d,namelen,&entry,&st);
|
||||
if(rv)
|
||||
return close_free_ret_enomem(dirfd,buf);
|
||||
}
|
||||
|
|
|
@ -45,6 +45,26 @@ using std::vector;
|
|||
|
||||
namespace l
|
||||
{
|
||||
static
|
||||
uint64_t
|
||||
dirent_exact_namelen(const struct dirent *d_)
|
||||
{
|
||||
#ifdef _D_EXACT_NAMLEN
|
||||
return _D_EXACT_NAMLEN(d_);
|
||||
#elif defined _DIRENT_HAVE_D_NAMLEN
|
||||
return d_->d_namlen;
|
||||
#else
|
||||
return strlen(d_->d_name);
|
||||
#endif
|
||||
}
|
||||
|
||||
static
|
||||
uint64_t
|
||||
dirent_alloc_namelen(const struct dirent *d_)
|
||||
{
|
||||
return (dirent_exact_namelen(d_) + 1);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
readdir_plus(const Branches &branches_,
|
||||
|
@ -55,6 +75,7 @@ namespace l
|
|||
HashSet names;
|
||||
string basepath;
|
||||
struct stat st;
|
||||
uint64_t namelen;
|
||||
fuse_entry_t entry;
|
||||
|
||||
entry.nodeid = 0;
|
||||
|
@ -83,7 +104,9 @@ namespace l
|
|||
rv = 0;
|
||||
for(struct dirent *de = fs::readdir(dh); de && !rv; de = fs::readdir(dh))
|
||||
{
|
||||
rv = names.put(de->d_name);
|
||||
namelen = l::dirent_alloc_namelen(de);
|
||||
|
||||
rv = names.put(de->d_name,namelen);
|
||||
if(rv == 0)
|
||||
continue;
|
||||
|
||||
|
@ -94,7 +117,7 @@ namespace l
|
|||
de->d_ino = fs::inode::recompute(de->d_ino,dev);
|
||||
st.st_ino = de->d_ino;
|
||||
|
||||
rv = fuse_dirents_add_plus(buf_,de,&entry,&st);
|
||||
rv = fuse_dirents_add_plus(buf_,de,namelen,&entry,&st);
|
||||
if(rv)
|
||||
return (fs::closedir(dh),-ENOMEM);
|
||||
}
|
||||
|
|
|
@ -44,6 +44,26 @@ using std::vector;
|
|||
|
||||
namespace l
|
||||
{
|
||||
static
|
||||
uint64_t
|
||||
dirent_exact_namelen(const struct dirent *d_)
|
||||
{
|
||||
#ifdef _D_EXACT_NAMLEN
|
||||
return _D_EXACT_NAMLEN(d_);
|
||||
#elif defined _DIRENT_HAVE_D_NAMLEN
|
||||
return d_->d_namlen;
|
||||
#else
|
||||
return strlen(d_->d_name);
|
||||
#endif
|
||||
}
|
||||
|
||||
static
|
||||
uint64_t
|
||||
dirent_alloc_namelen(const struct dirent *d_)
|
||||
{
|
||||
return (dirent_exact_namelen(d_) + 1);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
readdir(const Branches &branches_,
|
||||
|
@ -53,6 +73,7 @@ namespace l
|
|||
dev_t dev;
|
||||
HashSet names;
|
||||
string basepath;
|
||||
uint64_t namelen;
|
||||
|
||||
for(size_t i = 0, ei = branches_.size(); i != ei; i++)
|
||||
{
|
||||
|
@ -74,13 +95,15 @@ namespace l
|
|||
rv = 0;
|
||||
for(struct dirent *de = fs::readdir(dh); de && !rv; de = fs::readdir(dh))
|
||||
{
|
||||
rv = names.put(de->d_name);
|
||||
namelen = l::dirent_alloc_namelen(de);
|
||||
|
||||
rv = names.put(de->d_name,namelen);
|
||||
if(rv == 0)
|
||||
continue;
|
||||
|
||||
de->d_ino = fs::inode::recompute(de->d_ino,dev);
|
||||
|
||||
rv = fuse_dirents_add(buf_,de);
|
||||
rv = fuse_dirents_add(buf_,de,namelen);
|
||||
if(rv)
|
||||
return (fs::closedir(dh),-ENOMEM);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user