All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sunil Mushran <sunil.mushran@oracle.com>
To: ocfs2-devel@oss.oracle.com
Subject: [Ocfs2-devel] [Ocfs2-users] ocfs or configfs bug ?
Date: Wed, 18 May 2011 11:36:59 -0700	[thread overview]
Message-ID: <4DD411CB.4090308@oracle.com> (raw)
In-Reply-To: <20110518111223.GB7330@noexit.corp.google.com>

On 05/18/2011 04:12 AM, Joel Becker wrote:
> On Wed, May 18, 2011 at 03:49:56AM -0700, Joel Becker wrote:
>> 	sysfs_mutex is peppered everywhere.  It's rather ugly, I think.
>> I am thinking about how the code reads.  I admit I also don't like that
>> sysfs_mutex serializes all accesses to the sysfs directory tree, but I'd
>> be OK with that as a stopgap solution if the code only read better.
> 	Can you test this?
>
> Joel


So it did run for far longer. But then hit the following.

http://oss.oracle.com/~smushran/configfs_oops_20110518.txt

BTW, this is not new. I was running into it earlier too. Albeit
less frequently than readdir.


>  From 24307aa1e707b31613be92deaba7990e16bc1aec Mon Sep 17 00:00:00 2001
> From: Joel Becker<jlbec@evilplan.org>
> Date: Wed, 18 May 2011 04:08:16 -0700
> Subject: [PATCH] configfs: Fix race between configfs_readdir() and configfs_d_iput()
>
> configfs_readdir() will use the existing inode numbers of inodes in the
> dcache, but it makes them up for attribute files that aren't currently
> instantiated.  There is a race where a closing attribute file can be
> tearing down at the same time as configfs_readdir() is trying to get its
> inode number.
>
> We want to get the inode number of open attribute files, because they
> should match while instantiated.  We can't lock down the transition
> where dentry->d_inode is set to NULL, so we just check for NULL there.
> We can, however, ensure that an inode we find isn't iput() in
> configfs_d_iput() until after we've accessed it.
>
> Signed-off-by: Joel Becker<jlbec@evilplan.org>
> ---
>   fs/configfs/dir.c |   33 ++++++++++++++++++++++++++++-----
>   1 files changed, 28 insertions(+), 5 deletions(-)
>
> diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c
> index b11d734..9a37a9b 100644
> --- a/fs/configfs/dir.c
> +++ b/fs/configfs/dir.c
> @@ -53,11 +53,14 @@ DEFINE_SPINLOCK(configfs_dirent_lock);
>   static void configfs_d_iput(struct dentry * dentry,
>   			    struct inode * inode)
>   {
> -	struct configfs_dirent * sd = dentry->d_fsdata;
> +	struct configfs_dirent *sd = dentry->d_fsdata;
>
>   	if (sd) {
>   		BUG_ON(sd->s_dentry != dentry);
> +		/* Coordinate with configfs_readdir */
> +		spin_lock(&configfs_dirent_lock);
>   		sd->s_dentry = NULL;
> +		spin_unlock(&configfs_dirent_lock);
>   		configfs_put(sd);
>   	}
>   	iput(inode);
> @@ -1546,7 +1549,7 @@ static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir
>   	struct configfs_dirent * parent_sd = dentry->d_fsdata;
>   	struct configfs_dirent *cursor = filp->private_data;
>   	struct list_head *p, *q =&cursor->s_sibling;
> -	ino_t ino;
> +	ino_t ino = 0;
>   	int i = filp->f_pos;
>
>   	switch (i) {
> @@ -1574,6 +1577,7 @@ static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir
>   				struct configfs_dirent *next;
>   				const char * name;
>   				int len;
> +				struct inode *inode = NULL;
>
>   				next = list_entry(p, struct configfs_dirent,
>   						   s_sibling);
> @@ -1582,9 +1586,28 @@ static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir
>
>   				name = configfs_get_name(next);
>   				len = strlen(name);
> -				if (next->s_dentry)
> -					ino = next->s_dentry->d_inode->i_ino;
> -				else
> +
> +				/*
> +				 * We'll have a dentry and an inode for
> +				 * PINNED items and for open attribute
> +				 * files.  We lock here to prevent a race
> +				 * with configfs_d_iput() clearing
> +				 * s_dentry before calling iput().
> +				 *
> +				 * Why do we go to the trouble?  If
> +				 * someone has an attribute file open,
> +				 * the inode number should match until
> +				 * they close it.  Beyond that, we don't
> +				 * care.
> +				 */
> +				spin_lock(&configfs_dirent_lock);
> +				dentry = next->s_dentry;
> +				if (dentry)
> +					inode = dentry->d_inode;
> +				if (inode)
> +					ino = inode->i_ino;
> +				spin_unlock(&configfs_dirent_lock);
> +				if (!inode)
>   					ino = iunique(configfs_sb, 2);
>
>   				if (filldir(dirent, name, len, filp->f_pos, ino,

  reply	other threads:[~2011-05-18 18:36 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <4DADA228.5050209@bull.net>
     [not found] ` <20110419194840.GA27826@noexit>
2011-04-20  0:20   ` [Ocfs2-devel] [Ocfs2-users] ocfs or configfs bug ? Sunil Mushran
2011-05-11  1:38     ` Sunil Mushran
2011-05-18 10:49       ` Joel Becker
2011-05-18 11:12         ` Joel Becker
2011-05-18 18:36           ` Sunil Mushran [this message]
2011-05-18 19:11             ` Joel Becker
2011-05-18 20:08               ` Sunil Mushran

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4DD411CB.4090308@oracle.com \
    --to=sunil.mushran@oracle.com \
    --cc=ocfs2-devel@oss.oracle.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.