[lkml]   [2010]   [Mar]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
Patch in this message
Subject[PATCH] firewire: char device files are not seekable (BKL removal)
The <linux/firewire-cdev.h> character device file ABI is based on
- ioctl() to initiate actions,
- read() to consume events,
- mmap() for isochronous I/O DMA buffers.
lseek(), pread(), pwrite() (or any kind of write() at all) on the other
hand are not applicable to /dev/fw* device files.

Alas, whereas for example file_operations.write == NULL causes write()
to be failed with an appropriate error, file_operations.llseek == NULL
causes fs/read_write.c::default_llseek to be called on lseek() per

This looks like not doing any harm, but it grabs the Big Kernel Lock.
We don't want that, and we should return an error on lseek() and
friends. This is provided by fs/read_write.c::no_llseek which we get if
we clear the FMODE_LSEEK (and FMODE_PREAD, FMODE_PWRITE) flag by means
of nonseekable_open().

Side note: The firewire-cdev interface has always been free of any BKL
usage apart from this oversight regarding default_llseek (and from
involuntary BKL usage by open() in older kernels).

Signed-off-by: Stefan Richter <>

Somebody correct me if I got anything wrong in my patch description.

This patch is motivated by Arnd's
"bkl removal: make unlocked_ioctl mandatory";a=blobdiff;f=drivers/firewire/core-cdev.c;h=4464b9dc01a8c69258a1e8880e9a390f17420b6c;hp=4eeaed57e2197a0dd5f0cab7cffa4713eaf2ec96;hb=05e7753338045e9ee3950b2da032c5e5774efa90;hpb=03165e1d096afb4b1d9cfccdad66eed038121cec
"BKL removal: mark remaining users as 'depends on BKL'";a=blobdiff;f=drivers/firewire/Kconfig;h=ae6d45900230dfbdc32c099d6a026ecfd0a6f5c2;hp=a9371b36a9b9c3074f5b31d7bdacf1bda72a15dd;hb=abb83d8fe5f8dcc8fca09bd9117429f73e1417e0;hpb=33c014b118f45516113d4b6823e40ea6f834dc6a

drivers/firewire/core-cdev.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

Index: b/drivers/firewire/core-cdev.c
--- a/drivers/firewire/core-cdev.c
+++ b/drivers/firewire/core-cdev.c
@@ -226,7 +226,7 @@ static int fw_device_op_open(struct inod
list_add_tail(&client->link, &device->client_list);

- return 0;
+ return nonseekable_open(inode, file);

static void queue_event(struct client *client, struct event *event,
Stefan Richter
-=====-==-=- --== ==-==

 \ /
  Last update: 2010-03-27 10:19    [W:0.099 / U:7.160 seconds]
©2003-2018 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site