diff options
author | Jan Kara <jack@suse.cz> | 2017-03-15 04:16:27 -0400 |
---|---|---|
committer | Jan Kara <jack@suse.cz> | 2017-04-10 11:37:35 -0400 |
commit | a242677bb1e6faa9bd82bd33afb2621071258231 (patch) | |
tree | 853a675a0c61c182b834b1ced7d7e745c1eb3133 /fs/notify | |
parent | 0810b4f9f207910d90aee56d312d25f334796363 (diff) |
fsnotify: Move locking into fsnotify_recalc_mask()
Move locking of locks protecting a list of marks into
fsnotify_recalc_mask(). This reduces code churn in the following patch
which changes the lock protecting the list of marks.
Reviewed-by: Miklos Szeredi <mszeredi@redhat.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/notify')
-rw-r--r-- | fs/notify/dnotify/dnotify.c | 3 | ||||
-rw-r--r-- | fs/notify/fsnotify.h | 3 | ||||
-rw-r--r-- | fs/notify/inode_mark.c | 18 | ||||
-rw-r--r-- | fs/notify/mark.c | 40 | ||||
-rw-r--r-- | fs/notify/vfsmount_mark.c | 13 |
5 files changed, 37 insertions, 40 deletions
diff --git a/fs/notify/dnotify/dnotify.c b/fs/notify/dnotify/dnotify.c index 5024729dba23..41b2a070761c 100644 --- a/fs/notify/dnotify/dnotify.c +++ b/fs/notify/dnotify/dnotify.c | |||
@@ -69,8 +69,7 @@ static void dnotify_recalc_inode_mask(struct fsnotify_mark *fsn_mark) | |||
69 | if (old_mask == new_mask) | 69 | if (old_mask == new_mask) |
70 | return; | 70 | return; |
71 | 71 | ||
72 | if (fsn_mark->connector) | 72 | fsnotify_recalc_mask(fsn_mark->connector); |
73 | fsnotify_recalc_inode_mask(fsn_mark->connector->inode); | ||
74 | } | 73 | } |
75 | 74 | ||
76 | /* | 75 | /* |
diff --git a/fs/notify/fsnotify.h b/fs/notify/fsnotify.h index 0354338aad78..96051780d50e 100644 --- a/fs/notify/fsnotify.h +++ b/fs/notify/fsnotify.h | |||
@@ -14,9 +14,6 @@ extern void fsnotify_flush_notify(struct fsnotify_group *group); | |||
14 | /* protects reads of inode and vfsmount marks list */ | 14 | /* protects reads of inode and vfsmount marks list */ |
15 | extern struct srcu_struct fsnotify_mark_srcu; | 15 | extern struct srcu_struct fsnotify_mark_srcu; |
16 | 16 | ||
17 | /* Calculate mask of events for a list of marks */ | ||
18 | extern u32 fsnotify_recalc_mask(struct fsnotify_mark_connector *conn); | ||
19 | |||
20 | /* compare two groups for sorting of marks lists */ | 17 | /* compare two groups for sorting of marks lists */ |
21 | extern int fsnotify_compare_groups(struct fsnotify_group *a, | 18 | extern int fsnotify_compare_groups(struct fsnotify_group *a, |
22 | struct fsnotify_group *b); | 19 | struct fsnotify_group *b); |
diff --git a/fs/notify/inode_mark.c b/fs/notify/inode_mark.c index 87bef7d802db..9b2f4e6eb8eb 100644 --- a/fs/notify/inode_mark.c +++ b/fs/notify/inode_mark.c | |||
@@ -30,17 +30,9 @@ | |||
30 | 30 | ||
31 | #include "../internal.h" | 31 | #include "../internal.h" |
32 | 32 | ||
33 | /* | ||
34 | * Recalculate the inode->i_fsnotify_mask, or the mask of all FS_* event types | ||
35 | * any notifier is interested in hearing for this inode. | ||
36 | */ | ||
37 | void fsnotify_recalc_inode_mask(struct inode *inode) | 33 | void fsnotify_recalc_inode_mask(struct inode *inode) |
38 | { | 34 | { |
39 | spin_lock(&inode->i_lock); | 35 | fsnotify_recalc_mask(inode->i_fsnotify_marks); |
40 | inode->i_fsnotify_mask = fsnotify_recalc_mask(inode->i_fsnotify_marks); | ||
41 | spin_unlock(&inode->i_lock); | ||
42 | |||
43 | __fsnotify_update_child_dentry_flags(inode); | ||
44 | } | 36 | } |
45 | 37 | ||
46 | struct inode *fsnotify_destroy_inode_mark(struct fsnotify_mark *mark) | 38 | struct inode *fsnotify_destroy_inode_mark(struct fsnotify_mark *mark) |
@@ -57,14 +49,10 @@ struct inode *fsnotify_destroy_inode_mark(struct fsnotify_mark *mark) | |||
57 | empty = hlist_empty(&mark->connector->list); | 49 | empty = hlist_empty(&mark->connector->list); |
58 | mark->connector = NULL; | 50 | mark->connector = NULL; |
59 | 51 | ||
60 | /* | ||
61 | * this mark is now off the inode->i_fsnotify_marks list and we | ||
62 | * hold the inode->i_lock, so this is the perfect time to update the | ||
63 | * inode->i_fsnotify_mask | ||
64 | */ | ||
65 | inode->i_fsnotify_mask = fsnotify_recalc_mask(inode->i_fsnotify_marks); | ||
66 | spin_unlock(&inode->i_lock); | 52 | spin_unlock(&inode->i_lock); |
67 | 53 | ||
54 | fsnotify_recalc_mask(inode->i_fsnotify_marks); | ||
55 | |||
68 | return empty ? inode : NULL; | 56 | return empty ? inode : NULL; |
69 | } | 57 | } |
70 | 58 | ||
diff --git a/fs/notify/mark.c b/fs/notify/mark.c index b3f83ed6e8be..06faf166c7ae 100644 --- a/fs/notify/mark.c +++ b/fs/notify/mark.c | |||
@@ -105,18 +105,40 @@ void fsnotify_put_mark(struct fsnotify_mark *mark) | |||
105 | } | 105 | } |
106 | } | 106 | } |
107 | 107 | ||
108 | /* Calculate mask of events for a list of marks */ | 108 | static void __fsnotify_recalc_mask(struct fsnotify_mark_connector *conn) |
109 | u32 fsnotify_recalc_mask(struct fsnotify_mark_connector *conn) | ||
110 | { | 109 | { |
111 | u32 new_mask = 0; | 110 | u32 new_mask = 0; |
112 | struct fsnotify_mark *mark; | 111 | struct fsnotify_mark *mark; |
113 | 112 | ||
114 | if (!conn) | ||
115 | return 0; | ||
116 | |||
117 | hlist_for_each_entry(mark, &conn->list, obj_list) | 113 | hlist_for_each_entry(mark, &conn->list, obj_list) |
118 | new_mask |= mark->mask; | 114 | new_mask |= mark->mask; |
119 | return new_mask; | 115 | if (conn->flags & FSNOTIFY_OBJ_TYPE_INODE) |
116 | conn->inode->i_fsnotify_mask = new_mask; | ||
117 | else if (conn->flags & FSNOTIFY_OBJ_TYPE_VFSMOUNT) | ||
118 | real_mount(conn->mnt)->mnt_fsnotify_mask = new_mask; | ||
119 | } | ||
120 | |||
121 | /* | ||
122 | * Calculate mask of events for a list of marks. The caller must make sure | ||
123 | * connector cannot disappear under us (usually by holding a mark->lock or | ||
124 | * mark->group->mark_mutex for a mark on this list). | ||
125 | */ | ||
126 | void fsnotify_recalc_mask(struct fsnotify_mark_connector *conn) | ||
127 | { | ||
128 | if (!conn) | ||
129 | return; | ||
130 | |||
131 | if (conn->flags & FSNOTIFY_OBJ_TYPE_INODE) | ||
132 | spin_lock(&conn->inode->i_lock); | ||
133 | else | ||
134 | spin_lock(&conn->mnt->mnt_root->d_lock); | ||
135 | __fsnotify_recalc_mask(conn); | ||
136 | if (conn->flags & FSNOTIFY_OBJ_TYPE_INODE) { | ||
137 | spin_unlock(&conn->inode->i_lock); | ||
138 | __fsnotify_update_child_dentry_flags(conn->inode); | ||
139 | } else { | ||
140 | spin_unlock(&conn->mnt->mnt_root->d_lock); | ||
141 | } | ||
120 | } | 142 | } |
121 | 143 | ||
122 | /* | 144 | /* |
@@ -423,10 +445,8 @@ int fsnotify_add_mark_locked(struct fsnotify_mark *mark, | |||
423 | if (ret) | 445 | if (ret) |
424 | goto err; | 446 | goto err; |
425 | 447 | ||
426 | if (inode) | 448 | if (mark->mask) |
427 | fsnotify_recalc_inode_mask(inode); | 449 | fsnotify_recalc_mask(mark->connector); |
428 | else | ||
429 | fsnotify_recalc_vfsmount_mask(mnt); | ||
430 | 450 | ||
431 | return ret; | 451 | return ret; |
432 | err: | 452 | err: |
diff --git a/fs/notify/vfsmount_mark.c b/fs/notify/vfsmount_mark.c index 49ccbdb74f82..ffe0d7098cba 100644 --- a/fs/notify/vfsmount_mark.c +++ b/fs/notify/vfsmount_mark.c | |||
@@ -34,17 +34,9 @@ void fsnotify_clear_vfsmount_marks_by_group(struct fsnotify_group *group) | |||
34 | fsnotify_clear_marks_by_group_flags(group, FSNOTIFY_OBJ_TYPE_VFSMOUNT); | 34 | fsnotify_clear_marks_by_group_flags(group, FSNOTIFY_OBJ_TYPE_VFSMOUNT); |
35 | } | 35 | } |
36 | 36 | ||
37 | /* | ||
38 | * Recalculate the mnt->mnt_fsnotify_mask, or the mask of all FS_* event types | ||
39 | * any notifier is interested in hearing for this mount point | ||
40 | */ | ||
41 | void fsnotify_recalc_vfsmount_mask(struct vfsmount *mnt) | 37 | void fsnotify_recalc_vfsmount_mask(struct vfsmount *mnt) |
42 | { | 38 | { |
43 | struct mount *m = real_mount(mnt); | 39 | fsnotify_recalc_mask(real_mount(mnt)->mnt_fsnotify_marks); |
44 | |||
45 | spin_lock(&mnt->mnt_root->d_lock); | ||
46 | m->mnt_fsnotify_mask = fsnotify_recalc_mask(m->mnt_fsnotify_marks); | ||
47 | spin_unlock(&mnt->mnt_root->d_lock); | ||
48 | } | 40 | } |
49 | 41 | ||
50 | void fsnotify_destroy_vfsmount_mark(struct fsnotify_mark *mark) | 42 | void fsnotify_destroy_vfsmount_mark(struct fsnotify_mark *mark) |
@@ -60,8 +52,9 @@ void fsnotify_destroy_vfsmount_mark(struct fsnotify_mark *mark) | |||
60 | hlist_del_init_rcu(&mark->obj_list); | 52 | hlist_del_init_rcu(&mark->obj_list); |
61 | mark->connector = NULL; | 53 | mark->connector = NULL; |
62 | 54 | ||
63 | m->mnt_fsnotify_mask = fsnotify_recalc_mask(m->mnt_fsnotify_marks); | ||
64 | spin_unlock(&mnt->mnt_root->d_lock); | 55 | spin_unlock(&mnt->mnt_root->d_lock); |
56 | |||
57 | fsnotify_recalc_mask(m->mnt_fsnotify_marks); | ||
65 | } | 58 | } |
66 | 59 | ||
67 | /* | 60 | /* |