public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* What protects f_pos?
@ 2000-11-04 22:16 David Wragg
  2000-11-11 23:54 ` tytso
  0 siblings, 1 reply; 6+ messages in thread
From: David Wragg @ 2000-11-04 22:16 UTC (permalink / raw)
  To: linux-kernel

Since f_pos of struct file is a loff_t, on 32-bit architectures it
needs a lock to make accesses atomic (or some more sophisticated form
of protection).  But looking in 2.4.0-test10, there doesn't seem to be
any such lock.

The llseek op is called with the Big Kernel Lock, but unlike in 2.2,
the read and write ops are called without any locks held, and so
generic_file_{read|write} make unprotected accesses to f_pos (through
their ppos argument).

Is this something for Ted's todo list?

David
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: What protects f_pos?
  2000-11-04 22:16 What protects f_pos? David Wragg
@ 2000-11-11 23:54 ` tytso
  2000-11-12  1:56   ` David Wragg
  0 siblings, 1 reply; 6+ messages in thread
From: tytso @ 2000-11-11 23:54 UTC (permalink / raw)
  To: dpw; +Cc: linux-kernel

   From: David Wragg <dpw@doc.ic.ac.uk>
   Date: 	04 Nov 2000 22:16:18 +0000

   Since f_pos of struct file is a loff_t, on 32-bit architectures it
   needs a lock to make accesses atomic (or some more sophisticated form
   of protection).  But looking in 2.4.0-test10, there doesn't seem to be
   any such lock.

   The llseek op is called with the Big Kernel Lock, but unlike in 2.2,
   the read and write ops are called without any locks held, and so
   generic_file_{read|write} make unprotected accesses to f_pos (through
   their ppos argument).

This looks like it's a bug to me....  although if you have multiple
threads hitting a file descriptor at the same time, you're pretty much
asking for trouble.

						- Ted
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: What protects f_pos?
  2000-11-11 23:54 ` tytso
@ 2000-11-12  1:56   ` David Wragg
  2000-11-12 22:27     ` David Schwartz
  0 siblings, 1 reply; 6+ messages in thread
From: David Wragg @ 2000-11-12  1:56 UTC (permalink / raw)
  To: tytso; +Cc: linux-kernel

tytso@mit.edu writes:
> This looks like it's a bug to me....  although if you have multiple
> threads hitting a file descriptor at the same time, you're pretty much
> asking for trouble.

Yes, I haven't been able to come up with an example that might trigger
this that wasn't dubious to begin with.  I'll raise this again at a
convenient time during 2.5.

David

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* RE: What protects f_pos?
  2000-11-12  1:56   ` David Wragg
@ 2000-11-12 22:27     ` David Schwartz
  2000-11-13 15:22       ` David Wragg
  0 siblings, 1 reply; 6+ messages in thread
From: David Schwartz @ 2000-11-12 22:27 UTC (permalink / raw)
  To: David Wragg, tytso; +Cc: linux-kernel


> tytso@mit.edu writes:
> > This looks like it's a bug to me....  although if you have multiple
> > threads hitting a file descriptor at the same time, you're pretty much
> > asking for trouble.
>
> Yes, I haven't been able to come up with an example that might trigger
> this that wasn't dubious to begin with.  I'll raise this again at a
> convenient time during 2.5.
>
> David

	Suppose you had a multithreaded program that used a configuration file with
a group of fixed-length blocks indicating what work it had to do. Each
thread read a block from the file and then did the work. One might think
that there's no need to protect the file descriptor with a mutex.

	DS

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: What protects f_pos?
  2000-11-12 22:27     ` David Schwartz
@ 2000-11-13 15:22       ` David Wragg
  2000-11-13 15:44         ` Richard B. Johnson
  0 siblings, 1 reply; 6+ messages in thread
From: David Wragg @ 2000-11-13 15:22 UTC (permalink / raw)
  To: David Schwartz; +Cc: tytso, linux-kernel

"David Schwartz" <davids@webmaster.com> writes:
> 	Suppose you had a multithreaded program that used a
> configuration file with a group of fixed-length blocks indicating what
> work it had to do. Each thread read a block from the file and then did
> the work. One might think that there's no need to protect the file
> descriptor with a mutex.

