From 5989d41a86ed5aed4afd42010538f291aaa160c5 Mon Sep 17 00:00:00 2001 From: Antonio SJ Musumeci Date: Sun, 2 Aug 2020 18:43:09 -0400 Subject: [PATCH] readdir: use getdents64 for compatibility with ARM64 --- libfuse/include/fuse_dirents.h | 18 +++++++++--------- libfuse/include/linux_dirent.h | 9 --------- libfuse/include/linux_dirent64.h | 12 ++++++++++++ libfuse/lib/fuse_dirents.c | 22 +++++++++++----------- src/fs_base_getdents.cpp | 2 +- src/fuse_readdir_linux.cpp | 15 ++++----------- src/fuse_readdir_plus_linux.cpp | 15 ++++----------- 7 files changed, 41 insertions(+), 52 deletions(-) delete mode 100644 libfuse/include/linux_dirent.h create mode 100644 libfuse/include/linux_dirent64.h diff --git a/libfuse/include/fuse_dirents.h b/libfuse/include/fuse_dirents.h index 8c8459bc..b26bc12d 100644 --- a/libfuse/include/fuse_dirents.h +++ b/libfuse/include/fuse_dirents.h @@ -26,7 +26,7 @@ extern "C" { #include "fuse_dirent.h" #include "fuse_direntplus.h" #include "fuse_entry.h" -#include "linux_dirent.h" +#include "linux_dirent64.h" #include #include @@ -65,14 +65,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_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); +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); void *fuse_dirents_find(fuse_dirents_t *d, const uint64_t ino); diff --git a/libfuse/include/linux_dirent.h b/libfuse/include/linux_dirent.h deleted file mode 100644 index 67b6b00d..00000000 --- a/libfuse/include/linux_dirent.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -struct linux_dirent -{ - unsigned long ino; - unsigned long off; - unsigned short reclen; - char name[]; -}; diff --git a/libfuse/include/linux_dirent64.h b/libfuse/include/linux_dirent64.h new file mode 100644 index 00000000..e8a9f78c --- /dev/null +++ b/libfuse/include/linux_dirent64.h @@ -0,0 +1,12 @@ +#pragma once + +#include + +struct linux_dirent64 +{ + uint64_t ino; + int64_t off; + uint16_t reclen; + uint8_t type; + char name[]; +}; diff --git a/libfuse/lib/fuse_dirents.c b/libfuse/lib/fuse_dirents.c index baf23282..3f265428 100644 --- a/libfuse/lib/fuse_dirents.c +++ b/libfuse/lib/fuse_dirents.c @@ -5,7 +5,7 @@ #include "fuse_direntplus.h" #include "fuse_dirents.h" #include "fuse_entry.h" -#include "linux_dirent.h" +#include "linux_dirent64.h" #include "stat_utils.h" #include @@ -299,9 +299,9 @@ fuse_dirents_add_plus(fuse_dirents_t *d_, } int -fuse_dirents_add_linux(fuse_dirents_t *d_, - const struct linux_dirent *dirent_, - const uint64_t namelen_) +fuse_dirents_add_linux(fuse_dirents_t *d_, + const struct linux_dirent64 *dirent_, + const uint64_t namelen_) { fuse_dirent_t *d; @@ -324,18 +324,18 @@ fuse_dirents_add_linux(fuse_dirents_t *d_, kv_push(uint32_t,d_->offs,d_->data_len); d->ino = dirent_->ino; d->namelen = namelen_; - d->type = *((char*)dirent_ + dirent_->reclen - 1); + d->type = dirent_->type; memcpy(d->name,dirent_->name,namelen_); return 0; } int -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_) +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_direntplus_t *d; @@ -358,7 +358,7 @@ fuse_dirents_add_linux_plus(fuse_dirents_t *d_, kv_push(uint32_t,d_->offs,d_->data_len); d->dirent.ino = dirent_->ino; d->dirent.namelen = namelen_; - d->dirent.type = *((char*)dirent_ + dirent_->reclen - 1); + d->dirent.type = dirent_->type; memcpy(d->dirent.name,dirent_->name,namelen_); d->entry = *entry_; diff --git a/src/fs_base_getdents.cpp b/src/fs_base_getdents.cpp index 1945d7c9..1805a78d 100644 --- a/src/fs_base_getdents.cpp +++ b/src/fs_base_getdents.cpp @@ -31,7 +31,7 @@ namespace fs unsigned int count_) { #if defined SYS_getdents64 - return ::syscall(SYS_getdents,fd_,dirp_,count_); + return ::syscall(SYS_getdents64,fd_,dirp_,count_); #else return (errno=ENOTSUP,-1); #endif diff --git a/src/fuse_readdir_linux.cpp b/src/fuse_readdir_linux.cpp index 1768369c..b88a80c4 100644 --- a/src/fuse_readdir_linux.cpp +++ b/src/fuse_readdir_linux.cpp @@ -24,7 +24,7 @@ #include "fs_inode.hpp" #include "fs_path.hpp" #include "hashset.hpp" -#include "linux_dirent.h" +#include "linux_dirent64.h" #include "mempools.hpp" #include @@ -40,13 +40,6 @@ using std::vector; namespace l { - static - char - denttype(struct linux_dirent *d_) - { - return *((char*)d_ + d_->reclen - 1); - } - static int close_free_ret_enomem(int fd_, @@ -70,7 +63,7 @@ namespace l string basepath; string fullpath; uint64_t namelen; - struct linux_dirent *d; + struct linux_dirent64 *d; buf = (char*)g_DENTS_BUF_POOL.alloc(); if(buf == NULL) @@ -101,7 +94,7 @@ namespace l for(int64_t pos = 0; pos < nread; pos += d->reclen) { - d = (struct linux_dirent*)(buf + pos); + d = (struct linux_dirent64*)(buf + pos); namelen = strlen(d->name); rv = names.put(d->name,namelen); @@ -111,7 +104,7 @@ namespace l fullpath = fs::path::make(dirname_,d->name); d->ino = fs::inode::calc(fullpath.c_str(), fullpath.size(), - DTTOIF(l::denttype(d)), + DTTOIF(d->type), dev, d->ino); diff --git a/src/fuse_readdir_plus_linux.cpp b/src/fuse_readdir_plus_linux.cpp index 8c973877..49103227 100644 --- a/src/fuse_readdir_plus_linux.cpp +++ b/src/fuse_readdir_plus_linux.cpp @@ -25,7 +25,7 @@ #include "fs_inode.hpp" #include "fs_path.hpp" #include "hashset.hpp" -#include "linux_dirent.h" +#include "linux_dirent64.h" #include "mempools.hpp" #include @@ -41,13 +41,6 @@ using std::vector; namespace l { - static - char - denttype(struct linux_dirent *d_) - { - return *((char*)d_ + d_->reclen - 1); - } - static int close_free_ret_enomem(int fd_, @@ -75,7 +68,7 @@ namespace l uint64_t namelen; struct stat st; fuse_entry_t entry; - struct linux_dirent *d; + struct linux_dirent64 *d; buf = (char*)g_DENTS_BUF_POOL.alloc(); @@ -110,7 +103,7 @@ namespace l for(int64_t pos = 0; pos < nread; pos += d->reclen) { - d = (struct linux_dirent*)(buf + pos); + d = (struct linux_dirent64*)(buf + pos); namelen = (strlen(d->name) + 1); rv = names.put(d->name,namelen); @@ -123,7 +116,7 @@ namespace l memset(&st,0,sizeof(st)); st.st_ino = d->ino; st.st_dev = dev; - st.st_mode = DTTOIF(l::denttype(d)); + st.st_mode = DTTOIF(d->type); } fullpath = fs::path::make(dirname_,d->name);