diff -urNX dontdiff linux-2.4.2/fs/lockd/svclock.c linux-willy/fs/lockd/svclock.c
--- linux-2.4.2/fs/lockd/svclock.c Tue Nov 7 11:18:57 2000
+++ linux-willy/fs/lockd/svclock.c Fri Mar 2 00:21:00 2001
@@ -237,7 +237,7 @@
if (unlock && block->b_granted) {
dprintk("lockd: deleting granted lock\n");
fl->fl_type = F_UNLCK;
- posix_lock_file(&block->b_file->f_file, fl, 0);
+ posix_lock_file(&block->b_file->f_file, fl, F_GETLK);
block->b_granted = 0;
} else {
dprintk("lockd: unblocking blocked lock\n");
@@ -319,7 +319,7 @@
again:
if (!(conflock = posix_test_lock(&file->f_file, &lock->fl))) {
- error = posix_lock_file(&file->f_file, &lock->fl, 0);
+ error = posix_lock_file(&file->f_file, &lock->fl, F_GETLK);
if (block)
nlmsvc_delete_block(block, 0);
@@ -343,32 +343,39 @@
}
}
- if (!wait) {
- up(&file->f_sema);
- return nlm_lck_denied;
- }
+ error = nlm_lck_denied;
+
+ if (!wait)
+ goto out;
/* If we don't have a block, create and initialize it. Then
* retry because we may have slept in kmalloc. */
if (block == NULL) {
dprintk("lockd: blocking on this lock (allocating).\n");
- if (!(block = nlmsvc_create_block(rqstp, file, lock, cookie)))
- return nlm_lck_denied_nolocks;
- goto again;
+ error = nlm_lck_denied_nolocks;
+ block = nlmsvc_create_block(rqstp, file, lock, cookie);
+ if (block)
+ goto again;
+ goto out;
}
/* Append to list of blocked */
nlmsvc_insert_block(block, NLM_NEVER);
+ error = nlm_lck_blocked;
+
if (list_empty(&block->b_call.a_args.lock.fl.fl_block)) {
/* Now add block to block list of the conflicting lock
if we haven't done so. */
dprintk("lockd: blocking on this lock.\n");
- posix_block_lock(conflock, &block->b_call.a_args.lock.fl);
+ if (posix_block_lock(conflock, &block->b_call.a_args.lock.fl))
+ error = nlm_lck_denied;
}
+ out:
+
up(&file->f_sema);
- return nlm_lck_blocked;
+ return error;
}
/*
@@ -423,7 +430,7 @@
nlmsvc_cancel_blocked(file, lock);
lock->fl.fl_type = F_UNLCK;
- error = posix_lock_file(&file->f_file, &lock->fl, 0);
+ error = posix_lock_file(&file->f_file, &lock->fl, F_GETLK);
return (error < 0)? nlm_lck_denied_nolocks : nlm_granted;
}
@@ -528,7 +535,7 @@
* following yields an error, this is most probably due to low
* memory. Retry the lock in a few seconds.
*/
- if ((error = posix_lock_file(&file->f_file, &lock->fl, 0)) < 0) {
+ if ((error = posix_lock_file(&file->f_file, &lock->fl, F_GETLK)) < 0) {
printk(KERN_WARNING "lockd: unexpected error %d in %s!\n",
-error, __FUNCTION__);
nlmsvc_insert_block(block, 10 * HZ);
diff -urNX dontdiff linux-2.4.2/fs/lockd/svcsubs.c linux-willy/fs/lockd/svcsubs.c
--- linux-2.4.2/fs/lockd/svcsubs.c Fri Jun 23 22:12:53 2000
+++ linux-willy/fs/lockd/svcsubs.c Fri Mar 2 00:20:25 2001
@@ -176,7 +176,7 @@
lock.fl_type = F_UNLCK;
lock.fl_start = 0;
lock.fl_end = OFFSET_MAX;
- if (posix_lock_file(&file->f_file, &lock, 0) < 0) {
+ if (posix_lock_file(&file->f_file, &lock, F_GETLK) < 0) {
printk("lockd: unlock failure in %s:%d\n",
__FILE__, __LINE__);
return 1;
diff -urNX dontdiff linux-2.4.2/fs/locks.c linux-willy/fs/locks.c
--- linux-2.4.2/fs/locks.c Fri Feb 9 12:29:44 2001
+++ linux-willy/fs/locks.c Fri Mar 2 00:30:48 2001
@@ -618,6 +618,21 @@
{
struct file_lock *cfl;
+ if (filp->f_op && filp->f_op->lock) {
+ int error = filp->f_op->lock(filp, F_GETLK, fl);
+ if (error < 0) {
+ return ERR_PTR(error);
+ } else if (error == LOCK_USE_CLNT) {
+ /* NFS with no locking - 2.0 compatibility. Drop
+ * out and use client-side locking instead.
+ */
+ } else if (fl->fl_type == F_UNLCK) {
+ return NULL;
+ } else {
+ return fl;
+ }
+ }
+
lock_kernel();
for (cfl = filp->f_dentry->d_inode->i_flock; cfl; cfl = cfl->fl_next) {
if (!(cfl->fl_flags & FL_POSIX))
@@ -627,7 +642,7 @@
}
unlock_kernel();
- return (cfl);
+ return cfl;
}
/* This function tests for deadlock condition before putting a process to
@@ -839,7 +854,7 @@
*/
int posix_lock_file(struct file *filp, struct file_lock *caller,
- unsigned int wait)
+ unsigned int cmd)
{
struct file_lock *fl;
struct file_lock *new_fl, *new_fl2;
@@ -848,6 +863,7 @@
struct file_lock **before;
struct inode * inode = filp->f_dentry->d_inode;
int error, added = 0;
+ int wait = (cmd == F_SETLKW) || (cmd == F_SETLKW64);
/*
* We may need two file_lock structures for this operation,
@@ -859,6 +875,13 @@
if (!(new_fl && new_fl2))
goto out;
+ /* Check the underlying filesystem will allow us to lock */
+ if (filp->f_op && filp->f_op->lock != NULL) {
+ error = filp->f_op->lock(filp, cmd, caller);
+ if (error < 0)
+ goto out;
+ }
+
lock_kernel();
if (caller->fl_type != F_UNLCK) {
repeat:
@@ -1356,17 +1379,10 @@
if (!flock_to_posix_lock(filp, &file_lock, &flock))
goto out_putf;
- if (filp->f_op && filp->f_op->lock) {
- error = filp->f_op->lock(filp, F_GETLK, &file_lock);
- if (error < 0)
- goto out_putf;
- else if (error == LOCK_USE_CLNT)
- /* Bypass for NFS with no locking - 2.0.36 compat */
- fl = posix_test_lock(filp, &file_lock);
- else
- fl = (file_lock.fl_type == F_UNLCK ? NULL : &file_lock);
- } else {
- fl = posix_test_lock(filp, &file_lock);
+ fl = posix_test_lock(filp, &file_lock);
+ if (IS_ERR(fl)) {
+ error = PTR_ERR(fl);
+ goto out_putf;
}
flock.l_type = F_UNLCK;
@@ -1480,12 +1496,7 @@
goto out_putf;
}
- if (filp->f_op && filp->f_op->lock != NULL) {
- error = filp->f_op->lock(filp, cmd, file_lock);
- if (error < 0)
- goto out_putf;
- }
- error = posix_lock_file(filp, file_lock, cmd == F_SETLKW);
+ error = posix_lock_file(filp, file_lock, cmd);
out_putf:
fput(filp);
@@ -1521,17 +1532,10 @@
if (!flock64_to_posix_lock(filp, &file_lock, &flock))
goto out_putf;
- if (filp->f_op && filp->f_op->lock) {
- error = filp->f_op->lock(filp, F_GETLK, &file_lock);
- if (error < 0)
- goto out_putf;
- else if (error == LOCK_USE_CLNT)
- /* Bypass for NFS with no locking - 2.0.36 compat */
- fl = posix_test_lock(filp, &file_lock);
- else
- fl = (file_lock.fl_type == F_UNLCK ? NULL : &file_lock);
- } else {
- fl = posix_test_lock(filp, &file_lock);
+ fl = posix_test_lock(filp, &file_lock);
+ if (IS_ERR(fl)) {
+ error = PTR_ERR(fl);
+ goto out_putf;
}
flock.l_type = F_UNLCK;
@@ -1618,12 +1622,7 @@
goto out_putf;
}
- if (filp->f_op && filp->f_op->lock != NULL) {
- error = filp->f_op->lock(filp, cmd, file_lock);
- if (error < 0)
- goto out_putf;
- }
- error = posix_lock_file(filp, file_lock, cmd == F_SETLKW64);
+ error = posix_lock_file(filp, file_lock, cmd);
out_putf:
fput(filp);
@@ -1695,15 +1694,21 @@
/**
* posix_block_lock - blocks waiting for a file lock
- * @blocker: the lock which is blocking
- * @waiter: the lock which conflicts and has to wait
+ * @blocker: the existing lock which has been granted
+ * @waiter: the new lock which must sleep
*
- * lockd needs to block waiting for locks.
+ * This routine is for the use of lockd alone. It allows lockd to block
+ * waiting for locks by putting the lock in the list of blocking locks
+ * without actually going to sleep itself.
*/
-void
+int
posix_block_lock(struct file_lock *blocker, struct file_lock *waiter)
{
- locks_insert_block(blocker, waiter);
+ int error;
+ error = posix_locks_deadlock(waiter, blocker);
+ if (!error)
+ locks_insert_block(blocker, waiter);
+ return error;
}
/**
diff -urNX dontdiff linux-2.4.2/include/linux/fs.h linux-willy/include/linux/fs.h
--- linux-2.4.2/include/linux/fs.h Wed Feb 21 17:09:58 2001
+++ linux-willy/include/linux/fs.h Thu Mar 1 23:57:06 2001
@@ -568,7 +568,7 @@
extern void locks_remove_flock(struct file *);
extern struct file_lock *posix_test_lock(struct file *, struct file_lock *);
extern int posix_lock_file(struct file *, struct file_lock *, unsigned int);
-extern void posix_block_lock(struct file_lock *, struct file_lock *);
+extern int posix_block_lock(struct file_lock *, struct file_lock *);
extern void posix_unblock_lock(struct file_lock *);
extern int __get_lease(struct inode *inode, unsigned int flags);
extern time_t lease_get_mtime(struct inode *);