Skip to content

Commit 62bbf50

Browse files
author
Darrick J. Wong
committed
xfs: move dirent update hooks to xfs_dir2.c
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 <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]>
1 parent 28d0d81 commit 62bbf50

File tree

6 files changed

+130
-144
lines changed

6 files changed

+130
-144
lines changed

fs/xfs/libxfs/xfs_dir2.c

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -762,6 +762,81 @@ xfs_dir2_compname(
762762
return xfs_da_compname(args, name, len);
763763
}
764764

765+
#ifdef CONFIG_XFS_LIVE_HOOKS
766+
/*
767+
* Use a static key here to reduce the overhead of directory live update hooks.
768+
* If the compiler supports jump labels, the static branch will be replaced by
769+
* a nop sled when there are no hook users. Online fsck is currently the only
770+
* caller, so this is a reasonable tradeoff.
771+
*
772+
* Note: Patching the kernel code requires taking the cpu hotplug lock. Other
773+
* parts of the kernel allocate memory with that lock held, which means that
774+
* XFS callers cannot hold any locks that might be used by memory reclaim or
775+
* writeback when calling the static_branch_{inc,dec} functions.
776+
*/
777+
DEFINE_STATIC_XFS_HOOK_SWITCH(xfs_dir_hooks_switch);
778+
779+
void
780+
xfs_dir_hook_disable(void)
781+
{
782+
xfs_hooks_switch_off(&xfs_dir_hooks_switch);
783+
}
784+
785+
void
786+
xfs_dir_hook_enable(void)
787+
{
788+
xfs_hooks_switch_on(&xfs_dir_hooks_switch);
789+
}
790+
791+
/* Call hooks for a directory update relating to a child dirent update. */
792+
inline void
793+
xfs_dir_update_hook(
794+
struct xfs_inode *dp,
795+
struct xfs_inode *ip,
796+
int delta,
797+
const struct xfs_name *name)
798+
{
799+
if (xfs_hooks_switched_on(&xfs_dir_hooks_switch)) {
800+
struct xfs_dir_update_params p = {
801+
.dp = dp,
802+
.ip = ip,
803+
.delta = delta,
804+
.name = name,
805+
};
806+
struct xfs_mount *mp = ip->i_mount;
807+
808+
xfs_hooks_call(&mp->m_dir_update_hooks, 0, &p);
809+
}
810+
}
811+
812+
/* Call the specified function during a directory update. */
813+
int
814+
xfs_dir_hook_add(
815+
struct xfs_mount *mp,
816+
struct xfs_dir_hook *hook)
817+
{
818+
return xfs_hooks_add(&mp->m_dir_update_hooks, &hook->dirent_hook);
819+
}
820+
821+
/* Stop calling the specified function during a directory update. */
822+
void
823+
xfs_dir_hook_del(
824+
struct xfs_mount *mp,
825+
struct xfs_dir_hook *hook)
826+
{
827+
xfs_hooks_del(&mp->m_dir_update_hooks, &hook->dirent_hook);
828+
}
829+
830+
/* Configure directory update hook functions. */
831+
void
832+
xfs_dir_hook_setup(
833+
struct xfs_dir_hook *hook,
834+
notifier_fn_t mod_fn)
835+
{
836+
xfs_hook_setup(&hook->dirent_hook, mod_fn);
837+
}
838+
#endif /* CONFIG_XFS_LIVE_HOOKS */
839+
765840
/*
766841
* Given a directory @dp, a newly allocated inode @ip, and a @name, link @ip
767842
* into @dp under the given @name. If @ip is a directory, it will be
@@ -809,6 +884,7 @@ xfs_dir_create_child(
809884
return error;
810885
}
811886

887+
xfs_dir_update_hook(dp, ip, 1, name);
812888
return 0;
813889
}
814890

@@ -873,6 +949,7 @@ xfs_dir_add_child(
873949
return error;
874950
}
875951

952+
xfs_dir_update_hook(dp, ip, 1, name);
876953
return 0;
877954
}
878955

@@ -954,6 +1031,7 @@ xfs_dir_remove_child(
9541031
return error;
9551032
}
9561033

1034+
xfs_dir_update_hook(dp, ip, -1, name);
9571035
return 0;
9581036
}
9591037

@@ -1079,6 +1157,18 @@ xfs_dir_exchange_children(
10791157
return error;
10801158
}
10811159

1160+
/*
1161+
* Inform our hook clients that we've finished an exchange operation as
1162+
* follows: removed the source and target files from their directories;
1163+
* added the target to the source directory; and added the source to
1164+
* the target directory. All inodes are locked, so it's ok to model a
1165+
* rename this way so long as we say we deleted entries before we add
1166+
* new ones.
1167+
*/
1168+
xfs_dir_update_hook(dp1, ip1, -1, name1);
1169+
xfs_dir_update_hook(dp2, ip2, -1, name2);
1170+
xfs_dir_update_hook(dp1, ip2, 1, name1);
1171+
xfs_dir_update_hook(dp2, ip1, 1, name2);
10821172
return 0;
10831173
}
10841174

