]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
xfs: move dirent update hooks to xfs_dir2.c
authorDarrick J. Wong <djwong@kernel.org>
Tue, 2 Jul 2024 18:22:47 +0000 (11:22 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Tue, 2 Jul 2024 18:37:00 +0000 (11:37 -0700)
Move the directory entry update hook code to xfs_dir2 so that it is
mostly consolidated with the higher level directory functions.  Retain
the exports so that online fsck can still send notifications through the
hooks.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
fs/xfs/libxfs/xfs_dir2.c
fs/xfs/libxfs/xfs_dir2.h
fs/xfs/scrub/common.c
fs/xfs/xfs_inode.c
fs/xfs/xfs_inode.h
fs/xfs/xfs_symlink.c

index 34b63ba2e4f71e642a51fc176bb48711d42ae424..202468223bf9437a61a43472ca27f0fc6a9ba975 100644 (file)
@@ -762,6 +762,81 @@ xfs_dir2_compname(
        return xfs_da_compname(args, name, len);
 }
 
+#ifdef CONFIG_XFS_LIVE_HOOKS
+/*
+ * Use a static key here to reduce the overhead of directory live update hooks.
+ * If the compiler supports jump labels, the static branch will be replaced by
+ * a nop sled when there are no hook users.  Online fsck is currently the only
+ * caller, so this is a reasonable tradeoff.
+ *
+ * Note: Patching the kernel code requires taking the cpu hotplug lock.  Other
+ * parts of the kernel allocate memory with that lock held, which means that
+ * XFS callers cannot hold any locks that might be used by memory reclaim or
+ * writeback when calling the static_branch_{inc,dec} functions.
+ */
+DEFINE_STATIC_XFS_HOOK_SWITCH(xfs_dir_hooks_switch);
+
+void
+xfs_dir_hook_disable(void)
+{
+       xfs_hooks_switch_off(&xfs_dir_hooks_switch);
+}
+
+void
+xfs_dir_hook_enable(void)
+{
+       xfs_hooks_switch_on(&xfs_dir_hooks_switch);
+}
+
+/* Call hooks for a directory update relating to a child dirent update. */
+inline void
+xfs_dir_update_hook(
+       struct xfs_inode                *dp,
+       struct xfs_inode                *ip,
+       int                             delta,
+       const struct xfs_name           *name)
+{
+       if (xfs_hooks_switched_on(&xfs_dir_hooks_switch)) {
+               struct xfs_dir_update_params    p = {
+                       .dp             = dp,
+                       .ip             = ip,
+                       .delta          = delta,
+                       .name           = name,
+               };
+               struct xfs_mount        *mp = ip->i_mount;
+
+               xfs_hooks_call(&mp->m_dir_update_hooks, 0, &p);
+       }
+}
+
+/* Call the specified function during a directory update. */
+int
+xfs_dir_hook_add(
+       struct xfs_mount        *mp,
+       struct xfs_dir_hook     *hook)
+{
+       return xfs_hooks_add(&mp->m_dir_update_hooks, &hook->dirent_hook);
+}
+
+/* Stop calling the specified function during a directory update. */
+void
+xfs_dir_hook_del(
+       struct xfs_mount        *mp,
+       struct xfs_dir_hook     *hook)
+{
+       xfs_hooks_del(&mp->m_dir_update_hooks, &hook->dirent_hook);
+}
+
+/* Configure directory update hook functions. */
+void
+xfs_dir_hook_setup(
+       struct xfs_dir_hook     *hook,
+       notifier_fn_t           mod_fn)
+{
+       xfs_hook_setup(&hook->dirent_hook, mod_fn);
+}
+#endif /* CONFIG_XFS_LIVE_HOOKS */
+
 /*
  * Given a directory @dp, a newly allocated inode @ip, and a @name, link @ip
  * into @dp under the given @name.  If @ip is a directory, it will be
@@ -809,6 +884,7 @@ xfs_dir_create_child(
                        return error;
        }
 
+       xfs_dir_update_hook(dp, ip, 1, name);
        return 0;
 }
 
@@ -873,6 +949,7 @@ xfs_dir_add_child(
                        return error;
        }
 
+       xfs_dir_update_hook(dp, ip, 1, name);
        return 0;
 }
 
@@ -954,6 +1031,7 @@ xfs_dir_remove_child(
                        return error;
        }
 
+       xfs_dir_update_hook(dp, ip, -1, name);
        return 0;
 }
 
@@ -1079,6 +1157,18 @@ xfs_dir_exchange_children(
                        return error;
        }
 
+       /*
+        * Inform our hook clients that we've finished an exchange operation as
+        * follows: removed the source and target files from their directories;
+        * added the target to the source directory; and added the source to
+        * the target directory.  All inodes are locked, so it's ok to model a
+        * rename this way so long as we say we deleted entries before we add
+        * new ones.
+        */
+       xfs_dir_update_hook(dp1, ip1, -1, name1);
+       xfs_dir_update_hook(dp2, ip2, -1, name2);
+       xfs_dir_update_hook(dp1, ip2, 1, name1);
+       xfs_dir_update_hook(dp2, ip1, 1, name2);
        return 0;
 }
 
