From: Arnd Bergmann <arnd@arndb.de>
To: Christoph Hellwig <hch@infradead.org>
Cc: linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org,
Frederic Weisbecker <fweisbec@gmail.com>,
John Kacur <jkacur@redhat.com>, Ingo Molnar <mingo@elte.hu>,
Jan Blunck <jblunck@suse.de>, Julia Lawall <julia@diku.dk>
Subject: Re: [RFC 4/5] BKL: use no BKL in llseek
Date: Fri, 4 Jun 2010 01:47:26 +0200 [thread overview]
Message-ID: <201006040147.27070.arnd@arndb.de> (raw)
In-Reply-To: <20100603070608.GA12123@infradead.org>
On Thursday 03 June 2010 09:06:08 Christoph Hellwig wrote:
> On Thu, Jun 03, 2010 at 02:13:18AM +0200, Arnd Bergmann wrote:
> > We have shown that the BKL in default_llseek and other
> > llseek operations never protects against concurrent access
> > from another function:
>
> From VFS POV no to the default_llseek conversion. As told you and
> others of the BKL brigade don't change this thing but get rid of it
> entirely. I was under the impression we had agreed on a road map
> for that anyway. Please don't forget that overall kernel improvement
> should at least be a side effect of your big sweap and clean.
Well, the two things (killing the BKL and killing default_llseek)
are not as related as make it appear: as I've shown, nothing that
currently implicitly uses default_llseek depends on the BKL,
so we could kill them in either order.
Nevertheless, you are right that default_llseek needs to go as well,
and I've put some effort into this. This is a coccinelle patch
that tries to find the correct llseek method for each file_operation
(default_llseek, no_llseek, noop_llseek). It does not find the
correct answer in each case, and is likely much more complicated
than it needs to be.
Julia, can you take a look? This currently outputs more than
one .llseek= line for some operations and fails to make detect
some cases that I think it should find.
Arnd
---
@ open1 @
identifier nested_open;
identifier nso ~= "nonseekable_open";
@@
nested_open(...)
{
...
nso(...)
...
}
@ open @
identifier open_f;
identifier i, f;
identifier nso ~= "nonseekable_open";
identifier open1.nested_open;
@@
int open_f(struct inode *i, struct file *f)
{
...
(
nso(...)
|
nested_open(...)
)
...
}
@ read @
identifier read_f;
identifier f, p, s, off;
type ssize_t, size_t, loff_t;
expression E;
identifier func;
@@
ssize_t read_f(struct file *f, char *p, size_t s, loff_t *off)
{
(
... *off = E...
|
... func(..., off, ...) ...
|
... E = *off ...
)
}
@ read_no_fpos @
identifier read_f;
identifier f, p, s, off;
type ssize_t, size_t, loff_t;
@@
ssize_t read_f(struct file *f, char *p, size_t s, loff_t *off)
{
... when != off
}
@ write @
identifier write_f;
identifier f, p, s, off;
type ssize_t, size_t, loff_t;
expression E;
identifier func;
@@
ssize_t write_f(struct file *f, const char *p, size_t s, loff_t *off)
{
... *off = E...
|
... func(..., off, ...) ...
|
... E = *off ...
)
}
@ write_no_fpos @
identifier write_f;
identifier f, p, s, off;
type ssize_t, size_t, loff_t;
@@
ssize_t write_f(struct file *f, const char *p, size_t s, loff_t *off)
{
... when != off
}
@ fops0 @
identifier fops;
@@
struct file_operations fops = {
...
};
@ has_llseek depends on fops0 @
identifier fops0.fops;
identifier llseek_f;
@@
struct file_operations fops = {
...
.llseek = llseek_f,
...
};
@ has_read depends on fops0 @
identifier fops0.fops;
identifier read_f;
@@
struct file_operations fops = {
...
.read = read_f,
...
};
@ has_write depends on fops0 @
identifier fops0.fops;
identifier write_f;
@@
struct file_operations fops = {
...
.write = write_f,
...
};
@ has_open depends on fops0 @
identifier fops0.fops;
identifier open_f;
@@
struct file_operations fops = {
...
.open = open_f,
...
};
// does not work properly -- this always matches...
@ nonseekable1 depends on !has_llseek && has_open @
identifier fops;
identifier nso ~= "nonseekable_open";
@@
// fops directly use nonseekable_open
struct file_operations fops = {
... .open = nso, ...
+.llseek = no_llseek, /* nonseekable */
};
@ nonseekable2 depends on !has_llseek @
identifier fops;
identifier open.open_f;
@@
// fops use open which calls nonseekable_open
struct file_operations fops = {
... .open = open_f, ...
+.llseek = no_llseek, /* open uses nonseekable */
};
@ fops1 depends on !has_llseek && !nonseekable2 @
identifier fops0.fops;
identifier read.read_f;
identifier readdir_e;
@@
(
// read fops use offset
struct file_operations fops = {
... .read = read_f, ...
+.llseek = default_llseek, /* read accesses f_pos */
};
|
// any other fop is used that changes pos
struct file_operations fops = {
... .readdir = readdir_e, ...
+.llseek = default_llseek, /* readdir is present */
};
)
@ fops2 depends on !fops1 && !has_llseek && !nonseekable2 @
identifier fops0.fops;
identifier write.write_f;
@@
// write fops use offset
struct file_operations fops = {
... .write = write_f, ...
+ .llseek = default_llseek, /* write accesses f_pos */
};
@ fops3 depends on !fops1 && !fops2 && !has_llseek && !nonseekable2 @
identifier fops;
identifier read_no_fpos.read_f;
identifier write_no_fpos.write_f;
@@
// write fops use offset
struct file_operations fops = {
...
.write = write_f,
.read = read_f,
...
+.llseek = noop_llseek, /* read and write both use no f_pos */
};
@ depends on has_write && !has_read && !fops1 && !fops2 && !has_llseek && nonseekable2 @
identifier fops0.fops;
identifier write_no_fpos.write_f;
@@
struct file_operations fops = {
... .write = write_f, ...
+.llseek = noop_llseek, /* write uses no f_pos */
};
@ depends on has_read && !has_write && !fops1 && !fops2 && !has_llseek && !nonseekable2 @
identifier fops0.fops;
identifier read_no_fpos.read_f;
@@
struct file_operations fops = {
... .read = read_f, ...
+.llseek = noop_llseek, /* read uses no f_pos */
};
@ depends on !has_read && !has_write && !fops1 && !fops2 && !has_llseek && !nonseekable2@
identifier fops0.fops;
@@
struct file_operations fops = {
...
+.llseek = noop_llseek, /* no read or write fn */
};
next prev parent reply other threads:[~2010-06-03 23:47 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-06-03 0:13 [RFC 0/5] BKL removal leftovers Arnd Bergmann
2010-06-03 0:13 ` [RFC 1/5] BKL: autoconvert trivial users to private mutex Arnd Bergmann
2010-06-03 0:35 ` Frederic Weisbecker
2010-06-03 16:50 ` Greg KH
2010-06-03 0:13 ` [RFC 2/5] BKL: remove the BKL from kernel init code Arnd Bergmann
2010-06-03 1:07 ` Steven Rostedt
2010-06-03 0:13 ` [RFC 3/5] BKL: do not take BKL in do_coredump Arnd Bergmann
2010-06-03 0:13 ` [RFC 4/5] BKL: use no BKL in llseek Arnd Bergmann
2010-06-03 0:38 ` Frederic Weisbecker
2010-06-03 7:08 ` Christoph Hellwig
2010-06-03 7:06 ` Christoph Hellwig
2010-06-03 23:47 ` Arnd Bergmann [this message]
2010-06-03 7:41 ` Geert Uytterhoeven
2010-06-03 0:13 ` [RFC 5/5] BKL: introduce CONFIG_BKL Arnd Bergmann
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=201006040147.27070.arnd@arndb.de \
--to=arnd@arndb.de \
--cc=fweisbec@gmail.com \
--cc=hch@infradead.org \
--cc=jblunck@suse.de \
--cc=jkacur@redhat.com \
--cc=julia@diku.dk \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=mingo@elte.hu \
/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.