I don't think that this will work, due to a separate non-atomicity
issue with f_pos.  The generic file read and write implementations do
not atomically update f_pos.  They read f_pos to determine the file
offset to use, then manipulate the page cache (possibly sleeping on
I/O), and only then set f_pos to the appropriate updated value.  So
the example you suggest, with two threads, could do something like:

          Thread 1                           Thread 2

   sys_read(fd, buf1, len)

      off = file->f_pos                sys_read(fd, buf2, len)

         read to buf1                     off = file->f_pos

    file->f_pos = off + len                 read to buf2

                                        file->f_pos = off + len


So both threads read the same block, and f_pos only gets incremented
once.

(Pipes and sockets are a different matter, of course.)

2.2 has the same issue, since although the BKL is held, it will get
dropped if one of the threads sleeps on I/O.  (Earlier Linux versions
might well have the same issue, but I don't have the source around to
check.)

POSIX doesn't seem to bar this behaviour.  From 6.4.1.2:

    On a regular file or other file capable of seeking, read() shall
    start at a position in the file given by the file offset
    associated with fildes.  Before successful return from read(), the
    file offset shall be incremented by the number of bytes actually
    read.

Which is exactly what Linux does.  I can't find text anywhere else in
POSIX.1 that strengthens that condition for the case of multiple
processes/threads reading from the same file.  I'll try to find out
what the Austin Group has to say about this.


David
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: What protects f_pos?
  2000-11-13 15:22       ` David Wragg
@ 2000-11-13 15:44         ` Richard B. Johnson
  0 siblings, 0 replies; 6+ messages in thread
From: Richard B. Johnson @ 2000-11-13 15:44 UTC (permalink / raw)
  To: David Wragg; +Cc: David Schwartz, tytso, linux-kernel

On 13 Nov 2000, David Wragg wrote:

> "David Schwartz" <davids@webmaster.com> writes:
[SNIPPED....]


> 
> So both threads read the same block, and f_pos only gets incremented
> once.
> 
> (Pipes and sockets are a different matter, of course.)
> 
> 2.2 has the same issue, since although the BKL is held, it will get
> dropped if one of the threads sleeps on I/O.  (Earlier Linux versions
> might well have the same issue, but I don't have the source around to
> check.)
> 
> POSIX doesn't seem to bar this behaviour.  From 6.4.1.2:
> 
>     On a regular file or other file capable of seeking, read() shall
>     start at a position in the file given by the file offset
>     associated with fildes.  Before successful return from read(), the
>     file offset shall be incremented by the number of bytes actually
>     read.
> 
> Which is exactly what Linux does.  I can't find text anywhere else in
> POSIX.1 that strengthens that condition for the case of multiple
> processes/threads reading from the same file.  I'll try to find out
> what the Austin Group has to say about this.
> 

Anything that uses f_pos has a problem with multiple readers or multiple
writers. That's one of the problems that file locking is supposed to
handle. An application has got to know how to access a file when it can
be changed by another.

There is a more far-reaching problem that sooner or later will get us.
That's the built-in problem with lseek. Lseek is supposed to return -1
if it failed, with errno being set appropriately. This, in principle,
does not prevent seeking to the last byte of the file as long as errno
is checked by the caller if the function returns -1.

Linux, internally, uses "-errno" as a return value to show an
error. So what happens if we `lseek` to -EBADF or -EFAULT, etc.

An otherwise empty lseek routine in a module, that does nothing except
return the input value, will show errors once the offsets corresponding
to negative errno values are reached.


Cheers,
Dick Johnson

Penguin : Linux version 2.4.0 on an i686 machine (799.54 BogoMips).

"Memory is like gasoline. You use it up when you are running. Of
course you get it all back when you reboot..."; Actual explanation
obtained from the Micro$oft help desk.


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2000-11-13 15:46 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2000-11-04 22:16 What protects f_pos? David Wragg
2000-11-11 23:54 ` tytso
2000-11-12  1:56   ` David Wragg
2000-11-12 22:27     ` David Schwartz
2000-11-13 15:22       ` David Wragg
2000-11-13 15:44         ` Richard B. Johnson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox