All of lore.kernel.org
 help / color / mirror / Atom feed
From: Oleg Nesterov <oleg@redhat.com>
To: Jonathan Corbet <corbet@lwn.net>
Cc: LKML <linux-kernel@vger.kernel.org>,
	Andi Kleen <andi@firstfloor.org>,
	Alan Cox <alan@lxorguk.ukuu.org.uk>,
	Al Viro <viro@ZenIV.linux.org.uk>,
	bfields@fieldses.org, xfs-masters@oss.sgi.com
Subject: Re: RFC: Fix f_flags races without the BKL
Date: Mon, 29 Dec 2008 13:41:51 +0100	[thread overview]
Message-ID: <20081229124151.GA29634@redhat.com> (raw)
In-Reply-To: <20081229041352.6bbdf57c@tpl>

On 12/29, Jonathan Corbet wrote:
>
> After pondering for a while, I couldn't come up with anything better than a
> global file->f_flags mutex.  There's no point in bloating struct file with
> a mutex just for this purpose; it's hard to imagine that there will be any
> real contention for this lock.

Yes, this patch is simple and straightforward, but now we can't change
->f_flags in non-preempible context. And the global lock is not very
nice anyway.

Once again, can't we use O_LOCK_FLAGS bit? I agree, it is a bit ugly,
and I won't insist if you don't like is.

	static inline int try_lock_f_flags(struct file *file)
	{
		return !test_and_set_bit(O_LOCK_FLAGS, file->f_flags);
	}

	static inline set_f_flags(struct file *file, unsigned int flags)
	{
		file->f_flags = flags & ~O_LOCK_FLAGS;
	}

Now, nobody should change ->f_flags directly (except create/open
pathes. For example, ioctl_fionbio() should be changed:

		if (try_lock_f_flags(filp)) {
			if (on)
				set_f_flags(filp, filp->f_flags | flag);
			else
				set_f_flags(filp, filp->f_flags & ~flag);
		}

If try_lock_f_flags() fails we do nothing, as if the current owner of
O_LOCK_FLAGS changes ->f_flags after us.

What do you think?


> @@ -1116,6 +1116,7 @@ static int blkdev_open(struct inode * inode, struct file * filp)
>  	 * binary needs it. We might want to drop this workaround
>  	 * during an unstable branch.
>  	 */
> +	lock_file_flags();
>  	filp->f_flags |= O_LARGEFILE;
>
>  	if (filp->f_flags & O_NDELAY)
> @@ -1124,6 +1125,7 @@ static int blkdev_open(struct inode * inode, struct file * filp)
>  		filp->f_mode |= FMODE_EXCL;
>  	if ((filp->f_flags & O_ACCMODE) == 3)
>  		filp->f_mode |= FMODE_WRITE_IOCTL;
> +	unlock_file_flags();

do we really need lock_file_flags() here?

> diff --git a/fs/pipe.c b/fs/pipe.c
> index 7aea8b8..23ae227 100644
> --- a/fs/pipe.c
> +++ b/fs/pipe.c
> @@ -945,7 +945,9 @@ struct file *create_write_pipe(int flags)
>  		goto err_dentry;
>  	f->f_mapping = inode->i_mapping;
>
> +	lock_file_flags();
>  	f->f_flags = O_WRONLY | (flags & O_NONBLOCK);
> +	unlock_file_flags();
>  	f->f_version = 0;
>
>  	return f;
> @@ -981,7 +983,9 @@ struct file *create_read_pipe(struct file *wrf, int flags)
>  	f->f_mapping = wrf->f_path.dentry->d_inode->i_mapping;
>
>  	f->f_pos = 0;
> +	lock_file_flags();
>  	f->f_flags = O_RDONLY | (flags & O_NONBLOCK);
> +	unlock_file_flags();

Ditto. Nobody can see this file yet, we can change ->f_flags lockless.

But please correct me if I am wrong, I know nothing about fs/.

Oleg.


  parent reply	other threads:[~2008-12-29 12:44 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-12-29 11:13 RFC: Fix f_flags races without the BKL Jonathan Corbet
2008-12-29 11:57 ` Sam Ravnborg
2008-12-30 12:49   ` Jonathan Corbet
2008-12-29 12:41 ` Oleg Nesterov [this message]
2008-12-29 15:27   ` Andi Kleen
2008-12-30 12:59     ` Jonathan Corbet
2008-12-30 13:04       ` [xfs-masters] " Christoph Hellwig
2008-12-30 13:37         ` Andi Kleen
2008-12-30 14:48           ` Christoph Hellwig
2008-12-31  9:52             ` Jonathan Corbet
2008-12-30 14:55       ` Andi Kleen
2009-01-08 23:28   ` Jonathan Corbet
2009-01-09 10:08     ` Oleg Nesterov
2009-01-09 13:18       ` Jonathan Corbet
2009-01-09 14:03         ` Oleg Nesterov
2009-01-09 15:09         ` Andi Kleen
2008-12-29 12:50 ` [xfs-masters] " Christoph Hellwig
2008-12-29 15:15   ` Andi Kleen
2009-01-02 18:29     ` Al Viro
2009-01-02 18:27   ` Al Viro
2009-01-02 18:42 ` Al Viro
2009-01-02 19:09   ` Oleg Nesterov
2009-01-02 19:54     ` Al Viro
2009-01-03 16:45       ` Oleg Nesterov

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=20081229124151.GA29634@redhat.com \
    --to=oleg@redhat.com \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=andi@firstfloor.org \
    --cc=bfields@fieldses.org \
    --cc=corbet@lwn.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=viro@ZenIV.linux.org.uk \
    --cc=xfs-masters@oss.sgi.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.