From 8c76b852717fc35fc07b4805239cf7b51f3d39d9 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Wed, 16 Jul 2025 13:52:07 +0200 Subject: [PATCH] libmount: add mnt_fs_is_{moved,attached,detached} functions Let's use these simple functions to report what the last operation or status detected by the library means to the filesystem. It will be used by the fanotify monitor as well. Signed-off-by: Karel Zak --- libmount/docs/libmount-sections.txt | 3 ++ libmount/src/context_umount.c | 2 ++ libmount/src/fs.c | 45 +++++++++++++++++++++++++++++ libmount/src/hook_mount.c | 9 ++++++ libmount/src/hook_mount_legacy.c | 8 +++++ libmount/src/libmount.h.in | 4 +++ libmount/src/libmount.sym | 3 ++ libmount/src/mountP.h | 20 +++++++++++++ libmount/src/tab_parse.c | 5 ++-- 9 files changed, 97 insertions(+), 2 deletions(-) diff --git a/libmount/docs/libmount-sections.txt b/libmount/docs/libmount-sections.txt index e791415d9..95ad55fe5 100644 --- a/libmount/docs/libmount-sections.txt +++ b/libmount/docs/libmount-sections.txt @@ -256,7 +256,10 @@ mnt_fs_get_userdata mnt_fs_get_user_options mnt_fs_get_vfs_options mnt_fs_get_vfs_options_all +mnt_fs_is_attached +mnt_fs_is_detached mnt_fs_is_kernel +mnt_fs_is_moved mnt_fs_is_netfs mnt_fs_is_pseudofs mnt_fs_is_regularfs diff --git a/libmount/src/context_umount.c b/libmount/src/context_umount.c index 27319f77c..8fbd662ab 100644 --- a/libmount/src/context_umount.c +++ b/libmount/src/context_umount.c @@ -934,6 +934,7 @@ static int do_umount(struct libmnt_context *cxt) } cxt->syscall_status = 0; DBG(CXT, ul_debugobj(cxt, "read-only re-mount(2) success")); + mnt_fs_mark_attached(cxt->fs); return 0; } @@ -944,6 +945,7 @@ static int do_umount(struct libmnt_context *cxt) } cxt->syscall_status = 0; + mnt_fs_mark_detached(cxt->fs); DBG(CXT, ul_debugobj(cxt, "umount(2) success")); return 0; } diff --git a/libmount/src/fs.c b/libmount/src/fs.c index 64c7ee865..6147d1f53 100644 --- a/libmount/src/fs.c +++ b/libmount/src/fs.c @@ -706,6 +706,51 @@ int mnt_fs_is_kernel(struct libmnt_fs *fs) return mnt_fs_get_flags(fs) & MNT_FS_KERNEL ? 1 : 0; } +/** + * mnt_fs_is_moved: + * @fs: filesystem + * + * The move/attach/detach status depends on how @fs has been used by the library. + * The status is not set when working with fstab, etc. + * + * Returns: 1 if the filesystem has been moved. + */ +int mnt_fs_is_moved(struct libmnt_fs *fs) +{ + return fs->flags & MNT_FS_STATUS_ATTACH && + fs->flags & MNT_FS_STATUS_DETACH ? 1 : 0; +} + +/** + * mnt_fs_is_attached: + * @fs: filesystem + * + * The move/attach/detach status depends on how @fs has been used by the library. + * The status is not set when working with fstab, etc. + * + * Returns: 1 if the filesystem has been attached. + */ +int mnt_fs_is_attached(struct libmnt_fs *fs) +{ + return fs->flags & MNT_FS_STATUS_ATTACH + && !(fs->flags & MNT_FS_STATUS_DETACH) ? 1 : 0; +} + +/** + * mnt_fs_is_detached: + * @fs: filesystem + * + * The move/attach/detach status depends on how @fs has been used by the library. + * The status is not set when working with fstab, etc. + * + * Returns: 1 if the filesystem has been dettached. + */ +int mnt_fs_is_detached(struct libmnt_fs *fs) +{ + return fs->flags & MNT_FS_STATUS_DETACH && + !(fs->flags & MNT_FS_STATUS_ATTACH) ? 1 : 0; +} + /** * mnt_fs_is_swaparea: * @fs: filesystem diff --git a/libmount/src/hook_mount.c b/libmount/src/hook_mount.c index b545d2441..e1c67990e 100644 --- a/libmount/src/hook_mount.c +++ b/libmount/src/hook_mount.c @@ -545,6 +545,15 @@ static int hook_attach_target(struct libmnt_context *cxt, rc = move_mount(api->fd_tree, "", AT_FDCWD, target, MOVE_MOUNT_F_EMPTY_PATH); hookset_set_syscall_status(cxt, "move_mount", rc == 0); + if (rc == 0) { + struct libmnt_optlist *ol = mnt_context_get_optlist(cxt); + + if (ol && mnt_optlist_is_move(ol)) + mnt_fs_mark_moved(cxt->fs); + else + mnt_fs_mark_attached(cxt->fs); + } + return rc == 0 ? 0 : -errno; } diff --git a/libmount/src/hook_mount_legacy.c b/libmount/src/hook_mount_legacy.c index 18b7a0066..cfdd7af2b 100644 --- a/libmount/src/hook_mount_legacy.c +++ b/libmount/src/hook_mount_legacy.c @@ -158,6 +158,9 @@ static int hook_bindremount(struct libmnt_context *cxt, if (rc) DBG(HOOK, ul_debugobj(hs, " mount(2) failed" " [rc=%d errno=%d %m]", rc, errno)); + else + mnt_fs_mark_attached(cxt->fs); + return rc; } @@ -243,6 +246,11 @@ static int hook_mount(struct libmnt_context *cxt, return rc; } + if (mnt_optlist_is_move(ol)) + mnt_fs_mark_moved(cxt->fs); + else + mnt_fs_mark_attached(cxt->fs); + cxt->syscall_status = 0; return rc; } diff --git a/libmount/src/libmount.h.in b/libmount/src/libmount.h.in index 50e865899..23cf0a4fd 100644 --- a/libmount/src/libmount.h.in +++ b/libmount/src/libmount.h.in @@ -577,6 +577,10 @@ extern int mnt_fs_is_netfs(struct libmnt_fs *fs); extern int mnt_fs_is_pseudofs(struct libmnt_fs *fs); extern int mnt_fs_is_regularfs(struct libmnt_fs *fs); +extern int mnt_fs_is_moved(struct libmnt_fs *fs); +extern int mnt_fs_is_attached(struct libmnt_fs *fs); +extern int mnt_fs_is_detached(struct libmnt_fs *fs); + extern void mnt_free_mntent(struct mntent *mnt); extern int mnt_fs_to_mntent(struct libmnt_fs *fs, struct mntent **mnt); diff --git a/libmount/src/libmount.sym b/libmount/src/libmount.sym index f8fdd0ef6..cd3c5fb86 100644 --- a/libmount/src/libmount.sym +++ b/libmount/src/libmount.sym @@ -413,4 +413,7 @@ MOUNT_2_42 { mnt_context_enable_exclusive; mnt_context_is_exclusive; mnt_monitor_event_next_fs; + mnt_fs_is_moved; + mnt_fs_is_attached; + mnt_fs_is_detached; } MOUNT_2_41; diff --git a/libmount/src/mountP.h b/libmount/src/mountP.h index 7c504f95c..8dc31acad 100644 --- a/libmount/src/mountP.h +++ b/libmount/src/mountP.h @@ -286,6 +286,26 @@ struct libmnt_fs { #define MNT_FS_KERNEL (1 << 4) /* data from /proc/{mounts,self/mountinfo} */ #define MNT_FS_MERGED (1 << 5) /* already merged data from /run/mount/utab */ +#define MNT_FS_STATUS_ATTACH (1 << 6) +#define MNT_FS_STATUS_DETACH (1 << 7) + +static inline void mnt_fs_mark_attached(struct libmnt_fs *fs) +{ + fs->flags &= ~MNT_FS_STATUS_DETACH; + fs->flags |= MNT_FS_STATUS_ATTACH; +} + +static inline void mnt_fs_mark_detached(struct libmnt_fs *fs) +{ + fs->flags &= ~MNT_FS_STATUS_ATTACH; + fs->flags |= MNT_FS_STATUS_DETACH; +} + +static inline void mnt_fs_mark_moved(struct libmnt_fs *fs) +{ + fs->flags |= MNT_FS_STATUS_ATTACH | MNT_FS_STATUS_DETACH; +} + #ifdef HAVE_STATMOUNT_API # define mnt_fs_try_statmount(FS, MEMBER, FLAGS) __extension__ ({ \ if (!(FS)->MEMBER \ diff --git a/libmount/src/tab_parse.c b/libmount/src/tab_parse.c index 3dd853880..bd15ad909 100644 --- a/libmount/src/tab_parse.c +++ b/libmount/src/tab_parse.c @@ -188,6 +188,7 @@ static int mnt_parse_mountinfo_line(struct libmnt_fs *fs, const char *s) char *p; fs->flags |= MNT_FS_KERNEL; + mnt_fs_mark_attached(fs); /* (1) id */ s = next_s32(s, &fs->id, &rc); @@ -755,9 +756,9 @@ int mnt_table_parse_stream(struct libmnt_table *tb, FILE *f, const char *filenam * parser sets the flag properly */ if (tb->fmt == MNT_FMT_SWAPS) - flags = MNT_FS_SWAP; + flags = MNT_FS_SWAP | MNT_FS_STATUS_ATTACH; else if (filename && strcmp(filename, _PATH_PROC_MOUNTS) == 0) - flags = MNT_FS_KERNEL; + flags = MNT_FS_KERNEL | MNT_FS_STATUS_ATTACH; do { struct libmnt_fs *fs; -- 2.47.3