Different behavior of POSIX file locks depending on cache mode

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,

I've been hunting down a bug exhibited by Libreoffice regarding POSIX file 
locks in conjunction with CIFS mounts. In short: just before saving, it 
reopens a file on which it already holds a file lock (via another file 
descriptor in the same process) in order to read from it to create a backup 
copy... but the read call fails.

I've been in discussion with Andrew Bartlett for a little while regarding this 
issue and, after exploring several venues, he advised me to send an email to 
this list in order to get more opinions about it.

The latest discovery we did was that the cache option on the mountpoint seems 
to impact the behavior of the POSIX file locks. I made a minimal test 
application (attached to this email) which basically does the following:
 * open a file for read/write
 * set a POSIX write lock on the whole file
 * open the file a second time and try to read from it
 * open the file a third time and try to write to it

It assumes there is already some text in the file. Also, as it goes it outputs 
information about the calls.

The output I get is the following with cache=strict on the mount:
---
Testing with /mnt/foo
Got new file descriptor 3
Lock set: 1
Second file descriptor 4
Read from second fd: x count: -1
Third file descriptor 5
Wrote to third fd: -1
---
 
If I'm using cache=none:
---
Testing with /mnt/foo
Got new file descriptor 3
Lock set: 1
Second file descriptor 4
Read from second fd: b count: 1
Third file descriptor 5
Wrote to third fd: 1
---

That's the surprising behavior which prompted the email on this list. Is it 
somehow intended that the cache option would impact the semantic of the file 
locks? At least it caught me by surprise and I wouldn't expect such a 
difference in behavior.

Now, since the POSIX locks are process wide, I would have expected to have the 
output I'm getting for the "cache=none" case to be also the one I'm getting 
for the "cache=strict" case.

I'm looking forward to feedback on this one. I really wonder if we missed 
something obvious or if there is some kind of bug in the cifs driver.

Regards.
-- 
Kévin Ottens
kevin.ottens@xxxxxxxxxx
+33 7 57 08 95 13
#include <iostream>

#include <unistd.h>
#include <fcntl.h>

using namespace std;

int main(int argc, char **argv) {
    if (argc <= 1) {
        cout << "Please provide path to a file" << endl;
        return 1;
    }   

    const auto filepath = argv[1];
    cout << "Testing with " << filepath << endl;

    int fd = open(filepath, O_RDWR);
    cout << "Got new file descriptor " << fd << endl;


    struct flock lock;
    lock.l_type = F_WRLCK;
    lock.l_whence = SEEK_SET;
    lock.l_start = 0;
    lock.l_len = 0;
    int code = fcntl(fd, F_SETLK, &lock);
    cout << "Lock set: " << (code == 0) << endl;

    int fd2 = open(filepath, O_RDONLY);
    cout << "Second file descriptor " << fd2 << endl;

    char c = 'x';
    int count = read(fd2, &c, 1);
    cout << "Read from second fd: " << c << " count: " << count << endl;

    int fd3 = open(filepath, O_WRONLY|O_APPEND);
    cout << "Third file descriptor " << fd3 << endl;

    c = 'o';
    count = write(fd3, &c, 1);
    cout << "Wrote to third fd: " << count << endl;
}

[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux