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 --- |