; }  /* Apply the lock described by l to an open file descriptor.  * This implements both the F_SETLK and F_SETLKW commands of fcntl().  */ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd,   struct flock __user *l) {  struct file_lock *file_lock = locks_alloc_lock();  struct flock flock;  struct inode *inode;  struct file *f;  int error;   if (file_lock == NULL)   return -ENOLCK;   /*   * This might block, so we do it before checking the inode.   */  error = -EFAULT;  if (copy_from_user(&flock, l, sizeof(flock)))   goto out;   inode = file_inode(filp);   /* Don't allow mandatory locks on files that may be memory mapped   * and shared.   */  if (mandatory_lock(inode) && mapping_writably_mapped(filp->f_mapping)) {   error = -EAGAIN;   goto out;  }   error = flock_to_posix_lock(filp, file_lock, &flock);  if (error)   goto out;   error = check_fmode_for_setlk(file_lock);  if (error)   goto out;   /*   * If the cmd is requesting file-private locks, then set the   * FL_OFDLCK flag and override the owner.   */  switch (cmd) {  case F_OFD_SETLK:   error = -EINVAL;   if (flock.l_pid != 0)    goto out;    cmd = F_SETLK;   file_lock->fl_flags |= FL_OFDLCK;   file_lock->fl_owner = filp;   break;  case F_OFD_SETLKW:   error = -EINVAL;   if (flock.l_pid != 0)    goto out;    cmd = F_SETLKW;   file_lock->fl_flags |= FL_OFDLCK;   file_lock->fl_owner = filp;   /* Fallthrough */  case F_SETLKW:   file_lock->fl_flags |= FL_SLEEP;  }   error = do_lock_file_wait(filp, cmd, file_lock);   /*   * Attempt to detect a close/fcntl race and recover by   * releasing the lock that was just acquired.   */  if (!error && file_lock->fl_type != F_UNLCK) {   /*    * We need that spin_lock here - it prevents reordering between    * update of i_flctx->flc_posix and check for it done in    * close(). rcu_read_lock() wouldn't do.    */   spin_lock(&current->files->file_lock);   f = fcheck(fd);   spin_unlock(&current->files->file_lock);   if (f != filp) {    file_lock->fl_type = F_UNLCK;    error = do_lock_file_wait(filp, cmd, file_lock);    WARN_ON_ONCE(error);    error = -EBADF;   }  } out:  locks_free_lock(file_lock);  return error; } 