summaryrefslogtreecommitdiff
path: root/src/basic/fd-util.c
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2023-04-10 10:04:25 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2023-04-10 10:04:46 +0900
commitb4cb4c5cc6b074f79e317c96930109e6efb8de25 (patch)
treeacf336b705be5d1ce77a68ba253a528eb7c6cdb2 /src/basic/fd-util.c
parenta6ef5ef70726c77e621341b4de12413e1864e934 (diff)
downloadsystemd-b4cb4c5cc6b074f79e317c96930109e6efb8de25.tar.gz
fd-util: slightly optimize dir_fd_is_root()
When STATX_MNT_ID is not supported, we need to manually obtain mount id. Let's compare inodes earlier.
Diffstat (limited to 'src/basic/fd-util.c')
-rw-r--r--src/basic/fd-util.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/src/basic/fd-util.c b/src/basic/fd-util.c
index 3cc4f44bcd..7125e28e1b 100644
--- a/src/basic/fd-util.c
+++ b/src/basic/fd-util.c
@@ -903,6 +903,14 @@ int dir_fd_is_root(int dir_fd) {
if (r < 0)
return r;
+ r = statx_fallback(dir_fd, "..", 0, STATX_TYPE|STATX_INO|STATX_MNT_ID, &pst.sx);
+ if (r < 0)
+ return r;
+
+ /* First, compare inode. If these are different, the fd does not point to the root directory "/". */
+ if (!statx_inode_same(&st.sx, &pst.sx))
+ return false;
+
if (!FLAGS_SET(st.nsx.stx_mask, STATX_MNT_ID)) {
int mntid;
@@ -915,10 +923,6 @@ int dir_fd_is_root(int dir_fd) {
st.nsx.stx_mask |= STATX_MNT_ID;
}
- r = statx_fallback(dir_fd, "..", 0, STATX_TYPE|STATX_INO|STATX_MNT_ID, &pst.sx);
- if (r < 0)
- return r;
-
if (!FLAGS_SET(pst.nsx.stx_mask, STATX_MNT_ID)) {
int mntid;
@@ -931,14 +935,14 @@ int dir_fd_is_root(int dir_fd) {
pst.nsx.stx_mask |= STATX_MNT_ID;
}
- /* If the parent directory is the same inode, the fd points to the root directory "/". We also check
- * that the mount ids are the same. Otherwise, a construct like the following could be used to trick
- * us:
+ /* Even if the parent directory has the same inode, the fd may not point to the root directory "/",
+ * and we also need to check that the mount ids are the same. Otherwise, a construct like the
+ * following could be used to trick us:
*
* $ mkdir /tmp/x /tmp/x/y
* $ mount --bind /tmp/x /tmp/x/y
*/
- return statx_inode_same(&st.sx, &pst.sx) && statx_mount_same(&st.nsx, &pst.nsx);
+ return statx_mount_same(&st.nsx, &pst.nsx);
}
const char *accmode_to_string(int flags) {