Verified Commit 4bf6860f authored by Marc Vef's avatar Marc Vef
Browse files

Added interception of statfs() and fstatfs() calls.

ADA-FS's statfs will fill the struct mostly with rough estimations.
It is not supposed to return accurate data but "some" data for applications to work
parent 68fa711b
Loading
Loading
Loading
Loading
+25 −0
Original line number Diff line number Diff line
@@ -3,6 +3,29 @@

#include <preload/preload_util.hpp>

/*
 * See include/linux/statfs.h (not includable)
 *
 * Definitions for the flag in f_flag.
 *
 * Generally these flags are equivalent to the MS_ flags used in the mount
 * ABI.  The exception is ST_VALID which has the same value as MS_REMOUNT
 * which doesn't make any sense for statfs.
 */
#define ST_RDONLY    0x0001    /* mount read-only */
#define ST_NOSUID    0x0002    /* ignore suid and sgid bits */
#define ST_NODEV    0x0004    /* disallow access to device special files */
#define ST_NOEXEC    0x0008    /* disallow program execution */
#define ST_SYNCHRONOUS    0x0010    /* writes are synced at once */
#define ST_VALID    0x0020    /* f_flags support is implemented */
#define ST_MANDLOCK    0x0040    /* allow mandatory locks on an FS */
/* 0x0080 used for ST_WRITE in glibc */
/* 0x0100 used for ST_APPEND in glibc */
/* 0x0200 used for ST_IMMUTABLE in glibc */
#define ST_NOATIME    0x0400    /* do not update access times */
#define ST_NODIRATIME    0x0800    /* do not update directory access times */
#define ST_RELATIME    0x1000    /* update atime relative to mtime/ctime */

int adafs_open(const std::string& path, mode_t mode, int flags);

int adafs_mk_node(const std::string& path, mode_t mode);
@@ -15,6 +38,8 @@ int adafs_stat(const std::string& path, struct stat* buf);

int adafs_stat64(const std::string& path, struct stat64* buf);

int adafs_statfs(const std::string& path, struct statfs* adafs_buf, struct statfs& realfs_buf);

off64_t adafs_lseek(int fd, off64_t offset, int whence);

off64_t adafs_lseek(std::shared_ptr<OpenFile> adafs_fd, off64_t offset, int whence);
+3 −0
Original line number Diff line number Diff line
@@ -37,6 +37,9 @@ extern void* libc___fxstat64;
extern void* libc___lxstat;
extern void* libc___lxstat64;

extern void* libc_statfs;
extern void* libc_fstatfs;

extern void* libc_puts;

extern void* libc_write;
+2 −0
Original line number Diff line number Diff line
@@ -167,6 +167,8 @@ int main(int argc, const char* argv[]) {
    bfs::create_directories(ADAFS_DATA->inode_path());
    bfs::create_directories(ADAFS_DATA->chunk_path());
    bfs::create_directories(ADAFS_DATA->mgmt_path());
    // Create mountdir. We use this dir to get some information on the underlying fs with statfs in adafs_statfs
    bfs::create_directories(ADAFS_DATA->mountdir());

    if (init_environment()) {
        signal(SIGINT, shutdown_handler);
+1 −0
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ void destroy_enviroment() {
    cout << "\n####################\n\nMargo RPC server stats: " << endl;
    margo_diag_dump(RPC_DATA->server_rpc_mid(), "-", 0);
#endif
    bfs::remove_all(ADAFS_DATA->mountdir());
    if (!deregister_daemon_proc())
        ADAFS_DATA->spdlogger()->warn("{}() Unable to clean up auxiliary files", __func__);
    else
+36 −2
Original line number Diff line number Diff line
@@ -64,7 +64,7 @@ int adafs_access(const std::string& path, const int mask) {
}

// TODO combine adafs_stat and adafs_stat64
int adafs_stat(const std::string& path, struct stat* buf) {
int adafs_stat(const string& path, struct stat* buf) {
    init_ld_env_if_needed();
    string attr = ""s;
    auto err = rpc_send_stat(path, attr);
@@ -73,7 +73,7 @@ int adafs_stat(const std::string& path, struct stat* buf) {
    return err;
}

int adafs_stat64(const std::string& path, struct stat64* buf) {
int adafs_stat64(const string& path, struct stat64* buf) {
    init_ld_env_if_needed();
    string attr = ""s;
    auto err = rpc_send_stat(path, attr);
@@ -82,6 +82,40 @@ int adafs_stat64(const std::string& path, struct stat64* buf) {
    return err;
}

int adafs_statfs(const string& path, struct statfs* adafs_buf, struct statfs& realfs_buf) {
    // Check that file path exists
    auto ret = rpc_send_access(path, F_OK);
    // Valid fs error
    if (ret > 0) {
        errno = ret;
        return -1;
    }
    // RPC error (errno has been set)
    if (ret < 0)
        return -1;

    // fs object exists. Let's make up some fs values
    adafs_buf->f_type = 0; // fs is not know to VFS. Therefore, no valid specifier possible
    adafs_buf->f_bsize = static_cast<int>(CHUNKSIZE);
    // some rough estimations
    adafs_buf->f_blocks = realfs_buf.f_blocks * fs_config->host_size;
    adafs_buf->f_bfree = realfs_buf.f_bfree * fs_config->host_size;
    adafs_buf->f_bavail = realfs_buf.f_bavail * fs_config->host_size;
    adafs_buf->f_files = realfs_buf.f_files * fs_config->host_size;
    adafs_buf->f_ffree = realfs_buf.f_ffree * fs_config->host_size;
    adafs_buf->f_fsid = realfs_buf.f_fsid; // "Nobody knows what f_fsid is supposed to contain"
    adafs_buf->f_namelen = realfs_buf.f_namelen;
    adafs_buf->f_frsize = realfs_buf.f_frsize;
    adafs_buf->f_spare[0] = 0;
    adafs_buf->f_spare[1] = 0;
    adafs_buf->f_spare[2] = 0;
    adafs_buf->f_spare[3] = 0;
    adafs_buf->f_flags = ST_NOATIME | ST_NOSUID | ST_NODEV | ST_SYNCHRONOUS;
    if (!fs_config->atime_state)
        adafs_buf->f_flags = adafs_buf->f_flags | ST_NOATIME | ST_NODIRATIME;
    return 0;
}

off64_t adafs_lseek(int fd, off64_t offset, int whence) {
    init_ld_env_if_needed();
    return adafs_lseek(file_map.get(fd), offset, whence);
Loading