aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2017-03-15 04:48:11 -0400
committerJan Kara <jack@suse.cz>2017-04-10 11:37:35 -0400
commit8212a6097a720896b4cdbe516487ad47f4296599 (patch)
treec598677214226244c7db2b90be6f2715cfbf38eb
parenta03e2e4f078365428bb4317989cb5d1d6563cfe9 (diff)
fsnotify: Remove indirection from fsnotify_detach_mark()
fsnotify_detach_mark() calls fsnotify_destroy_inode_mark() or fsnotify_destroy_vfsmount_mark() to remove mark from object list. These two functions are however very similar and differ only in the lock they use to protect the object list of marks. Simplify the code by removing the indirection and removing mark from the object list in a common function. Reviewed-by: Miklos Szeredi <mszeredi@redhat.com> Reviewed-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Jan Kara <jack@suse.cz>
-rw-r--r--fs/notify/fsnotify.h4
-rw-r--r--fs/notify/inode_mark.c21
-rw-r--r--fs/notify/mark.c32
-rw-r--r--fs/notify/vfsmount_mark.c18
4 files changed, 26 insertions, 49 deletions
diff --git a/fs/notify/fsnotify.h b/fs/notify/fsnotify.h
index 225924274f8a..510f027bdf0f 100644
--- a/fs/notify/fsnotify.h
+++ b/fs/notify/fsnotify.h
@@ -18,10 +18,6 @@ extern struct srcu_struct fsnotify_mark_srcu;
18extern int fsnotify_compare_groups(struct fsnotify_group *a, 18extern int fsnotify_compare_groups(struct fsnotify_group *a,
19 struct fsnotify_group *b); 19 struct fsnotify_group *b);
20 20
21/* vfsmount specific destruction of a mark */
22extern void fsnotify_destroy_vfsmount_mark(struct fsnotify_mark *mark);
23/* inode specific destruction of a mark */
24extern struct inode *fsnotify_destroy_inode_mark(struct fsnotify_mark *mark);
25/* Find mark belonging to given group in the list of marks */ 21/* Find mark belonging to given group in the list of marks */
26extern struct fsnotify_mark *fsnotify_find_mark( 22extern struct fsnotify_mark *fsnotify_find_mark(
27 struct fsnotify_mark_connector *conn, 23 struct fsnotify_mark_connector *conn,
diff --git a/fs/notify/inode_mark.c b/fs/notify/inode_mark.c
index f05fc49b8242..080b6d8b9973 100644
--- a/fs/notify/inode_mark.c
+++ b/fs/notify/inode_mark.c
@@ -35,27 +35,6 @@ void fsnotify_recalc_inode_mask(struct inode *inode)
35 fsnotify_recalc_mask(inode->i_fsnotify_marks); 35 fsnotify_recalc_mask(inode->i_fsnotify_marks);
36} 36}
37 37
38struct inode *fsnotify_destroy_inode_mark(struct fsnotify_mark *mark)
39{
40 struct inode *inode = mark->connector->inode;
41 bool empty;
42
43 BUG_ON(!mutex_is_locked(&mark->group->mark_mutex));
44 assert_spin_locked(&mark->lock);
45
46 spin_lock(&inode->i_lock);
47
48 hlist_del_init_rcu(&mark->obj_list);
49 empty = hlist_empty(&mark->connector->list);
50 mark->connector = NULL;
51
52 spin_unlock(&inode->i_lock);
53
54 fsnotify_recalc_mask(inode->i_fsnotify_marks);
55
56 return empty ? inode : NULL;
57}
58
59/* 38/*
60 * Given a group clear all of the inode marks associated with that group. 39 * Given a group clear all of the inode marks associated with that group.
61 */ 40 */
diff --git a/fs/notify/mark.c b/fs/notify/mark.c
index f32ca924c44e..08ab7b252322 100644
--- a/fs/notify/mark.c
+++ b/fs/notify/mark.c
@@ -141,6 +141,30 @@ void fsnotify_recalc_mask(struct fsnotify_mark_connector *conn)
141 } 141 }
142} 142}
143 143
144static struct inode *fsnotify_detach_from_object(struct fsnotify_mark *mark)
145{
146 struct fsnotify_mark_connector *conn;
147 struct inode *inode = NULL;
148 spinlock_t *lock;
149
150 conn = mark->connector;
151 if (conn->flags & FSNOTIFY_OBJ_TYPE_INODE)
152 lock = &conn->inode->i_lock;
153 else
154 lock = &conn->mnt->mnt_root->d_lock;
155 spin_lock(lock);
156 hlist_del_init_rcu(&mark->obj_list);
157 if (hlist_empty(&conn->list)) {
158 if (conn->flags & FSNOTIFY_OBJ_TYPE_INODE)
159 inode = conn->inode;
160 }
161 mark->connector = NULL;
162 spin_unlock(lock);
163 fsnotify_recalc_mask(conn);
164
165 return inode;
166}
167
144/* 168/*
145 * Remove mark from inode / vfsmount list, group list, drop inode reference 169 * Remove mark from inode / vfsmount list, group list, drop inode reference
146 * if we got one. 170 * if we got one.
@@ -164,12 +188,8 @@ void fsnotify_detach_mark(struct fsnotify_mark *mark)
164 188
165 mark->flags &= ~FSNOTIFY_MARK_FLAG_ATTACHED; 189 mark->flags &= ~FSNOTIFY_MARK_FLAG_ATTACHED;
166 190
167 if (mark->connector->flags & FSNOTIFY_OBJ_TYPE_INODE) 191 inode = fsnotify_detach_from_object(mark);
168 inode = fsnotify_destroy_inode_mark(mark); 192
169 else if (mark->connector->flags & FSNOTIFY_OBJ_TYPE_VFSMOUNT)
170 fsnotify_destroy_vfsmount_mark(mark);
171 else
172 BUG();
173 /* 193 /*
174 * Note that we didn't update flags telling whether inode cares about 194 * Note that we didn't update flags telling whether inode cares about
175 * what's happening with children. We update these flags from 195 * what's happening with children. We update these flags from
diff --git a/fs/notify/vfsmount_mark.c b/fs/notify/vfsmount_mark.c
index 3476ee44b2c5..26da5c209944 100644
--- a/fs/notify/vfsmount_mark.c
+++ b/fs/notify/vfsmount_mark.c
@@ -39,24 +39,6 @@ void fsnotify_recalc_vfsmount_mask(struct vfsmount *mnt)
39 fsnotify_recalc_mask(real_mount(mnt)->mnt_fsnotify_marks); 39 fsnotify_recalc_mask(real_mount(mnt)->mnt_fsnotify_marks);
40} 40}
41 41
42void fsnotify_destroy_vfsmount_mark(struct fsnotify_mark *mark)
43{
44 struct vfsmount *mnt = mark->connector->mnt;
45 struct mount *m = real_mount(mnt);
46
47 BUG_ON(!mutex_is_locked(&mark->group->mark_mutex));
48 assert_spin_locked(&mark->lock);
49
50 spin_lock(&mnt->mnt_root->d_lock);
51
52 hlist_del_init_rcu(&mark->obj_list);
53 mark->connector = NULL;
54
55 spin_unlock(&mnt->mnt_root->d_lock);
56
57 fsnotify_recalc_mask(m->mnt_fsnotify_marks);
58}
59
60/* 42/*
61 * given a group and vfsmount, find the mark associated with that combination. 43 * given a group and vfsmount, find the mark associated with that combination.
62 * if found take a reference to that mark and return it, else return NULL 44 * if found take a reference to that mark and return it, else return NULL