[GH-ISSUE #320] fsync does not update stat cache #167

Closed
opened 2026-03-04 01:42:48 +03:00 by kerem · 1 comment
Owner

Originally created by @mcellis33 on GitHub (Dec 18, 2015).
Original GitHub issue: https://github.com/s3fs-fuse/s3fs-fuse/issues/320

When I perform these operations on a file:

  1. open
  2. write (count > 0)
  3. fsync
  4. stat

stat returns st_size == 0 even though I wrote more than 0 bytes and synced them.

The offending call stack is

FUSE stat handler
s3fs_getattr
check_object_access
get_object_attribute
StatCache::getStatCacheData()->GetStat

GetStat encounters a stat cache hit, and the stat cache entry has st_size == 0.

s3fs_create creates the stat cache entry with st_size == 0. The root cause of the bug is that s3fs_fsync does not update the stat cache to reflect the new size.

Here is a C program to reproduce this. You will need to point name at your s3fs-fuse instance. The output should look like

/vagrant/testmount/testfile
stat size 0
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>

const char* test_content = "test-content";

int try(char* name) {
    int ret;
    int fd = open(name, O_RDWR|O_CREAT|O_EXCL, 0600);
    if (fd == -1) {
        ret = errno;
        perror("open");
        return ret;
    }

    // Write to file.
    ret = write(fd, test_content, 12);
    if (ret == -1) {
        ret = errno;
        perror("write");
        close(fd);
        return ret;
    }

    // Sync to ensure content is written.
    ret = fsync(fd);
    if (ret == -1) {
        ret = errno;
        perror("sync");
        close(fd);
        return ret;
    }

    // Check that stat is 12.
    struct stat st;
    ret = stat(name, &st);
    if (ret == -1) {
        ret = errno;
        perror("stat");
        return ret;
    }
    printf("stat size %ld\n", st.st_size);

    close(fd);

    return 0;
}

int main() {
    char* name = "/vagrant/testmount/testfile";
    printf("%s\n", name);
    return try(name);
}
Originally created by @mcellis33 on GitHub (Dec 18, 2015). Original GitHub issue: https://github.com/s3fs-fuse/s3fs-fuse/issues/320 When I perform these operations on a file: 1. open 2. write (count > 0) 3. fsync 4. stat `stat` returns `st_size == 0` even though I wrote more than 0 bytes and synced them. The offending call stack is ``` FUSE stat handler s3fs_getattr check_object_access get_object_attribute StatCache::getStatCacheData()->GetStat ``` `GetStat` encounters a stat cache hit, and the stat cache entry has `st_size == 0`. `s3fs_create` creates the stat cache entry with `st_size == 0`. The root cause of the bug is that `s3fs_fsync` does not update the stat cache to reflect the new size. Here is a C program to reproduce this. You will need to point `name` at your s3fs-fuse instance. The output should look like ``` /vagrant/testmount/testfile stat size 0 ``` ``` #include <fcntl.h> #include <string.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/stat.h> const char* test_content = "test-content"; int try(char* name) { int ret; int fd = open(name, O_RDWR|O_CREAT|O_EXCL, 0600); if (fd == -1) { ret = errno; perror("open"); return ret; } // Write to file. ret = write(fd, test_content, 12); if (ret == -1) { ret = errno; perror("write"); close(fd); return ret; } // Sync to ensure content is written. ret = fsync(fd); if (ret == -1) { ret = errno; perror("sync"); close(fd); return ret; } // Check that stat is 12. struct stat st; ret = stat(name, &st); if (ret == -1) { ret = errno; perror("stat"); return ret; } printf("stat size %ld\n", st.st_size); close(fd); return 0; } int main() { char* name = "/vagrant/testmount/testfile"; printf("%s\n", name); return try(name); } ```
kerem 2026-03-04 01:42:48 +03:00
  • closed this issue
  • added the
    bug
    label
Author
Owner

@ggtakec commented on GitHub (Dec 20, 2015):

@mcellis33 Thans for fixing this bug.

<!-- gh-comment-id:166069573 --> @ggtakec commented on GitHub (Dec 20, 2015): @mcellis33 Thans for fixing this bug.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/s3fs-fuse#167
No description provided.