@@ -1305,5 +1395,19 @@ xfs_dir_rename_children(
                        return error;
        }
 
+       /*
+        * Inform our hook clients that we've finished a rename operation as
+        * follows: removed the source and target files from their directories;
+        * that we've added the source to the target directory; and finally
+        * that we've added the whiteout, if there was one.  All inodes are
+        * locked, so it's ok to model a rename this way so long as we say we
+        * deleted entries before we add new ones.
+        */
+       if (target_ip)
+               xfs_dir_update_hook(target_dp, target_ip, -1, target_name);
+       xfs_dir_update_hook(src_dp, src_ip, -1, src_name);
+       xfs_dir_update_hook(target_dp, src_ip, 1, target_name);
+       if (du_wip->ip)
+               xfs_dir_update_hook(src_dp, du_wip->ip, 1, src_name);
        return 0;
 }
index df6d4bbe3d6f960c3f0721752847f73a5cdf7df7..576068ed81fac275feb60eaa67a4cd2d45cb46ae 100644 (file)
@@ -309,6 +309,31 @@ static inline unsigned char xfs_ascii_ci_xfrm(unsigned char c)
        return c;
 }
 
+struct xfs_dir_update_params {
+       const struct xfs_inode  *dp;
+       const struct xfs_inode  *ip;
+       const struct xfs_name   *name;
+       int                     delta;
+};
+
+#ifdef CONFIG_XFS_LIVE_HOOKS
+void xfs_dir_update_hook(struct xfs_inode *dp, struct xfs_inode *ip,
+               int delta, const struct xfs_name *name);
+
+struct xfs_dir_hook {
+       struct xfs_hook         dirent_hook;
+};
+
+void xfs_dir_hook_disable(void);
+void xfs_dir_hook_enable(void);
+
+int xfs_dir_hook_add(struct xfs_mount *mp, struct xfs_dir_hook *hook);
+void xfs_dir_hook_del(struct xfs_mount *mp, struct xfs_dir_hook *hook);
+void xfs_dir_hook_setup(struct xfs_dir_hook *hook, notifier_fn_t mod_fn);
+#else
+# define xfs_dir_update_hook(dp, ip, delta, name)      ((void)0)
+#endif /* CONFIG_XFS_LIVE_HOOKS */
+
 struct xfs_parent_args;
 
 struct xfs_dir_update {
index 1ad8ec63a7f443e313a3a8a06390fa356285a916..22f5f1a9d3f09b133524f1dc10deea4d91ea565b 100644 (file)
@@ -26,6 +26,7 @@
 #include "xfs_da_format.h"
 #include "xfs_da_btree.h"
 #include "xfs_dir2_priv.h"
+#include "xfs_dir2.h"
 #include "xfs_attr.h"
 #include "xfs_reflink.h"
 #include "xfs_ag.h"
index 3e4ec5337a3b74f1e40f4c25da3f179dbe2c7cff..438651cf33f1be4b759c647ad6b6b607a7b39a03 100644 (file)
@@ -600,81 +600,6 @@ xfs_icreate(
        return 0;
 }
 
-#ifdef CONFIG_XFS_LIVE_HOOKS
-/*
- * Use a static key here to reduce the overhead of directory live update hooks.
- * If the compiler supports jump labels, the static branch will be replaced by
- * a nop sled when there are no hook users.  Online fsck is currently the only
- * caller, so this is a reasonable tradeoff.
- *
- * Note: Patching the kernel code requires taking the cpu hotplug lock.  Other
- * parts of the kernel allocate memory with that lock held, which means that
- * XFS callers cannot hold any locks that might be used by memory reclaim or
- * writeback when calling the static_branch_{inc,dec} functions.
- */
-DEFINE_STATIC_XFS_HOOK_SWITCH(xfs_dir_hooks_switch);
-
-void
-xfs_dir_hook_disable(void)
-{
-       xfs_hooks_switch_off(&xfs_dir_hooks_switch);
-}
-
-void
-xfs_dir_hook_enable(void)
-{
-       xfs_hooks_switch_on(&xfs_dir_hooks_switch);
-}
-
-/* Call hooks for a directory update relating to a child dirent update. */
-inline void
-xfs_dir_update_hook(
-       struct xfs_inode                *dp,
-       struct xfs_inode                *ip,
-       int                             delta,
-       const struct xfs_name           *name)
-{
-       if (xfs_hooks_switched_on(&xfs_dir_hooks_switch)) {
-               struct xfs_dir_update_params    p = {
-                       .dp             = dp,
-                       .ip             = ip,
-                       .delta          = delta,
-                       .name           = name,
-               };
-               struct xfs_mount        *mp = ip->i_mount;
-
-               xfs_hooks_call(&mp->m_dir_update_hooks, 0, &p);
-       }
-}
-
-/* Call the specified function during a directory update. */
-int
-xfs_dir_hook_add(
-       struct xfs_mount        *mp,
-       struct xfs_dir_hook     *hook)
-{
-       return xfs_hooks_add(&mp->m_dir_update_hooks, &hook->dirent_hook);
-}
-
-/* Stop calling the specified function during a directory update. */
-void
-xfs_dir_hook_del(
-       struct xfs_mount        *mp,
-       struct xfs_dir_hook     *hook)
-{
-       xfs_hooks_del(&mp->m_dir_update_hooks, &hook->dirent_hook);
-}
-
-/* Configure directory update hook functions. */
-void
-xfs_dir_hook_setup(
-       struct xfs_dir_hook     *hook,
-       notifier_fn_t           mod_fn)
-{
-       xfs_hook_setup(&hook->dirent_hook, mod_fn);
-}
-#endif /* CONFIG_XFS_LIVE_HOOKS */
-
 /* Return dquots for the ids that will be assigned to a new file. */
 int
 xfs_icreate_dqalloc(
@@ -798,12 +723,6 @@ xfs_create(
        if (error)
                goto out_trans_cancel;
 
-       /*
-        * Create ip with a reference from dp, and add '.' and '..' references
-        * if it's a directory.
-        */
-       xfs_dir_update_hook(dp, du.ip, 1, name);
-
        /*
         * If this is a synchronous mount, make sure that the
         * create transaction goes to disk before returning to
@@ -1025,8 +944,6 @@ xfs_link(
        if (error)
                goto error_return;
 
-       xfs_dir_update_hook(tdp, sip, 1, target_name);
-
        /*
         * If this is a synchronous mount, make sure that the
         * link transaction goes to disk before returning to
@@ -2094,12 +2011,6 @@ xfs_remove(
        if (error)
                goto out_trans_cancel;
 
-       /*
-        * Drop the link from dp to ip, and if ip was a directory, remove the
-        * '.' and '..' references since we freed the directory.
-        */
-       xfs_dir_update_hook(dp, ip, -1, name);
-
        /*
         * If this is a synchronous mount, make sure that the
         * remove transaction goes to disk before returning to
@@ -2256,19 +2167,6 @@ xfs_cross_rename(
        if (error)
                goto out_trans_abort;
 
-       /*
-        * Inform our hook clients that we've finished an exchange operation as
-        * follows: removed the source and target files from their directories;
-        * added the target to the source directory; and added the source to
-        * the target directory.  All inodes are locked, so it's ok to model a
-        * rename this way so long as we say we deleted entries before we add
-        * new ones.
-        */
-       xfs_dir_update_hook(dp1, ip1, -1, name1);
-       xfs_dir_update_hook(dp2, ip2, -1, name2);
-       xfs_dir_update_hook(dp1, ip2, 1, name1);
-       xfs_dir_update_hook(dp2, ip1, 1, name2);
-
        return xfs_finish_rename(tp);
 
 out_trans_abort:
@@ -2550,21 +2448,6 @@ retry:
                VFS_I(du_wip.ip)->i_state &= ~I_LINKABLE;
        }
 
-       /*
-        * Inform our hook clients that we've finished a rename operation as
-        * follows: removed the source and target files from their directories;
-        * that we've added the source to the target directory; and finally
-        * that we've added the whiteout, if there was one.  All inodes are
-        * locked, so it's ok to model a rename this way so long as we say we
-        * deleted entries before we add new ones.
-        */
-       if (target_ip)
-               xfs_dir_update_hook(target_dp, target_ip, -1, target_name);
-       xfs_dir_update_hook(src_dp, src_ip, -1, src_name);
-       xfs_dir_update_hook(target_dp, src_ip, 1, target_name);
-       if (du_wip.ip)
-               xfs_dir_update_hook(src_dp, du_wip.ip, 1, src_name);
-
        error = xfs_finish_rename(tp);
        nospace_error = 0;
        goto out_unlock;
index 5ee044674c3ab1ff6240fb62a4127595f56939dd..51defdebef30ed4f224ac03e2881d934ade4bfde 100644 (file)
@@ -632,31 +632,6 @@ void xfs_inode_count_blocks(struct xfs_trans *tp, struct xfs_inode *ip,
                xfs_filblks_t *dblocks, xfs_filblks_t *rblocks);
 unsigned int xfs_inode_alloc_unitsize(struct xfs_inode *ip);
 
-struct xfs_dir_update_params {
-       const struct xfs_inode  *dp;
-       const struct xfs_inode  *ip;
-       const struct xfs_name   *name;
-       int                     delta;
-};
-
-#ifdef CONFIG_XFS_LIVE_HOOKS
-void xfs_dir_update_hook(struct xfs_inode *dp, struct xfs_inode *ip,
-               int delta, const struct xfs_name *name);
-
-struct xfs_dir_hook {
-       struct xfs_hook         dirent_hook;
-};
-
-void xfs_dir_hook_disable(void);
-void xfs_dir_hook_enable(void);
-
-int xfs_dir_hook_add(struct xfs_mount *mp, struct xfs_dir_hook *hook);
-void xfs_dir_hook_del(struct xfs_mount *mp, struct xfs_dir_hook *hook);
-void xfs_dir_hook_setup(struct xfs_dir_hook *hook, notifier_fn_t mod_fn);
-#else
-# define xfs_dir_update_hook(dp, ip, delta, name)      ((void)0)
-#endif /* CONFIG_XFS_LIVE_HOOKS */
-
 int xfs_icreate_dqalloc(const struct xfs_icreate_args *args,
                struct xfs_dquot **udqpp, struct xfs_dquot **gdqpp,
                struct xfs_dquot **pdqpp);
index c0f5c2e1f215b8283dff97cf8363ee9494dfdaa1..77f19e2f66e077a94672a1ade5c7d0ae302aa5f2 100644 (file)
@@ -200,8 +200,6 @@ xfs_symlink(
        if (error)
                goto out_trans_cancel;
 
-       xfs_dir_update_hook(dp, du.ip, 1, link_name);
-
        /*
         * If this is a synchronous mount, make sure that the
         * symlink transaction goes to disk before returning to