On Thu, Mar 1, 2012 at 2:17 PM, Li Zefan <lizf@xxxxxxxxxxxxxx> wrote: > > -static void cgroup_clear_directory(struct dentry *dentry) > +static void cgroup_clear_directory(struct dentry *dentry, bool remove_all, > + unsigned long removed_bits) > { > - struct list_head *node; > + LIST_HEAD(head); > + struct dentry *d, *node; > > BUG_ON(!mutex_is_locked(&dentry->d_inode->i_mutex)); > + > spin_lock(&dentry->d_lock); > - node = dentry->d_subdirs.next; > - while (node != &dentry->d_subdirs) { > - struct dentry *d = list_entry(node, struct dentry, d_u.d_child); > + list_for_each_entry_safe(d, node, &dentry->d_subdirs, d_u.d_child) { > + struct cftype *cft = d->d_fsdata; > + > + if (!remove_all && cft->subsys && > + !test_bit(cft->subsys->subsys_id, &removed_bits)) > + continue; > > spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED); > - list_del_init(node); > + list_move(&d->d_u.d_child, &head); > if (d->d_inode) { > /* This should never be called on a cgroup > * directory with child cgroups */ > BUG_ON(d->d_inode->i_mode & S_IFDIR); > dget_dlock(d); > - spin_unlock(&d->d_lock); > - spin_unlock(&dentry->d_lock); > + } > + spin_unlock(&d->d_lock); > + } > + spin_unlock(&dentry->d_lock); > + Safe to process isolated entries without dentry->d_lock held? -hd > + list_for_each_entry_safe(d, node, &head, d_u.d_child) { > + spin_lock(&d->d_lock); > + list_del_init(&d->d_u.d_child); > + spin_unlock(&d->d_lock); > + if (d->d_inode) { > d_delete(d); > simple_unlink(dentry->d_inode, d); > dput(d); > - spin_lock(&dentry->d_lock); > - } else > - spin_unlock(&d->d_lock); > - node = dentry->d_subdirs.next; > + } > } > - spin_unlock(&dentry->d_lock); > } > ��.n��������+%������w��{.n������.����n�r������&��z�ޗ�zf���h���~����������_��+v���)ߣ