Read denied because it uses the OPEN state instead of the LOCK state
From Linux NFS
Contents |
About
- Kernel version:
- bug 14501
- Reported by: Jean-Louis ROCHETTE (October 28, 2009)
- Fixed by:
Symptoms
- Source code to reproduce
- When a single process does open(), fcntl(F_SETLK), read(), the read operation uses the LOCK state and succeeds.
- If the process opens the file and then forks a child process, and the child process locks the file and reads it, the read operation is done with the OPEN state, and the server denies the file access.
- Incorrect output from the test case:
jlr@newlnxjlr(53) g++ lock_read.cxx -o lock_read jlr@newlnxjlr(54) lock_read /mnt/ns801s2_v4/testfile.0 Waiting for child 0 to exit Error while reading [Input/output error] iteration=0, pid=30977 Waiting for child 1 to exit Error while reading [Input/output error] iteration=0, pid=30979 Error while reading [Input/output error] iteration=0, pid=30978 Waiting for child 2 to exit Exiting parent
- Expected output from the test case:
jlr@vmfc12jlr(22) g++ lock_read.cxx -o lock_read jlr@vmfc12jlr(32) lock_read /mnt/ns801s2_v4/testfile.0 Waiting for child 0 to exit Successfully completed 5 iterations, pid=16405 Waiting for child 1 to exit Successfully completed 5 iterations, pid=16406 Waiting for child 2 to exit Successfully completed 5 iterations, pid=16407 Exiting parent
Cause
- We do not keep a record of the lockowner in the struct nfs_page (that tracks dirty regions on a page).
- nfs_create_request fails to record the posix lock owner (i.e. the value of current->files), and so when we get round to actually writing out the data to the server, we have lost track of the correct lock stateid to use.
Resolution
- 1 struct nfs_open_context per lockowner in the case where the application uses locking.
- That way we do not have to increase the size of each individual struct nfs_page.
- This problem was fixed by commit [1]