From mboxrd@z Thu Jan 1 00:00:00 1970 From: Eric Paris Subject: Re: [patch 09/33] fs: dcache scale dentry refcount Date: Sun, 6 Sep 2009 14:01:05 -0400 Message-ID: <7e0fb38c0909061101t6b4f337cvf691814c28bcf50e@mail.gmail.com> References: <20090904065142.114706411@nick.local0.net> <20090904065535.281876981@nick.local0.net> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: QUOTED-PRINTABLE Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org To: npiggin@suse.de Return-path: Received: from mail-vw0-f195.google.com ([209.85.212.195]:50972 "EHLO mail-vw0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758068AbZIFSBD convert rfc822-to-8bit (ORCPT ); Sun, 6 Sep 2009 14:01:03 -0400 In-Reply-To: <20090904065535.281876981@nick.local0.net> Sender: linux-fsdevel-owner@vger.kernel.org List-ID: On Fri, Sep 4, 2009 at 2:51 AM, wrote: > Make d_count non-atomic and protect it with d_lock. This allows us to > ensure a 0 refcount dentry remains 0 without dcache_lock. It is also > fairly natural when we start protecting many other dentry members wit= h > d_lock. > +struct dentry *dget_parent(struct dentry *dentry) > +{ > + =A0 =A0 =A0 struct dentry *ret; > + > +repeat: > + =A0 =A0 =A0 spin_lock(&dentry->d_lock); > + =A0 =A0 =A0 ret =3D dentry->d_parent; > + =A0 =A0 =A0 if (!ret) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto out; > + =A0 =A0 =A0 if (!spin_trylock(&ret->d_lock)) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 spin_unlock(&dentry->d_lock); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto repeat; > + =A0 =A0 =A0 } > + =A0 =A0 =A0 BUG_ON(!ret->d_count); > + =A0 =A0 =A0 ret->d_count++; > + =A0 =A0 =A0 spin_unlock(&ret->d_lock); > +out: > + =A0 =A0 =A0 spin_unlock(&dentry->d_lock); > + =A0 =A0 =A0 return ret; > +} > +EXPORT_SYMBOL(dget_parent); > Index: linux-2.6/fs/notify/inotify/inotify.c > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- linux-2.6.orig/fs/notify/inotify/inotify.c > +++ linux-2.6/fs/notify/inotify/inotify.c > @@ -339,18 +339,26 @@ void inotify_dentry_parent_queue_event(s > =A0 =A0 =A0 =A0if (!(dentry->d_flags & DCACHE_INOTIFY_PARENT_WATCHED)= ) > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return; > > +again: > =A0 =A0 =A0 =A0spin_lock(&dentry->d_lock); > =A0 =A0 =A0 =A0parent =3D dentry->d_parent; > + =A0 =A0 =A0 if (!spin_trylock(&parent->d_lock)) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 spin_unlock(&dentry->d_lock); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto again; > + =A0 =A0 =A0 } > =A0 =A0 =A0 =A0inode =3D parent->d_inode; > > =A0 =A0 =A0 =A0if (inotify_inode_watched(inode)) { > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 dget(parent); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 dget_dlock(parent); > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0spin_unlock(&dentry->d_lock); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 spin_unlock(&parent->d_lock); > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0inotify_inode_queue_event(inode, mask,= cookie, name, > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 =A0 =A0dentry->d_inode); > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0dput(parent); > - =A0 =A0 =A0 } else > + =A0 =A0 =A0 } else { > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0spin_unlock(&dentry->d_lock); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 spin_unlock(&parent->d_lock); > + =A0 =A0 =A0 } I don't think I understand why in both of these cases you don't need to check for dentry->d_parent =3D=3D dentry > Index: linux-2.6/fs/notify/fsnotify.c > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- linux-2.6.orig/fs/notify/fsnotify.c > +++ linux-2.6/fs/notify/fsnotify.c > @@ -87,13 +87,18 @@ void __fsnotify_parent(struct dentry *de > =A0 =A0 =A0 =A0if (!(dentry->d_flags & DCACHE_FSNOTIFY_PARENT_WATCHED= )) > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return; > > +again: > =A0 =A0 =A0 =A0spin_lock(&dentry->d_lock); > =A0 =A0 =A0 =A0parent =3D dentry->d_parent; > + =A0 =A0 =A0 if (parent !=3D dentry && !spin_trylock(&parent->d_lock= )) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 spin_unlock(&dentry->d_lock); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto again; > + =A0 =A0 =A0 } > =A0 =A0 =A0 =A0p_inode =3D parent->d_inode; > > =A0 =A0 =A0 =A0if (fsnotify_inode_watches_children(p_inode)) { > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (p_inode->i_fsnotify_mask & mask) { > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 dget(parent); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 dget_dlock(parent); > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0send =3D true; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0} > =A0 =A0 =A0 =A0} else { And yet in this case we do check for dentry->d_parent =3D=3D dentry. (= my unknowing self thinks we'd want to check in all places) -Eric -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel= " in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html