Re: fcntl: F_SETLEASE/F_RDLCK question

From: William A.(Andy) Adamson
Date: Tue May 03 2005 - 08:57:32 EST


> Hi Michael,
>
> On Tue, 3 May 2005 12:00:18 +0200 (MEST) "Michael Kerrisk" <mtk-lkml@xxxxxxx> wrote:
> >
> > Indeed the problem referred to is fixed, but it looks like another
> > one may have been introduced.
> >
> > It now appears (I tested on 2.6.11.6) that if a process opens
> > a file O_RDWR and then tries to place a read lease via that
> > file descriptor, then the F_SETLEASE fails with EAGAIN,
> > even though no other process has the file open for writing.
> > (On the other hand, if the process opens the file
> > O_WRONLY, then it can place either a read or a write lease.
> > This is how I think things always worked, but it seems
> > inconsistent with the aforementioned behaviour.)
> >
> > Some further testing showed the following (both open()
> > and fcntl(F_SETLEASE) from same process):
> >
> > open() | lease requested
> > flag | F_RDLCK | F_WRLCK
> > ---------+----------+----------
> > O_RDONLY | okay | okay
> > O_WRONLY | EAGAIN | okay
> > O_RDWR | EAGAIN | okay
> >
> > This seems strange (I imagine the caller should be excluded
> > from the list of processes being checked to see if the file
> > is opened for writing), and differs from earlier kernel
> > versions. What is the intended behaviour here?
>
> Thanks for the testing. My expectation is that it shouldn't matter how
> the current process opened the file for either type of lease. However,
> you are right (IMHO) that the current process should *not* be counted as a
> writer in the case of trying to obtain a F_RDLCK lease.

i believe the current implementation is correct. opening a file for write
means that you can not have a read lease, caller included.


-->Andy


>
> How does this (completely untested, not even compiled) patch look?
>
> diff -ruNP linus/fs/locks.c linus-leases.1/fs/locks.c
> --- linus/fs/locks.c 2005-04-26 15:38:00.000000000 +1000
> +++ linus-leases.1/fs/locks.c 2005-05-03 23:00:14.000000000 +1000
> @@ -1288,7 +1288,8 @@
> goto out;
>
> error = -EAGAIN;
> - if ((arg == F_RDLCK) && (atomic_read(&inode->i_writecount) > 0))
> + if ((arg == F_RDLCK) && (atomic_read(&inode->i_writecount)
> + > ((filp->f_mode & FMODE_WRITE) ? 1 : 0)))
> goto out;
> if ((arg == F_WRLCK)
> && ((atomic_read(&dentry->d_count) > 1)
>
> --
> Cheers,
> Stephen Rothwell sfr@xxxxxxxxxxxxxxxx
> http://www.canb.auug.org.au/~sfr/


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