locks: don't reuse file_lock in __posix_lock_file
Currently in the case where a new file lock completely replaces the old one, we end up overwriting the existing lock with the new info. This means that we have to call fl_release_private inside i_lock. Change the code to instead copy the info to new_fl, insert that lock into the correct spot and then delete the old lock. In a later patch, we'll defer the freeing of the old lock until after the i_lock has been dropped. Acked-by: J. Bruce Fields <bfields@fieldses.org> Signed-off-by: Jeff Layton <jlayton@primarydata.com>
This commit is contained in:
parent
566709bd62
commit
b84d49f944
25
fs/locks.c
25
fs/locks.c
|
@ -1022,18 +1022,21 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str
|
|||
locks_delete_lock(before);
|
||||
continue;
|
||||
}
|
||||
/* Replace the old lock with the new one.
|
||||
* Wake up anybody waiting for the old one,
|
||||
* as the change in lock type might satisfy
|
||||
* their needs.
|
||||
/*
|
||||
* Replace the old lock with new_fl, and
|
||||
* remove the old one. It's safe to do the
|
||||
* insert here since we know that we won't be
|
||||
* using new_fl later, and that the lock is
|
||||
* just replacing an existing lock.
|
||||
*/
|
||||
locks_wake_up_blocks(fl);
|
||||
fl->fl_start = request->fl_start;
|
||||
fl->fl_end = request->fl_end;
|
||||
fl->fl_type = request->fl_type;
|
||||
locks_release_private(fl);
|
||||
locks_copy_private(fl, request);
|
||||
request = fl;
|
||||
error = -ENOLCK;
|
||||
if (!new_fl)
|
||||
goto out;
|
||||
locks_copy_lock(new_fl, request);
|
||||
request = new_fl;
|
||||
new_fl = NULL;
|
||||
locks_delete_lock(before);
|
||||
locks_insert_lock(before, request);
|
||||
added = true;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue