mark.c (b812a9f5896379b6cff2ac168ddb5b89037d8e78) mark.c (36f10f55ff1d2867bfc48ed898a9cc0dc6b49dd2)
1/*
2 * Copyright (C) 2008 Red Hat, Inc., Eric Paris <eparis@redhat.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2, or (at your option)
7 * any later version.
8 *

--- 106 unchanged lines hidden (view full) ---

115 struct fsnotify_mark *mark;
116
117 assert_spin_locked(&conn->lock);
118 hlist_for_each_entry(mark, &conn->list, obj_list) {
119 if (mark->flags & FSNOTIFY_MARK_FLAG_ATTACHED)
120 new_mask |= mark->mask;
121 }
122 if (conn->type == FSNOTIFY_OBJ_TYPE_INODE)
1/*
2 * Copyright (C) 2008 Red Hat, Inc., Eric Paris <eparis@redhat.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2, or (at your option)
7 * any later version.
8 *

--- 106 unchanged lines hidden (view full) ---

115 struct fsnotify_mark *mark;
116
117 assert_spin_locked(&conn->lock);
118 hlist_for_each_entry(mark, &conn->list, obj_list) {
119 if (mark->flags & FSNOTIFY_MARK_FLAG_ATTACHED)
120 new_mask |= mark->mask;
121 }
122 if (conn->type == FSNOTIFY_OBJ_TYPE_INODE)
123 conn->inode->i_fsnotify_mask = new_mask;
123 fsnotify_conn_inode(conn)->i_fsnotify_mask = new_mask;
124 else if (conn->type == FSNOTIFY_OBJ_TYPE_VFSMOUNT)
124 else if (conn->type == FSNOTIFY_OBJ_TYPE_VFSMOUNT)
125 real_mount(conn->mnt)->mnt_fsnotify_mask = new_mask;
125 fsnotify_conn_mount(conn)->mnt_fsnotify_mask = new_mask;
126}
127
128/*
129 * Calculate mask of events for a list of marks. The caller must make sure
126}
127
128/*
129 * Calculate mask of events for a list of marks. The caller must make sure
130 * connector and connector->inode cannot disappear under us. Callers achieve
130 * connector and connector->obj cannot disappear under us. Callers achieve
131 * this by holding a mark->lock or mark->group->mark_mutex for a mark on this
132 * list.
133 */
134void fsnotify_recalc_mask(struct fsnotify_mark_connector *conn)
135{
136 if (!conn)
137 return;
138
139 spin_lock(&conn->lock);
140 __fsnotify_recalc_mask(conn);
141 spin_unlock(&conn->lock);
142 if (conn->type == FSNOTIFY_OBJ_TYPE_INODE)
131 * this by holding a mark->lock or mark->group->mark_mutex for a mark on this
132 * list.
133 */
134void fsnotify_recalc_mask(struct fsnotify_mark_connector *conn)
135{
136 if (!conn)
137 return;
138
139 spin_lock(&conn->lock);
140 __fsnotify_recalc_mask(conn);
141 spin_unlock(&conn->lock);
142 if (conn->type == FSNOTIFY_OBJ_TYPE_INODE)
143 __fsnotify_update_child_dentry_flags(conn->inode);
143 __fsnotify_update_child_dentry_flags(
144 fsnotify_conn_inode(conn));
144}
145
146/* Free all connectors queued for freeing once SRCU period ends */
147static void fsnotify_connector_destroy_workfn(struct work_struct *work)
148{
149 struct fsnotify_mark_connector *conn, *free;
150
151 spin_lock(&destroy_lock);

--- 9 unchanged lines hidden (view full) ---

161 }
162}
163
164static struct inode *fsnotify_detach_connector_from_object(
165 struct fsnotify_mark_connector *conn)
166{
167 struct inode *inode = NULL;
168
145}
146
147/* Free all connectors queued for freeing once SRCU period ends */
148static void fsnotify_connector_destroy_workfn(struct work_struct *work)
149{
150 struct fsnotify_mark_connector *conn, *free;
151
152 spin_lock(&destroy_lock);

--- 9 unchanged lines hidden (view full) ---

162 }
163}
164
165static struct inode *fsnotify_detach_connector_from_object(
166 struct fsnotify_mark_connector *conn)
167{
168 struct inode *inode = NULL;
169
170 if (conn->type == FSNOTIFY_OBJ_TYPE_DETACHED)
171 return NULL;
172
169 if (conn->type == FSNOTIFY_OBJ_TYPE_INODE) {
173 if (conn->type == FSNOTIFY_OBJ_TYPE_INODE) {
170 inode = conn->inode;
171 rcu_assign_pointer(inode->i_fsnotify_marks, NULL);
174 inode = fsnotify_conn_inode(conn);
172 inode->i_fsnotify_mask = 0;
175 inode->i_fsnotify_mask = 0;
173 conn->inode = NULL;
174 conn->type = FSNOTIFY_OBJ_TYPE_DETACHED;
175 } else if (conn->type == FSNOTIFY_OBJ_TYPE_VFSMOUNT) {
176 } else if (conn->type == FSNOTIFY_OBJ_TYPE_VFSMOUNT) {
176 rcu_assign_pointer(real_mount(conn->mnt)->mnt_fsnotify_marks,
177 NULL);
178 real_mount(conn->mnt)->mnt_fsnotify_mask = 0;
179 conn->mnt = NULL;
180 conn->type = FSNOTIFY_OBJ_TYPE_DETACHED;
177 fsnotify_conn_mount(conn)->mnt_fsnotify_mask = 0;
181 }
182
178 }
179
180 rcu_assign_pointer(*(conn->obj), NULL);
181 conn->obj = NULL;
182 conn->type = FSNOTIFY_OBJ_TYPE_DETACHED;
183
183 return inode;
184}
185
186static void fsnotify_final_mark_destroy(struct fsnotify_mark *mark)
187{
188 struct fsnotify_group *group = mark->group;
189
190 if (WARN_ON_ONCE(!group))

--- 252 unchanged lines hidden (view full) ---

443 struct fsnotify_mark_connector *conn;
444
445 conn = kmem_cache_alloc(fsnotify_mark_connector_cachep, GFP_KERNEL);
446 if (!conn)
447 return -ENOMEM;
448 spin_lock_init(&conn->lock);
449 INIT_HLIST_HEAD(&conn->list);
450 conn->type = type;
184 return inode;
185}
186
187static void fsnotify_final_mark_destroy(struct fsnotify_mark *mark)
188{
189 struct fsnotify_group *group = mark->group;
190
191 if (WARN_ON_ONCE(!group))

--- 252 unchanged lines hidden (view full) ---

444 struct fsnotify_mark_connector *conn;
445
446 conn = kmem_cache_alloc(fsnotify_mark_connector_cachep, GFP_KERNEL);
447 if (!conn)
448 return -ENOMEM;
449 spin_lock_init(&conn->lock);
450 INIT_HLIST_HEAD(&conn->list);
451 conn->type = type;
452 conn->obj = connp;
451 if (conn->type == FSNOTIFY_OBJ_TYPE_INODE)
453 if (conn->type == FSNOTIFY_OBJ_TYPE_INODE)
452 inode = conn->inode = igrab(fsnotify_obj_inode(connp));
453 else if (conn->type == FSNOTIFY_OBJ_TYPE_VFSMOUNT)
454 conn->mnt = &fsnotify_obj_mount(connp)->mnt;
454 inode = igrab(fsnotify_conn_inode(conn));
455 /*
456 * cmpxchg() provides the barrier so that readers of *connp can see
457 * only initialized structure
458 */
459 if (cmpxchg(connp, NULL, conn)) {
460 /* Someone else created list structure for us */
461 if (inode)
462 iput(inode);

--- 305 unchanged lines hidden ---
455 /*
456 * cmpxchg() provides the barrier so that readers of *connp can see
457 * only initialized structure
458 */
459 if (cmpxchg(connp, NULL, conn)) {
460 /* Someone else created list structure for us */
461 if (inode)
462 iput(inode);

--- 305 unchanged lines hidden ---