inode.c (6b93f350e55f3f2ee071dd41109d936abfba8ebf) inode.c (499aa1ca4eb6602df38afaecb88fc14edf50cdbb)
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * inode.c - part of tracefs, a pseudo file system for activating tracing
4 *
5 * Based on debugfs by: Greg Kroah-Hartman <greg@kroah.com>
6 *
7 * Copyright (C) 2014 Red Hat Inc, author: Steven Rostedt <srostedt@redhat.com>
8 *

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

194 * Taken from d_walk, but without he need for handling renames.
195 * Nothing can be renamed while walking the list, as tracefs
196 * does not support renames. This is only called when mounting
197 * or remounting the file system, to set all the files to
198 * the given gid.
199 */
200static void set_gid(struct dentry *parent, kgid_t gid)
201{
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * inode.c - part of tracefs, a pseudo file system for activating tracing
4 *
5 * Based on debugfs by: Greg Kroah-Hartman <greg@kroah.com>
6 *
7 * Copyright (C) 2014 Red Hat Inc, author: Steven Rostedt <srostedt@redhat.com>
8 *

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

194 * Taken from d_walk, but without he need for handling renames.
195 * Nothing can be renamed while walking the list, as tracefs
196 * does not support renames. This is only called when mounting
197 * or remounting the file system, to set all the files to
198 * the given gid.
199 */
200static void set_gid(struct dentry *parent, kgid_t gid)
201{
202 struct dentry *this_parent;
203 struct list_head *next;
202 struct dentry *this_parent, *dentry;
204
205 this_parent = parent;
206 spin_lock(&this_parent->d_lock);
207
208 change_gid(this_parent, gid);
209repeat:
203
204 this_parent = parent;
205 spin_lock(&this_parent->d_lock);
206
207 change_gid(this_parent, gid);
208repeat:
210 next = this_parent->d_subdirs.next;
209 dentry = d_first_child(this_parent);
211resume:
210resume:
212 while (next != &this_parent->d_subdirs) {
213 struct list_head *tmp = next;
214 struct dentry *dentry = list_entry(tmp, struct dentry, d_child);
215 next = tmp->next;
211 hlist_for_each_entry_from(dentry, d_sib) {
212 struct tracefs_inode *ti;
216
213
214 /* Note, getdents() can add a cursor dentry with no inode */
215 if (!dentry->d_inode)
216 continue;
217
217 spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
218
219 change_gid(dentry, gid);
220
218 spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
219
220 change_gid(dentry, gid);
221
221 if (!list_empty(&dentry->d_subdirs)) {
222 /* If this is the events directory, update that too */
223 ti = get_tracefs(dentry->d_inode);
224 if (ti && (ti->flags & TRACEFS_EVENT_INODE))
225 eventfs_update_gid(dentry, gid);
226
227 if (!hlist_empty(&dentry->d_children)) {
222 spin_unlock(&this_parent->d_lock);
223 spin_release(&dentry->d_lock.dep_map, _RET_IP_);
224 this_parent = dentry;
225 spin_acquire(&this_parent->d_lock.dep_map, 0, 1, _RET_IP_);
226 goto repeat;
227 }
228 spin_unlock(&dentry->d_lock);
229 }
230 /*
231 * All done at this level ... ascend and resume the search.
232 */
233 rcu_read_lock();
234ascend:
235 if (this_parent != parent) {
228 spin_unlock(&this_parent->d_lock);
229 spin_release(&dentry->d_lock.dep_map, _RET_IP_);
230 this_parent = dentry;
231 spin_acquire(&this_parent->d_lock.dep_map, 0, 1, _RET_IP_);
232 goto repeat;
233 }
234 spin_unlock(&dentry->d_lock);
235 }
236 /*
237 * All done at this level ... ascend and resume the search.
238 */
239 rcu_read_lock();
240ascend:
241 if (this_parent != parent) {
236 struct dentry *child = this_parent;
237 this_parent = child->d_parent;
242 dentry = this_parent;
243 this_parent = dentry->d_parent;
238
244
239 spin_unlock(&child->d_lock);
245 spin_unlock(&dentry->d_lock);
240 spin_lock(&this_parent->d_lock);
241
242 /* go into the first sibling still alive */
246 spin_lock(&this_parent->d_lock);
247
248 /* go into the first sibling still alive */
243 do {
244 next = child->d_child.next;
245 if (next == &this_parent->d_subdirs)
246 goto ascend;
247 child = list_entry(next, struct dentry, d_child);
248 } while (unlikely(child->d_flags & DCACHE_DENTRY_KILLED));
249 rcu_read_unlock();
250 goto resume;
249 hlist_for_each_entry_continue(dentry, d_sib) {
250 if (likely(!(dentry->d_flags & DCACHE_DENTRY_KILLED))) {
251 rcu_read_unlock();
252 goto resume;
253 }
254 }
255 goto ascend;
251 }
252 rcu_read_unlock();
253 spin_unlock(&this_parent->d_lock);
254 return;
255}
256
257static int tracefs_parse_options(char *data, struct tracefs_mount_opts *opts)
258{

--- 518 unchanged lines hidden ---
256 }
257 rcu_read_unlock();
258 spin_unlock(&this_parent->d_lock);
259 return;
260}
261
262static int tracefs_parse_options(char *data, struct tracefs_mount_opts *opts)
263{

--- 518 unchanged lines hidden ---