@@ -1305,5 +1395,19 @@ xfs_dir_rename_children(
13051395
return error;
13061396
}
13071397

1398+
/*
1399+
* Inform our hook clients that we've finished a rename operation as
1400+
* follows: removed the source and target files from their directories;
1401+
* that we've added the source to the target directory; and finally
1402+
* that we've added the whiteout, if there was one. All inodes are
1403+
* locked, so it's ok to model a rename this way so long as we say we
1404+
* deleted entries before we add new ones.
1405+
*/
1406+
if (target_ip)
1407+
xfs_dir_update_hook(target_dp, target_ip, -1, target_name);
1408+
xfs_dir_update_hook(src_dp, src_ip, -1, src_name);
1409+
xfs_dir_update_hook(target_dp, src_ip, 1, target_name);
1410+
if (du_wip->ip)
1411+
xfs_dir_update_hook(src_dp, du_wip->ip, 1, src_name);
13081412
return 0;
13091413
}

fs/xfs/libxfs/xfs_dir2.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,31 @@ static inline unsigned char xfs_ascii_ci_xfrm(unsigned char c)
309309
return c;
310310
}
311311

312+
struct xfs_dir_update_params {
313+
const struct xfs_inode *dp;
314+
const struct xfs_inode *ip;
315+
const struct xfs_name *name;
316+
int delta;
317+
};
318+
319+
#ifdef CONFIG_XFS_LIVE_HOOKS
320+
void xfs_dir_update_hook(struct xfs_inode *dp, struct xfs_inode *ip,
321+
int delta, const struct xfs_name *name);
322+
323+
struct xfs_dir_hook {
324+
struct xfs_hook dirent_hook;
325+
};
326+
327+
void xfs_dir_hook_disable(void);
328+
void xfs_dir_hook_enable(void);
329+
330+
int xfs_dir_hook_add(struct xfs_mount *mp, struct xfs_dir_hook *hook);
331+
void xfs_dir_hook_del(struct xfs_mount *mp, struct xfs_dir_hook *hook);
332+
void xfs_dir_hook_setup(struct xfs_dir_hook *hook, notifier_fn_t mod_fn);
333+
#else
334+
# define xfs_dir_update_hook(dp, ip, delta, name) ((void)0)
335+
#endif /* CONFIG_XFS_LIVE_HOOKS */
336+
312337
struct xfs_parent_args;
313338

