additional readdir refactor cleanup

Differences between readdir and getdents is minimal at best. Leaving code
for now to allow for possible expansion later.
This commit is contained in:
Antonio SJ Musumeci 2020-06-26 16:50:49 -04:00
parent 4160a8e2f8
commit dbdd3e22fc
28 changed files with 453 additions and 177 deletions

View File

@ -1,7 +1,7 @@
/*
ISC License
Copyright (c) 2019, Antonio SJ Musumeci <trapexit@spawn.link>
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above

View File

@ -25,7 +25,7 @@ extern "C" {
#include "fuse_dirent.h"
#include "fuse_direntplus.h"
#include "fuse_entry.h"
#include "linux_dirent64.h"
#include "linux_dirent.h"
#include <dirent.h>
#include <stdint.h>
@ -63,14 +63,14 @@ int fuse_dirents_add_plus(fuse_dirents_t *d,
const uint64_t namelen,
const fuse_entry_t *entry,
const struct stat *st);
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);
int fuse_dirents_add_linux(fuse_dirents_t *d,
const struct linux_dirent *de,
const uint64_t namelen);
int fuse_dirents_add_linux_plus(fuse_dirents_t *d,
const struct linux_dirent *de,
const uint64_t namelen,
const fuse_entry_t *entry,
const struct stat *st);
void *fuse_dirents_find(fuse_dirents_t *d,
const uint64_t ino);

View File

@ -0,0 +1,9 @@
#pragma once
struct linux_dirent
{
unsigned long ino;
unsigned long off;
unsigned short reclen;
char name[];
};

View File

@ -1,12 +0,0 @@
#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[];
};

View File

@ -5,7 +5,7 @@
#include "fuse_direntplus.h"
#include "fuse_dirents.h"
#include "fuse_entry.h"
#include "linux_dirent64.h"
#include "linux_dirent.h"
#include "stat_utils.h"
#include <dirent.h>
@ -16,7 +16,8 @@
#include <stdlib.h>
#include <string.h>
#define DEFAULT_SIZE (1024 * 16)
/* 32KB - same as glibc getdents buffer size */
#define DEFAULT_SIZE (1024 * 32)
static
uint64_t
@ -308,9 +309,9 @@ fuse_dirents_add_plus(fuse_dirents_t *d_,
}
int
fuse_dirents_add_linux(fuse_dirents_t *d_,
const struct linux_dirent64 *dirent_,
const uint64_t namelen_)
fuse_dirents_add_linux(fuse_dirents_t *d_,
const struct linux_dirent *dirent_,
const uint64_t namelen_)
{
uint64_t size;
fuse_dirent_t *d;
@ -332,21 +333,21 @@ fuse_dirents_add_linux(fuse_dirents_t *d_,
if(d == NULL)
return -ENOMEM;
d->ino = dirent_->d_ino;
d->ino = dirent_->ino;
d->off = d_->data_len;
d->namelen = namelen_;
d->type = dirent_->d_type;
memcpy(d->name,dirent_->d_name,namelen_);
d->type = *((char*)dirent_ + dirent_->reclen - 1);
memcpy(d->name,dirent_->name,namelen_);
return 0;
}
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_)
fuse_dirents_add_linux_plus(fuse_dirents_t *d_,
const struct linux_dirent *dirent_,
const uint64_t namelen_,
const fuse_entry_t *entry_,
const struct stat *st_)
{
uint64_t size;
fuse_direntplus_t *d;
@ -368,11 +369,11 @@ fuse_dirents_add_linux_plus(fuse_dirents_t *d_,
if(d == NULL)
return -ENOMEM;
d->dirent.ino = dirent_->d_ino;
d->dirent.ino = dirent_->ino;
d->dirent.off = d_->data_len;
d->dirent.namelen = namelen_;
d->dirent.type = dirent_->d_type;
memcpy(d->dirent.name,dirent_->d_name,namelen_);
d->dirent.type = *((char*)dirent_ + dirent_->reclen - 1);
memcpy(d->dirent.name,dirent_->name,namelen_);
d->entry = *entry_;

View File

@ -90,6 +90,7 @@ Config::Config()
nullrw(false),
pid(::getpid()),
posix_acl(false),
readdir(ReadDir::ENUM::POSIX),
readdirplus(false),
security_capability(true),
srcmounts(branches),
@ -149,6 +150,7 @@ Config::Config()
_map["nullrw"] = &nullrw;
_map["pid"] = &pid;
_map["posix_acl"] = &posix_acl;
// _map["readdir"] = &readdir;
_map["readdirplus"] = &readdirplus;
_map["security_capability"] = &security_capability;
_map["srcmounts"] = &srcmounts;

View File

@ -17,6 +17,7 @@
#pragma once
#include "branch.hpp"
#include "config_readdir.hpp"
#include "enum.hpp"
#include "errno.hpp"
#include "func_category.hpp"
@ -110,6 +111,7 @@ public:
ConfigBOOL nullrw;
ConfigUINT64 pid;
ConfigBOOL posix_acl;
ReadDir readdir;
ConfigBOOL readdirplus;
ConfigBOOL security_capability;
SrcMounts srcmounts;

49
src/config_readdir.cpp Normal file
View File

@ -0,0 +1,49 @@
/*
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config_readdir.hpp"
#include "ef.hpp"
template<>
int
ReadDir::from_string(const std::string &s_)
{
if(s_ == "posix")
_data = ReadDir::ENUM::POSIX;
ef(s_ == "linux")
_data = ReadDir::ENUM::LINUX;
else
return -EINVAL;
return 0;
}
template<>
std::string
ReadDir::to_string(void) const
{
switch(_data)
{
case ReadDir::ENUM::POSIX:
return "posix";
case ReadDir::ENUM::LINUX:
return "linux";
}
return "invalid";
}

29
src/config_readdir.hpp Normal file
View File

@ -0,0 +1,29 @@
/*
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "enum.hpp"
enum class ReadDirEnum
{
POSIX,
LINUX
};
typedef Enum<ReadDirEnum> ReadDir;

View File

@ -16,6 +16,8 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "tofrom_string.hpp"
#include <string>

View File

@ -16,6 +16,8 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

37
src/fs_base_getdents.cpp Normal file
View File

@ -0,0 +1,37 @@
/*
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#if defined __linux__
#include <unistd.h>
#include <sys/syscall.h>
#endif
namespace fs
{
int
getdents(unsigned int fd_,
void *dirp_,
unsigned int count_)
{
#if defined SYS_getdents64
return ::syscall(SYS_getdents,fd_,dirp_,count_);
#else
return (errno=ENOTSUP,-1);
#endif
}
}

27
src/fs_base_getdents.hpp Normal file
View File

@ -0,0 +1,27 @@
/*
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
namespace fs
{
int
getdents(unsigned int fd,
void *dirp,
unsigned int count);
}

View File

@ -18,6 +18,8 @@
#include "fs_base_stat.hpp"
#include "fs_copy_file_range.hpp"
#include <stdint.h>
namespace l
{
int64_t

View File

@ -16,9 +16,11 @@
#pragma once
#include <stdint.h>
namespace fs
{
int
int64_t
copydata_copy_file_range(const int src_fd,
const int dst_fd);
}

View File

@ -14,6 +14,8 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include <string>
#include <vector>

View File

@ -16,6 +16,8 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include <stdint.h>
#include <sys/statvfs.h>

View File

@ -16,8 +16,35 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef __linux__
# include "fuse_readdir_linux.icpp"
#else
# include "fuse_readdir_posix.icpp"
#endif
#include "fuse_readdir_posix.hpp"
#include "fuse_readdir_linux.hpp"
#include "config.hpp"
#include "dirinfo.hpp"
#include "rwlock.hpp"
#include "ugid.hpp"
#include <fuse.h>
namespace FUSE
{
int
readdir(fuse_file_info *ffi_,
fuse_dirents_t *buf_)
{
DirInfo *di = reinterpret_cast<DirInfo*>(ffi_->fh);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::ro();
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard guard(&config.branches.lock);
switch(config.readdir)
{
case ReadDir::ENUM::LINUX:
return FUSE::readdir_linux(config.branches,di->fusepath.c_str(),buf_);
default:
case ReadDir::ENUM::POSIX:
return FUSE::readdir_posix(config.branches,di->fusepath.c_str(),buf_);
}
}
}

View File

@ -14,22 +14,18 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#define _DEFAULT_SOURCE
#include "config.hpp"
#include "dirinfo.hpp"
#include "branch.hpp"
#include "errno.hpp"
#include "fs_base_close.hpp"
#include "fs_base_getdents.hpp"
#include "fs_base_open.hpp"
#include "fs_base_stat.hpp"
#include "fs_devid.hpp"
#include "fs_inode.hpp"
#include "fs_path.hpp"
#include "hashset.hpp"
#include "linux_dirent64.h"
#include "linux_dirent.h"
#include "mempools.hpp"
#include "rwlock.hpp"
#include "ugid.hpp"
#include <fuse.h>
#include <fuse_dirents.h>
@ -38,23 +34,12 @@
#include <vector>
#include <stddef.h>
#include <sys/syscall.h>
using std::string;
using std::vector;
namespace l
{
static
inline
int
getdents64(unsigned int fd_,
char *dirp_,
unsigned int count_)
{
return syscall(SYS_getdents64,fd_,dirp_,count_);
}
static
int
close_free_ret_enomem(int fd_,
@ -77,7 +62,7 @@ namespace l
HashSet names;
string basepath;
uint64_t namelen;
struct linux_dirent64 *d;
struct linux_dirent *d;
buf = (char*)g_DENTS_BUF_POOL.alloc();
if(buf == NULL)
@ -100,22 +85,22 @@ namespace l
for(;;)
{
nread = l::getdents64(dirfd,buf,g_DENTS_BUF_POOL.size());
nread = fs::getdents(dirfd,buf,g_DENTS_BUF_POOL.size());
if(nread == -1)
break;
if(nread == 0)
break;
for(int64_t pos = 0; pos < nread; pos += d->d_reclen)
for(int64_t pos = 0; pos < nread; pos += d->reclen)
{
d = (struct linux_dirent64*)(buf + pos);
namelen = (strlen(d->d_name) + 1);
d = (struct linux_dirent*)(buf + pos);
namelen = strlen(d->name);
rv = names.put(d->d_name,namelen);
rv = names.put(d->name,namelen);
if(rv == 0)
continue;
d->d_ino = fs::inode::recompute(d->d_ino,dev);
d->ino = fs::inode::recompute(d->ino,dev);
rv = fuse_dirents_add_linux(buf_,d,namelen);
if(rv)
@ -135,17 +120,10 @@ namespace l
namespace FUSE
{
int
readdir(fuse_file_info *ffi_,
fuse_dirents_t *buf_)
readdir_linux(const Branches &branches_,
const char *dirname_,
fuse_dirents_t *buf_)
{
DirInfo *di = reinterpret_cast<DirInfo*>(ffi_->fh);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::ro();
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.branches.lock);
return l::readdir(config.branches,
di->fusepath.c_str(),
buf_);
return l::readdir(branches_,dirname_,buf_);
}
}

View File

@ -0,0 +1,33 @@
/*
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "branch.hpp"
#include <fuse.h>
#include <stdint.h>
namespace FUSE
{
int
readdir_linux(const Branches &branches,
const char *dirname,
fuse_dirents_t *buf);
}

View File

@ -16,8 +16,43 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef __linux__
# include "fuse_readdir_plus_linux.icpp"
#else
# include "fuse_readdir_plus_posix.icpp"
#endif
#include "fuse_readdir_plus_linux.hpp"
#include "fuse_readdir_plus_posix.hpp"
#include "config.hpp"
#include "dirinfo.hpp"
#include "rwlock.hpp"
#include "ugid.hpp"
#include <fuse.h>
namespace FUSE
{
int
readdir_plus(fuse_file_info *ffi_,
fuse_dirents_t *buf_)
{
DirInfo *di = reinterpret_cast<DirInfo*>(ffi_->fh);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::ro();
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard guard(&config.branches.lock);
switch(config.readdir)
{
case ReadDir::ENUM::LINUX:
return FUSE::readdir_plus_linux(config.branches,
di->fusepath.c_str(),
config.cache_entry,
config.cache_attr,
buf_);
default:
case ReadDir::ENUM::POSIX:
return FUSE::readdir_plus_posix(config.branches,
di->fusepath.c_str(),
config.cache_entry,
config.cache_attr,
buf_);
}
}
}

View File

@ -18,10 +18,6 @@
#include <fuse.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
namespace FUSE
{
int

View File

@ -14,23 +14,19 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#define _DEFAULT_SOURCE
#include "config.hpp"
#include "dirinfo.hpp"
#include "branch.hpp"
#include "errno.hpp"
#include "fs_base_close.hpp"
#include "fs_base_fstatat.hpp"
#include "fs_base_getdents.hpp"
#include "fs_base_open.hpp"
#include "fs_base_stat.hpp"
#include "fs_devid.hpp"
#include "fs_inode.hpp"
#include "fs_path.hpp"
#include "hashset.hpp"
#include "linux_dirent64.h"
#include "linux_dirent.h"
#include "mempools.hpp"
#include "rwlock.hpp"
#include "ugid.hpp"
#include <fuse.h>
#include <fuse_dirents.h>
@ -39,23 +35,12 @@
#include <vector>
#include <stddef.h>
#include <sys/syscall.h>
using std::string;
using std::vector;
namespace l
{
static
inline
int
getdents64(unsigned int fd_,
char *dirp_,
unsigned int count_)
{
return syscall(SYS_getdents64,fd_,dirp_,count_);
}
int
close_free_ret_enomem(int fd_,
void *buf_)
@ -81,7 +66,7 @@ namespace l
uint64_t namelen;
struct stat st;
fuse_entry_t entry;
struct linux_dirent64 *d;
struct linux_dirent *d;
buf = (char*)g_DENTS_BUF_POOL.alloc();
@ -108,27 +93,27 @@ namespace l
for(;;)
{
nread = l::getdents64(dirfd,buf,g_DENTS_BUF_POOL.size());
nread = fs::getdents(dirfd,buf,g_DENTS_BUF_POOL.size());
if(nread == -1)
break;
if(nread == 0)
break;
for(int64_t pos = 0; pos < nread; pos += d->d_reclen)
for(int64_t pos = 0; pos < nread; pos += d->reclen)
{
d = (struct linux_dirent64*)(buf + pos);
namelen = (strlen(d->d_name) + 1);
d = (struct linux_dirent*)(buf + pos);
namelen = (strlen(d->name) + 1);
rv = names.put(d->d_name,namelen);
rv = names.put(d->name,namelen);
if(rv == 0)
continue;
rv = fs::fstatat_nofollow(dirfd,d->d_name,&st);
rv = fs::fstatat_nofollow(dirfd,d->name,&st);
if(rv == -1)
memset(&st,0,sizeof(st));
d->d_ino = fs::inode::recompute(d->d_ino,dev);
st.st_ino = d->d_ino;
d->ino = fs::inode::recompute(d->ino,dev);
st.st_ino = d->ino;
rv = fuse_dirents_add_linux_plus(buf_,d,namelen,&entry,&st);
if(rv)
@ -148,19 +133,12 @@ namespace l
namespace FUSE
{
int
readdir_plus(fuse_file_info *ffi_,
fuse_dirents_t *buf_)
readdir_plus_linux(const Branches &branches_,
const char *dirname_,
const uint64_t entry_timeout_,
const uint64_t attr_timeout_,
fuse_dirents_t *buf_)
{
DirInfo *di = reinterpret_cast<DirInfo*>(ffi_->fh);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::ro();
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard guard(&config.branches.lock);
return l::readdir_plus(config.branches,
di->fusepath.c_str(),
config.cache_entry,
config.cache_attr,
buf_);
return l::readdir_plus(branches_,dirname_,entry_timeout_,attr_timeout_,buf_);
}
}

View File

@ -0,0 +1,35 @@
/*
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "branch.hpp"
#include <fuse.h>
#include <stdint.h>
namespace FUSE
{
int
readdir_plus_linux(const Branches &branches_,
const char *dirname_,
const uint64_t entry_timeout_,
const uint64_t attr_timeout_,
fuse_dirents_t *buf_);
}

View File

@ -16,8 +16,7 @@
#define _DEFAULT_SOURCE
#include "config.hpp"
#include "dirinfo.hpp"
#include "branch.hpp"
#include "errno.hpp"
#include "fs_base_closedir.hpp"
#include "fs_base_dirfd.hpp"
@ -29,8 +28,6 @@
#include "fs_inode.hpp"
#include "fs_path.hpp"
#include "hashset.hpp"
#include "rwlock.hpp"
#include "ugid.hpp"
#include <fuse.h>
#include <fuse_dirents.h>
@ -58,17 +55,12 @@ namespace l
#endif
}
static
uint64_t
dirent_alloc_namelen(const struct dirent *d_)
{
return (dirent_exact_namelen(d_) + 1);
}
static
int
readdir_plus(const Branches &branches_,
const char *dirname_,
const uint64_t entry_timeout_,
const uint64_t attr_timeout_,
fuse_dirents_t *buf_)
{
dev_t dev;
@ -80,8 +72,8 @@ namespace l
entry.nodeid = 0;
entry.generation = 0;
entry.entry_valid = 1;
entry.attr_valid = 1;
entry.entry_valid = entry_timeout_;
entry.attr_valid = attr_timeout_;
entry.entry_valid_nsec = 0;
entry.attr_valid_nsec = 0;
for(size_t i = 0, ei = branches_.size(); i != ei; i++)
@ -104,7 +96,7 @@ namespace l
rv = 0;
for(struct dirent *de = fs::readdir(dh); de && !rv; de = fs::readdir(dh))
{
namelen = l::dirent_alloc_namelen(de);
namelen = l::dirent_exact_namelen(de);
rv = names.put(de->d_name,namelen);
if(rv == 0)
@ -132,17 +124,12 @@ namespace l
namespace FUSE
{
int
readdir_plus(fuse_file_info *ffi_,
fuse_dirents_t *buf_)
readdir_plus_posix(const Branches &branches_,
const char *dirname_,
const uint64_t entry_timeout_,
const uint64_t attr_timeout_,
fuse_dirents_t *buf_)
{
DirInfo *di = reinterpret_cast<DirInfo*>(ffi_->fh);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::ro();
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard guard(&config.branches.lock);
return l::readdir_plus(config.branches,
di->fusepath.c_str(),
buf_);
return l::readdir_plus(branches_,dirname_,entry_timeout_,attr_timeout_,buf_);
}
}

View File

@ -0,0 +1,35 @@
/*
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "branch.hpp"
#include <fuse.h>
#include <stdint.h>
namespace FUSE
{
int
readdir_plus_posix(const Branches &branches_,
const char *dirname_,
const uint64_t entry_timeout_,
const uint64_t attr_timeout_,
fuse_dirents_t *buf_);
}

View File

@ -16,8 +16,7 @@
#define _DEFAULT_SOURCE
#include "config.hpp"
#include "dirinfo.hpp"
#include "branch.hpp"
#include "errno.hpp"
#include "fs_base_closedir.hpp"
#include "fs_base_dirfd.hpp"
@ -28,8 +27,6 @@
#include "fs_inode.hpp"
#include "fs_path.hpp"
#include "hashset.hpp"
#include "rwlock.hpp"
#include "ugid.hpp"
#include <fuse.h>
#include <fuse_dirents.h>
@ -57,13 +54,6 @@ namespace l
#endif
}
static
uint64_t
dirent_alloc_namelen(const struct dirent *d_)
{
return (dirent_exact_namelen(d_) + 1);
}
static
int
readdir(const Branches &branches_,
@ -95,7 +85,7 @@ namespace l
rv = 0;
for(struct dirent *de = fs::readdir(dh); de && !rv; de = fs::readdir(dh))
{
namelen = l::dirent_alloc_namelen(de);
namelen = l::dirent_exact_namelen(de);
rv = names.put(de->d_name,namelen);
if(rv == 0)
@ -118,17 +108,10 @@ namespace l
namespace FUSE
{
int
readdir(fuse_file_info *ffi_,
fuse_dirents_t *buf_)
readdir_posix(const Branches &branches_,
const char *dirname_,
fuse_dirents_t *buf_)
{
DirInfo *di = reinterpret_cast<DirInfo*>(ffi_->fh);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::ro();
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard guard(&config.branches.lock);
return l::readdir(config.branches,
di->fusepath.c_str(),
buf_);
return l::readdir(branches_,dirname_,buf_);
}
}

View File

@ -0,0 +1,33 @@
/*
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "branch.hpp"
#include <fuse.h>
#include <stdint.h>
namespace FUSE
{
int
readdir_posix(const Branches &branches,
const char *dirname,
fuse_dirents_t *buf);
}