diff -u --recursive --new-file linux-2.4.11/fs/lockd/clntproc.c linux-2.4.11-deadlck/fs/lockd/clntproc.c --- linux-2.4.11/fs/lockd/clntproc.c Wed Oct 10 23:50:16 2001 +++ linux-2.4.11-deadlck/fs/lockd/clntproc.c Thu Oct 11 00:00:48 2001 @@ -6,6 +6,7 @@ * Copyright (C) 1996, Olaf Kirch */ +#include #include #include #include @@ -676,6 +677,18 @@ case NLM_LCK_BLOCKED: printk(KERN_NOTICE "lockd: unexpected status NLM_BLOCKED\n"); return -ENOLCK; +#ifdef CONFIG_LOCKD_V4 + case NLM_DEADLCK: + return -EDEADLK; + case NLM_ROFS: + return -EROFS; + case NLM_STALE_FH: + return -ESTALE; + case NLM_FBIG: + return -EOVERFLOW; + case NLM_FAILED: + return -ENOLCK; +#endif } printk(KERN_NOTICE "lockd: unexpected server status %d\n", status); return -ENOLCK; diff -u --recursive --new-file linux-2.4.11/fs/lockd/svclock.c linux-2.4.11-deadlck/fs/lockd/svclock.c --- linux-2.4.11/fs/lockd/svclock.c Tue Nov 7 19:18:57 2000 +++ linux-2.4.11-deadlck/fs/lockd/svclock.c Thu Oct 11 00:00:48 2001 @@ -31,9 +31,14 @@ #include #include - #define NLMDBG_FACILITY NLMDBG_SVCLOCK +#ifdef CONFIG_LOCKD_V4 +#define nlm_deadlock nlm4_deadlock +#else +#define nlm_deadlock nlm_lck_denied +#endif + static void nlmsvc_insert_block(struct nlm_block *block, unsigned long); static int nlmsvc_remove_block(struct nlm_block *block); static void nlmsvc_grant_callback(struct rpc_task *task); @@ -330,12 +335,7 @@ case 0: return nlm_granted; case EDEADLK: -#ifdef CONFIG_LOCKD_V4 - return nlm4_deadlock; /* will be downgraded to lck_deined if this - * is a NLMv1,3 request */ -#else - /* no applicable NLM status */ -#endif + return nlm_deadlock; case EAGAIN: return nlm_lck_denied; default: /* includes ENOLCK */ @@ -346,6 +346,11 @@ if (!wait) { up(&file->f_sema); return nlm_lck_denied; + } + + if (posix_locks_deadlock(&lock->fl, conflock)) { + up(&file->f_sema); + return nlm_deadlock; } /* If we don't have a block, create and initialize it. Then diff -u --recursive --new-file linux-2.4.11/fs/lockd/svcproc.c linux-2.4.11-deadlck/fs/lockd/svcproc.c --- linux-2.4.11/fs/lockd/svcproc.c Wed Oct 10 23:50:16 2001 +++ linux-2.4.11-deadlck/fs/lockd/svcproc.c Thu Oct 11 00:06:51 2001 @@ -29,17 +29,20 @@ static u32 cast_to_nlm(u32 status, u32 vers) { - + /* Note: status is assumed to be in network byte order !!! */ if (vers != 4){ - switch(ntohl(status)){ - case NLM_LCK_GRANTED: - case NLM_LCK_DENIED: - case NLM_LCK_DENIED_NOLOCKS: - case NLM_LCK_BLOCKED: - case NLM_LCK_DENIED_GRACE_PERIOD: + switch (status) { + case nlm_granted: + case nlm_lck_denied: + case nlm_lck_denied_nolocks: + case nlm_lck_blocked: + case nlm_lck_denied_grace_period: + break; + case nlm4_deadlock: + status = nlm_lck_denied; break; default: - status = NLM_LCK_DENIED_NOLOCKS; + status = nlm_lck_denied_nolocks; } } diff -u --recursive --new-file linux-2.4.11/fs/locks.c linux-2.4.11-deadlck/fs/locks.c --- linux-2.4.11/fs/locks.c Sun Sep 23 18:48:01 2001 +++ linux-2.4.11-deadlck/fs/locks.c Thu Oct 11 00:00:48 2001 @@ -548,7 +548,7 @@ return (1); default: - printk("locks_conflict(): impossible lock type - %d\n", + printk(KERN_ERR "locks_conflict(): impossible lock type - %d\n", caller_fl->fl_type); break; } @@ -660,7 +660,7 @@ * from a broken NFS client. But broken NFS clients have a lot more to * worry about than proper deadlock detection anyway... --okir */ -static int posix_locks_deadlock(struct file_lock *caller_fl, +int posix_locks_deadlock(struct file_lock *caller_fl, struct file_lock *block_fl) { struct list_head *tmp; @@ -715,6 +715,9 @@ struct file_lock *new_fl = locks_alloc_lock(0); int error; + if (new_fl == NULL) + return -ENOMEM; + new_fl->fl_owner = current->files; new_fl->fl_pid = current->pid; new_fl->fl_file = filp; @@ -1428,6 +1431,9 @@ struct inode *inode; int error; + if (file_lock == NULL) + return -ENOLCK; + /* * This might block, so we do it before checking the inode. */ @@ -1580,6 +1586,9 @@ struct flock64 flock; struct inode *inode; int error; + + if (file_lock == NULL) + return -ENOLCK; /* * This might block, so we do it before checking the inode. diff -u --recursive --new-file linux-2.4.11/include/linux/fs.h linux-2.4.11-deadlck/include/linux/fs.h --- linux-2.4.11/include/linux/fs.h Wed Oct 10 23:59:44 2001 +++ linux-2.4.11-deadlck/include/linux/fs.h Thu Oct 11 00:11:15 2001 @@ -603,6 +603,7 @@ extern int posix_lock_file(struct file *, struct file_lock *, unsigned int); extern void posix_block_lock(struct file_lock *, struct file_lock *); extern void posix_unblock_lock(struct file_lock *); +extern int posix_locks_deadlock(struct file_lock *, struct file_lock *); extern int __get_lease(struct inode *inode, unsigned int flags); extern time_t lease_get_mtime(struct inode *); extern int lock_may_read(struct inode *, loff_t start, unsigned long count); diff -u --recursive --new-file linux-2.4.11/kernel/ksyms.c linux-2.4.11-deadlck/kernel/ksyms.c --- linux-2.4.11/kernel/ksyms.c Wed Oct 10 23:50:23 2001 +++ linux-2.4.11-deadlck/kernel/ksyms.c Thu Oct 11 00:00:48 2001 @@ -223,6 +223,7 @@ EXPORT_SYMBOL(posix_test_lock); EXPORT_SYMBOL(posix_block_lock); EXPORT_SYMBOL(posix_unblock_lock); +EXPORT_SYMBOL(posix_locks_deadlock); EXPORT_SYMBOL(locks_mandatory_area); EXPORT_SYMBOL(dput); EXPORT_SYMBOL(have_submounts);