314339
struct xfs_dir_update {

fs/xfs/scrub/common.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "xfs_da_format.h"
2727
#include "xfs_da_btree.h"
2828
#include "xfs_dir2_priv.h"
29+
#include "xfs_dir2.h"
2930
#include "xfs_attr.h"
3031
#include "xfs_reflink.h"
3132
#include "xfs_ag.h"

fs/xfs/xfs_inode.c

Lines changed: 0 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -600,81 +600,6 @@ xfs_icreate(
600600
return 0;
601601
}
602602

603-
#ifdef CONFIG_XFS_LIVE_HOOKS
604-
/*
605-
* Use a static key here to reduce the overhead of directory live update hooks.
606-
* If the compiler supports jump labels, the static branch will be replaced by
607-
* a nop sled when there are no hook users. Online fsck is currently the only
608-
* caller, so this is a reasonable tradeoff.
609-
*
610-
* Note: Patching the kernel code requires taking the cpu hotplug lock. Other
611-
* parts of the kernel allocate memory with that lock held, which means that
612-
* XFS callers cannot hold any locks that might be used by memory reclaim or
613-
* writeback when calling the static_branch_{inc,dec} functions.
614-
*/
615-
DEFINE_STATIC_XFS_HOOK_SWITCH(xfs_dir_hooks_switch);
616-
617-
void
618-
xfs_dir_hook_disable(void)
619-
{
620-
xfs_hooks_switch_off(&xfs_dir_hooks_switch);
621-
}
622-
623-
void
624-
xfs_dir_hook_enable(void)
625-
{
626-
xfs_hooks_switch_on(&xfs_dir_hooks_switch);
627-
}
628-
629-
/* Call hooks for a directory update relating to a child dirent update. */
630-
inline void
631-
xfs_dir_update_hook(
632-
struct xfs_inode *dp,
633-
struct xfs_inode *ip,
634-
int delta,
635-
const struct xfs_name *name)
636-
{
637-
if (xfs_hooks_switched_on(&xfs_dir_hooks_switch)) {
638-
struct xfs_dir_update_params p = {
639-
.dp = dp,
640-
.ip = ip,
641-
.delta = delta,
642-
.name = name,
643-
};
644-
struct xfs_mount *mp = ip->i_mount;
645-
646-
xfs_hooks_call(&mp->m_dir_update_hooks, 0, &p);
647-
}
648-
}
649-
650-
/* Call the specified function during a directory update. */
651-
int
652-
xfs_dir_hook_add(
653-
struct xfs_mount *mp,
654-
struct xfs_dir_hook *hook)
655-
{
656-
return xfs_hooks_add(&mp->m_dir_update_hooks, &hook->dirent_hook);
657-
}
658-
659-
/* Stop calling the specified function during a directory update. */
660-
void
661-
xfs_dir_hook_del(
662-
struct xfs_mount *mp,
663-
struct xfs_dir_hook *hook)
664-
{
665-
xfs_hooks_del(&mp->m_dir_update_hooks, &hook->dirent_hook);
666-
}
667-
668-
/* Configure directory update hook functions. */
669-
void
670-
xfs_dir_hook_setup(
671-
struct xfs_dir_hook *hook,
672-
notifier_fn_t mod_fn)
673-
{
674-
xfs_hook_setup(&hook->dirent_hook, mod_fn);
675-
}
676-
#endif /* CONFIG_XFS_LIVE_HOOKS */
677-
678603
/* Return dquots for the ids that will be assigned to a new file. */
679604
int
680605
xfs_icreate_dqalloc(
@@ -798,12 +723,6 @@ xfs_create(
798723
if (error)
799724
goto out_trans_cancel;
800725

801-
/*
802-
* Create ip with a reference from dp, and add '.' and '..' references
803-
* if it's a directory.
804-
*/
805-
xfs_dir_update_hook(dp, du.ip, 1, name);
806-
807726
/*
808727
* If this is a synchronous mount, make sure that the
809728
* create transaction goes to disk before returning to
@@ -1025,8 +944,6 @@ xfs_link(
1025944
if (error)
1026945
goto error_return;
1027946

1028-
xfs_dir_update_hook(tdp, sip, 1, target_name);
1029-
1030947
/*
1031948
* If this is a synchronous mount, make sure that the
1032949
* link transaction goes to disk before returning to
@@ -2094,12 +2011,6 @@ xfs_remove(
20942011
if (error)
20952012
goto out_trans_cancel;
20962013

2097-
/*
2098-
* Drop the link from dp to ip, and if ip was a directory, remove the
2099-
* '.' and '..' references since we freed the directory.
2100-
*/
2101-
xfs_dir_update_hook(dp, ip, -1, name);
2102-
21032014
/*
21042015
* If this is a synchronous mount, make sure that the
21052016
* remove transaction goes to disk before returning to
@@ -2256,19 +2167,6 @@ xfs_cross_rename(
22562167
if (error)
22572168
goto out_trans_abort;
22582169

2259-
/*
2260-
* Inform our hook clients that we've finished an exchange operation as
2261-
* follows: removed the source and target files from their directories;
2262-
* added the target to the source directory; and added the source to
2263-
* the target directory. All inodes are locked, so it's ok to model a
2264-
* rename this way so long as we say we deleted entries before we add
2265-
* new ones.
2266-
*/
2267-
xfs_dir_update_hook(dp1, ip1, -1, name1);
2268-
xfs_dir_update_hook(dp2, ip2, -1, name2);
2269-
xfs_dir_update_hook(dp1, ip2, 1, name1);
2270-
xfs_dir_update_hook(dp2, ip1, 1, name2);
2271-
22722170
return xfs_finish_rename(tp);
22732171

22742172
out_trans_abort:
@@ -2550,21 +2448,6 @@ xfs_rename(
25502448
VFS_I(du_wip.ip)->i_state &= ~I_LINKABLE;
25512449
}
25522450

2553-
/*
2554-
* Inform our hook clients that we've finished a rename operation as
2555-
* follows: removed the source and target files from their directories;
2556-
* that we've added the source to the target directory; and finally
2557-
* that we've added the whiteout, if there was one. All inodes are
2558-
* locked, so it's ok to model a rename this way so long as we say we
2559-
* deleted entries before we add new ones.
2560-
*/
2561-
if (target_ip)
2562-
xfs_dir_update_hook(target_dp, target_ip, -1, target_name);
2563-
xfs_dir_update_hook(src_dp, src_ip, -1, src_name);
2564-
xfs_dir_update_hook(target_dp, src_ip, 1, target_name);
2565-
if (du_wip.ip)
2566-
xfs_dir_update_hook(src_dp, du_wip.ip, 1, src_name);
2567-
25682451
error = xfs_finish_rename(tp);
25692452
nospace_error = 0;
25702453
goto out_unlock;

fs/xfs/xfs_inode.h

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -632,31 +632,6 @@ void xfs_inode_count_blocks(struct xfs_trans *tp, struct xfs_inode *ip,
632632
xfs_filblks_t *dblocks, xfs_filblks_t *rblocks);
633633
unsigned int xfs_inode_alloc_unitsize(struct xfs_inode *ip);
634634

635-
struct xfs_dir_update_params {
636-
const struct xfs_inode *dp;
637-
const struct xfs_inode *ip;
638-
const struct xfs_name *name;
639-
int delta;
640-
};
641-
642-
#ifdef CONFIG_XFS_LIVE_HOOKS
643-
void xfs_dir_update_hook(struct xfs_inode *dp, struct xfs_inode *ip,
644-
int delta, const struct xfs_name *name);
645-
646-
struct xfs_dir_hook {
647-
struct xfs_hook dirent_hook;
648-
};
649-
650-
void xfs_dir_hook_disable(void);
651-
void xfs_dir_hook_enable(void);
652-
653-
int xfs_dir_hook_add(struct xfs_mount *mp, struct xfs_dir_hook *hook);
654-
void xfs_dir_hook_del(struct xfs_mount *mp, struct xfs_dir_hook *hook);
655-
void xfs_dir_hook_setup(struct xfs_dir_hook *hook, notifier_fn_t mod_fn);
656-
#else
657-
# define xfs_dir_update_hook(dp, ip, delta, name) ((void)0)
658-
#endif /* CONFIG_XFS_LIVE_HOOKS */
659-
660635
int xfs_icreate_dqalloc(const struct xfs_icreate_args *args,
661636
struct xfs_dquot **udqpp, struct xfs_dquot **gdqpp,
662637
struct xfs_dquot **pdqpp);

fs/xfs/xfs_symlink.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,6 @@ xfs_symlink(
200200
if (error)
201201
goto out_trans_cancel;
202202

203-
xfs_dir_update_hook(dp, du.ip, 1, link_name);
204-
205203
/*
206204
* If this is a synchronous mount, make sure that the
207205
* symlink transaction goes to disk before returning to

0 commit comments

Comments
 (0)