From 67b48fcb3a49e26d23da32cdbd070916c8cdfaea Mon Sep 17 00:00:00 2001 From: Antonio SJ Musumeci Date: Thu, 15 Dec 2016 17:11:39 -0500 Subject: [PATCH] compute inode in readdir --- src/fs_base_dirfd.hpp | 36 ++++++++++++++++++++++++++++++++++ src/fs_devid.hpp | 45 +++++++++++++++++++++++++++++++++++++++++++ src/readdir.cpp | 23 ++++++++++++++++------ 3 files changed, 98 insertions(+), 6 deletions(-) create mode 100644 src/fs_base_dirfd.hpp create mode 100644 src/fs_devid.hpp diff --git a/src/fs_base_dirfd.hpp b/src/fs_base_dirfd.hpp new file mode 100644 index 00000000..06846fcf --- /dev/null +++ b/src/fs_base_dirfd.hpp @@ -0,0 +1,36 @@ +/* + ISC License + + Copyright (c) 2016, Antonio SJ Musumeci + + 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. +*/ + +#ifndef __FS_DIRFD_HPP__ +#define __FS_DIRFD_HPP__ + +#include +#include + +namespace fs +{ + static + inline + int + dirfd(DIR *dirp) + { + return ::dirfd(dirp); + } +} + +#endif diff --git a/src/fs_devid.hpp b/src/fs_devid.hpp new file mode 100644 index 00000000..961f040e --- /dev/null +++ b/src/fs_devid.hpp @@ -0,0 +1,45 @@ +/* + ISC License + + Copyright (c) 2016, Antonio SJ Musumeci + + 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. +*/ + +#ifndef __FS_DEVID_HPP__ +#define __FS_DEVID_HPP__ + +#include +#include +#include + +namespace fs +{ + static + inline + dev_t + devid(const int fd) + { + int rv; + struct stat st; + + rv = ::fstat(fd,&st); + if(rv == -1) + return -1; + + return st.st_dev; + } +} + +#endif + diff --git a/src/readdir.cpp b/src/readdir.cpp index f14b93b1..56d8e054 100644 --- a/src/readdir.cpp +++ b/src/readdir.cpp @@ -25,9 +25,11 @@ #include "config.hpp" #include "errno.hpp" #include "fs_base_closedir.hpp" +#include "fs_base_dirfd.hpp" #include "fs_base_opendir.hpp" #include "fs_base_readdir.hpp" #include "fs_base_stat.hpp" +#include "fs_devid.hpp" #include "fs_inode.hpp" #include "fs_path.hpp" #include "readdir.hpp" @@ -48,13 +50,14 @@ _readdir(const vector &srcmounts, void *buf, const fuse_fill_dir_t filler) { + StrSet names; string basepath; struct stat st = {0}; - StrSet names; - st.st_ino = fs::inode::MAGIC; for(size_t i = 0, ei = srcmounts.size(); i != ei; i++) { + int rv; + int dirfd; DIR *dh; fs::path::make(&srcmounts[i],dirname,basepath); @@ -63,18 +66,26 @@ _readdir(const vector &srcmounts, if(!dh) continue; - for(struct dirent *de = fs::readdir(dh); de != NULL; de = fs::readdir(dh)) - { - int rv; + dirfd = fs::dirfd(dh); + st.st_dev = fs::devid(dirfd); + if(st.st_dev == (dev_t)-1) + st.st_dev = i; + rv = 0; + for(struct dirent *de = fs::readdir(dh); de && !rv; de = fs::readdir(dh)) + { rv = names.put(de->d_name); if(rv == 0) continue; + st.st_ino = de->d_ino; st.st_mode = DTTOIF(de->d_type); + + fs::inode::recompute(st); + rv = filler(buf,de->d_name,&st,NO_OFFSET); if(rv) - return -ENOMEM; + return (fs::closedir(dh),-ENOMEM); } fs::closedir(dh);