Commit b044105d authored by Linus Torvalds's avatar Linus Torvalds

Fix close() vs posix lock race

A threaded app that posix-locks and closes the same file
in two threads concurrently may result in a posix lock
that was never visible to the closer, and that thus needs
cleanup on the final fput.

Handle it together with the regular flocks.
parent cf54a5af
...@@ -1766,7 +1766,12 @@ void locks_remove_flock(struct file *filp) ...@@ -1766,7 +1766,12 @@ void locks_remove_flock(struct file *filp)
while ((fl = *before) != NULL) { while ((fl = *before) != NULL) {
if (fl->fl_file == filp) { if (fl->fl_file == filp) {
if (IS_FLOCK(fl)) { /*
* We might have a POSIX lock that was created at the same time
* the filp was closed for the last time. Just remove that too,
* regardless of ownership, since nobody can own it.
*/
if (IS_FLOCK(fl) || IS_POSIX(fl)) {
locks_delete_lock(before); locks_delete_lock(before);
continue; continue;
} }
...@@ -1774,9 +1779,7 @@ void locks_remove_flock(struct file *filp) ...@@ -1774,9 +1779,7 @@ void locks_remove_flock(struct file *filp)
lease_modify(before, F_UNLCK); lease_modify(before, F_UNLCK);
continue; continue;
} }
/* FL_POSIX locks of this process have already been /* What? */
* removed in filp_close->locks_remove_posix.
*/
BUG(); BUG();
} }
before = &fl->fl_next; before = &fl->fl_next;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment