mirror of
https://git.sr.ht/~cismonx/bookmarkfs
synced 2025-07-26 19:18:52 +00:00
fs_ops: fix mtime update of regular files
Explicit mtime update (e.g., via futimens(2)) should override file handle mtime.
This commit is contained in:
parent
72b9e200d9
commit
5082e7c67c
1 changed files with 27 additions and 14 deletions
41
src/fs_ops.c
41
src/fs_ops.c
|
@ -68,6 +68,8 @@
|
||||||
|
|
||||||
#define FH_FLAG_DIRTY ( 1u << 0 )
|
#define FH_FLAG_DIRTY ( 1u << 0 )
|
||||||
#define FH_FLAG_FSCK ( 1u << 1 )
|
#define FH_FLAG_FSCK ( 1u << 1 )
|
||||||
|
#define FH_FLAG_ISDIR ( 1u << 2 )
|
||||||
|
#define FH_FLAG_MTIME ( 1u << 3 )
|
||||||
|
|
||||||
#define SUBSYS_ID_BITS ( 64 - BOOKMARKFS_BOOKMARK_TYPE_BITS )
|
#define SUBSYS_ID_BITS ( 64 - BOOKMARKFS_BOOKMARK_TYPE_BITS )
|
||||||
#define SUBSYS_ID_MASK ( ((fuse_ino_t)1 << SUBSYS_ID_BITS) - 1 )
|
#define SUBSYS_ID_MASK ( ((fuse_ino_t)1 << SUBSYS_ID_BITS) - 1 )
|
||||||
|
@ -313,6 +315,7 @@ inval_dir (
|
||||||
if (ctx.flags.readonly || !ctx.flags.exclusive) {
|
if (ctx.flags.readonly || !ctx.flags.exclusive) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
debug_assert(fh->flags & FH_FLAG_ISDIR);
|
||||||
if (fh->flags & FH_FLAG_DIRTY) {
|
if (fh->flags & FH_FLAG_DIRTY) {
|
||||||
if (0 != inval_inode(ino)) {
|
if (0 != inval_inode(ino)) {
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
@ -436,6 +439,7 @@ bm_do_write (
|
||||||
if (fh == NULL || !(fh->flags & FH_FLAG_DIRTY)) {
|
if (fh == NULL || !(fh->flags & FH_FLAG_DIRTY)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
debug_assert(!(fh->flags & FH_FLAG_ISDIR));
|
||||||
|
|
||||||
size_t data_len = fh->data_len;
|
size_t data_len = fh->data_len;
|
||||||
if (ctx.flags.eol && fh->buf[data_len - 1] == '\n') {
|
if (ctx.flags.eol && fh->buf[data_len - 1] == '\n') {
|
||||||
|
@ -447,16 +451,17 @@ bm_do_write (
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct timespec const times[2] = {
|
if (fh->flags & FH_FLAG_MTIME) {
|
||||||
[1] = fh->mtime,
|
struct timespec const times[2] = {
|
||||||
};
|
[1] = fh->mtime,
|
||||||
uint32_t set_flags = BOOKMARK_FLAG(SET_MTIME);
|
};
|
||||||
status = BACKEND_CALL(bookmark_set, id, NULL, set_flags, times, 0);
|
uint32_t set_flags = BOOKMARK_FLAG(SET_MTIME);
|
||||||
if (status < 0) {
|
status = BACKEND_CALL(bookmark_set, id, NULL, set_flags, times, 0);
|
||||||
return status;
|
if (status < 0) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
fh->flags &= ~(FH_FLAG_DIRTY | FH_FLAG_MTIME);
|
||||||
fh->flags &= ~FH_FLAG_DIRTY;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -530,7 +535,7 @@ bm_fillstat (
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
struct fs_file_handle *fh = bm_fh_get(ino, NULL, NULL);
|
struct fs_file_handle *fh = bm_fh_get(ino, NULL, NULL);
|
||||||
if (fh == NULL || !(fh->flags & FH_FLAG_DIRTY)) {
|
if (fh == NULL || !(fh->flags & FH_FLAG_MTIME)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// If file content changes locally, remote mtime no longer matters,
|
// If file content changes locally, remote mtime no longer matters,
|
||||||
|
@ -803,7 +808,7 @@ bm_open (
|
||||||
if ((flags & O_ACCMODE) != O_RDONLY) {
|
if ((flags & O_ACCMODE) != O_RDONLY) {
|
||||||
fh->data_len = 0;
|
fh->data_len = 0;
|
||||||
xgetrealtime(&fh->mtime);
|
xgetrealtime(&fh->mtime);
|
||||||
fh->flags |= FH_FLAG_DIRTY;
|
fh->flags |= (FH_FLAG_DIRTY | FH_FLAG_MTIME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -836,7 +841,9 @@ bm_opendir (
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
bm_fh_new(ino);
|
struct fs_file_handle *fh = bm_fh_new(ino);
|
||||||
|
fh->flags |= FH_FLAG_ISDIR;
|
||||||
|
|
||||||
// Do not cache tag and keyword dents, since a bookmark
|
// Do not cache tag and keyword dents, since a bookmark
|
||||||
// delete or rename may have a side effect of changing them.
|
// delete or rename may have a side effect of changing them.
|
||||||
switch (flags & BOOKMARKFS_BOOKMARK_TYPE_MASK) {
|
switch (flags & BOOKMARKFS_BOOKMARK_TYPE_MASK) {
|
||||||
|
@ -1076,6 +1083,7 @@ bm_setattr (
|
||||||
|
|
||||||
struct fs_file_handle *fh = uint2ptr(fi->fh);
|
struct fs_file_handle *fh = uint2ptr(fi->fh);
|
||||||
debug_assert(fh == bm_fh_get(ino, NULL, NULL));
|
debug_assert(fh == bm_fh_get(ino, NULL, NULL));
|
||||||
|
debug_assert(!(fh->flags & FH_FLAG_ISDIR));
|
||||||
|
|
||||||
size_t new_len = stat_buf->st_size;
|
size_t new_len = stat_buf->st_size;
|
||||||
if (new_len > ctx.file_max) {
|
if (new_len > ctx.file_max) {
|
||||||
|
@ -1090,7 +1098,7 @@ bm_setattr (
|
||||||
}
|
}
|
||||||
fh->data_len = new_len;
|
fh->data_len = new_len;
|
||||||
xgetrealtime(&fh->mtime);
|
xgetrealtime(&fh->mtime);
|
||||||
fh->flags |= FH_FLAG_DIRTY;
|
fh->flags |= (FH_FLAG_DIRTY | FH_FLAG_MTIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mask & (TO_SET(ATIME, MTIME))) {
|
if (mask & (TO_SET(ATIME, MTIME))) {
|
||||||
|
@ -1119,6 +1127,11 @@ bm_setattr (
|
||||||
times[1] = stat_buf->st_mtim;
|
times[1] = stat_buf->st_mtim;
|
||||||
}
|
}
|
||||||
set_flags |= BOOKMARK_FLAG(SET_MTIME);
|
set_flags |= BOOKMARK_FLAG(SET_MTIME);
|
||||||
|
|
||||||
|
struct fs_file_handle *fh = bm_fh_get(ino, NULL, NULL);
|
||||||
|
if (fh != NULL && !(fh->flags & FH_FLAG_ISDIR)) {
|
||||||
|
fh->flags &= ~FH_FLAG_MTIME;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
int status = BACKEND_CALL(bookmark_set, INODE_SUBSYS_ID(ino), NULL,
|
int status = BACKEND_CALL(bookmark_set, INODE_SUBSYS_ID(ino), NULL,
|
||||||
set_flags, times, 0);
|
set_flags, times, 0);
|
||||||
|
@ -1199,7 +1212,7 @@ bm_write (
|
||||||
xgetrealtime(&fh->mtime);
|
xgetrealtime(&fh->mtime);
|
||||||
// We're tempted to free the cookie here, however,
|
// We're tempted to free the cookie here, however,
|
||||||
// that would make a read following a writeback always realloc the buffer.
|
// that would make a read following a writeback always realloc the buffer.
|
||||||
fh->flags |= FH_FLAG_DIRTY;
|
fh->flags |= (FH_FLAG_DIRTY | FH_FLAG_MTIME);
|
||||||
|
|
||||||
return send_reply(write, req, req_buf_len);
|
return send_reply(write, req, req_buf_len);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue