diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/cifs/file.c | 10 | ||||
-rw-r--r-- | fs/locks.c | 3 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 2 |
3 files changed, 12 insertions, 3 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 159fcc56dc2d..0f7dc228c10a 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -835,13 +835,21 @@ cifs_posix_lock_set(struct file *file, struct file_lock *flock) 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; } diff --git a/fs/locks.c b/fs/locks.c index 637694bf3a03..0d68f1f81799 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -510,12 +510,13 @@ static void __locks_delete_block(struct file_lock *waiter) /* */ -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 diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index d9457002ca04..757293b66dbb 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -3618,7 +3618,7 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu if (acl_len > buflen) goto out_free; _copy_from_pages(buf, pages, res.acl_data_offset, - res.acl_len); + acl_len); } ret = acl_len; out_free: |