if ((flock->fl_flags & FL_POSIX) == 0)
                return rc;
 
+try_again:
        mutex_lock(&cinode->lock_mutex);
        if (!cinode->can_cache_brlcks) {
                mutex_unlock(&cinode->lock_mutex);
                return rc;
        }
-       rc = posix_lock_file_wait(file, flock);
+
+       rc = posix_lock_file(file, flock, NULL);
        mutex_unlock(&cinode->lock_mutex);
+       if (rc == FILE_LOCK_DEFERRED) {
+               rc = wait_event_interruptible(flock->fl_wait, !flock->fl_next);
+               if (!rc)
+                       goto try_again;
+               locks_delete_block(flock);
+       }
        return rc;
 }
 
 
 
 /*
  */
-static void locks_delete_block(struct file_lock *waiter)
+void locks_delete_block(struct file_lock *waiter)
 {
        lock_flocks();
        __locks_delete_block(waiter);
        unlock_flocks();
 }
+EXPORT_SYMBOL(locks_delete_block);
 
 /* Insert waiter into blocker's block list.
  * We use a circular list so that processes can be easily woken up in
 
 extern int lease_modify(struct file_lock **, int);
 extern int lock_may_read(struct inode *, loff_t start, unsigned long count);
 extern int lock_may_write(struct inode *, loff_t start, unsigned long count);
+extern void locks_delete_block(struct file_lock *waiter);
 extern void lock_flocks(void);
 extern void unlock_flocks(void);
 #else /* !CONFIG_FILE_LOCKING */
        return 1;
 }
 
+static inline void locks_delete_block(struct file_lock *waiter)
+{
+}
+
 static inline void lock_flocks(void)
 {
 }