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);
|
locks_delete_lock(before);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* Replace the old lock with the new one.
|
/*
|
||||||
* Wake up anybody waiting for the old one,
|
* Replace the old lock with new_fl, and
|
||||||
* as the change in lock type might satisfy
|
* remove the old one. It's safe to do the
|
||||||
* their needs.
|
* 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);
|
error = -ENOLCK;
|
||||||
fl->fl_start = request->fl_start;
|
if (!new_fl)
|
||||||
fl->fl_end = request->fl_end;
|
goto out;
|
||||||
fl->fl_type = request->fl_type;
|
locks_copy_lock(new_fl, request);
|
||||||
locks_release_private(fl);
|
request = new_fl;
|
||||||
locks_copy_private(fl, request);
|
new_fl = NULL;
|
||||||
request = fl;
|
locks_delete_lock(before);
|
||||||
|
locks_insert_lock(before, request);
|
||||||
added = true;
|
added = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue