/**
* locks_mandatory_locked - Check for an active lock
- * @inode: the file to check
+ * @file: the file to check
*
* Searches the inode's list of locks to find any POSIX locks which conflict.
* This function is called from locks_verify_locked() only.
*/
-int locks_mandatory_locked(struct inode *inode)
+int locks_mandatory_locked(struct file *file)
{
+ struct inode *inode = file_inode(file);
fl_owner_t owner = current->files;
struct file_lock *fl;
for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
if (!IS_POSIX(fl))
continue;
- if (fl->fl_owner != owner)
+ if (fl->fl_owner != owner && fl->fl_owner != (fl_owner_t)file)
break;
}
spin_unlock(&inode->i_lock);
{
struct file_lock fl;
int error;
+ bool sleep = false;
locks_init_lock(&fl);
- fl.fl_owner = current->files;
fl.fl_pid = current->tgid;
fl.fl_file = filp;
fl.fl_flags = FL_POSIX | FL_ACCESS;
if (filp && !(filp->f_flags & O_NONBLOCK))
- fl.fl_flags |= FL_SLEEP;
+ sleep = true;
fl.fl_type = (read_write == FLOCK_VERIFY_WRITE) ? F_WRLCK : F_RDLCK;
fl.fl_start = offset;
fl.fl_end = offset + count - 1;
for (;;) {
+ if (filp) {
+ fl.fl_owner = (fl_owner_t)filp;
+ fl.fl_flags &= ~FL_SLEEP;
+ error = __posix_lock_file(inode, &fl, NULL);
+ if (!error)
+ break;
+ }
+
+ if (sleep)
+ fl.fl_flags |= FL_SLEEP;
+ fl.fl_owner = current->files;
error = __posix_lock_file(inode, &fl, NULL);
if (error != FILE_LOCK_DEFERRED)
break;
goto out;
if (cmd == F_GETLKP) {
+ error = -EINVAL;
+ if (flock.l_pid != 0)
+ goto out;
+
cmd = F_GETLK;
file_lock.fl_flags |= FL_FILE_PVT;
file_lock.fl_owner = (fl_owner_t)filp;
*/
switch (cmd) {
case F_SETLKP:
+ error = -EINVAL;
+ if (flock.l_pid != 0)
+ goto out;
+
cmd = F_SETLK;
file_lock->fl_flags |= FL_FILE_PVT;
file_lock->fl_owner = (fl_owner_t)filp;
break;
case F_SETLKPW:
+ error = -EINVAL;
+ if (flock.l_pid != 0)
+ goto out;
+
cmd = F_SETLKW;
file_lock->fl_flags |= FL_FILE_PVT;
file_lock->fl_owner = (fl_owner_t)filp;
goto out;
if (cmd == F_GETLKP) {
+ error = -EINVAL;
+ if (flock.l_pid != 0)
+ goto out;
+
cmd = F_GETLK64;
file_lock.fl_flags |= FL_FILE_PVT;
file_lock.fl_owner = (fl_owner_t)filp;
*/
switch (cmd) {
case F_SETLKP:
+ error = -EINVAL;
+ if (flock.l_pid != 0)
+ goto out;
+
cmd = F_SETLK64;
file_lock->fl_flags |= FL_FILE_PVT;
file_lock->fl_owner = (fl_owner_t)filp;
break;
case F_SETLKPW:
+ error = -EINVAL;
+ if (flock.l_pid != 0)
+ goto out;
+
cmd = F_SETLKW64;
file_lock->fl_flags |= FL_FILE_PVT;
file_lock->fl_owner = (fl_owner_t)filp;