From: David Teigland Add DLM_LKF_FORCEUNLOCK so device.c doesn't have to muck about with locks that are in progress. Signed-off-by: Patrick Caulfield Signed-off-by: David Teigland Signed-off-by: Andrew Morton --- drivers/dlm/device.c | 22 ++-------------------- drivers/dlm/lock.c | 8 +++++++- include/linux/dlm.h | 7 +++++++ 3 files changed, 16 insertions(+), 21 deletions(-) diff -puN drivers/dlm/device.c~dlm-device-interface-dlm-force-unlock drivers/dlm/device.c --- devel/drivers/dlm/device.c~dlm-device-interface-dlm-force-unlock 2005-11-07 19:20:20.000000000 -0800 +++ devel-akpm/drivers/dlm/device.c 2005-11-07 19:20:26.000000000 -0800 @@ -546,37 +546,19 @@ static int dlm_close(struct inode *inode clear_bit(LI_FLAG_COMPLETE, &li.li_flags); - /* If it's not granted then cancel the request. - * If the lock was WAITING then it will be dropped, - * if it was converting then it will be reverted to GRANTED, - * then we will unlock it. - */ - - if (old_li->li_grmode != old_li->li_rqmode) - flags = DLM_LKF_CANCEL; - + flags = DLM_LKF_FORCEUNLOCK; if (old_li->li_grmode >= DLM_LOCK_PW) flags |= DLM_LKF_IVVALBLK; status = dlm_unlock(f->fi_ls->ls_lockspace, old_li->li_lksb.sb_lkid, flags, &li.li_lksb, &li); + /* Must wait for it to complete as the next lock could be its * parent */ if (status == 0) wait_for_ast(&li); - /* If it was waiting for a conversion, it will - now be granted so we can unlock it properly */ - if (flags & DLM_LKF_CANCEL) { - flags &= ~DLM_LKF_CANCEL; - clear_bit(LI_FLAG_COMPLETE, &li.li_flags); - status = dlm_unlock(f->fi_ls->ls_lockspace, - old_li->li_lksb.sb_lkid, flags, - &li.li_lksb, &li); - if (status == 0) - wait_for_ast(&li); - } /* Unlock suceeded, free the lock_info struct. */ if (status == 0) release_lockinfo(old_li); diff -puN drivers/dlm/lock.c~dlm-device-interface-dlm-force-unlock drivers/dlm/lock.c --- devel/drivers/dlm/lock.c~dlm-device-interface-dlm-force-unlock 2005-11-07 19:20:20.000000000 -0800 +++ devel-akpm/drivers/dlm/lock.c 2005-11-07 19:20:27.000000000 -0800 @@ -1622,7 +1622,8 @@ static int set_lock_args(int mode, struc static int set_unlock_args(uint32_t flags, void *astarg, struct dlm_args *args) { - if (flags & ~(DLM_LKF_CANCEL | DLM_LKF_VALBLK | DLM_LKF_IVVALBLK)) + if (flags & ~(DLM_LKF_CANCEL | DLM_LKF_VALBLK | DLM_LKF_IVVALBLK | + DLM_LKF_FORCEUNLOCK)) return -EINVAL; args->flags = flags; @@ -1692,6 +1693,9 @@ static int validate_unlock_args(struct d if (lkb->lkb_flags & DLM_IFL_MSTCPY) goto out; + if (args->flags & DLM_LKF_FORCEUNLOCK) + goto out_ok; + if (args->flags & DLM_LKF_CANCEL && lkb->lkb_status == DLM_LKSTS_GRANTED) goto out; @@ -1704,9 +1708,11 @@ static int validate_unlock_args(struct d if (lkb->lkb_wait_type) goto out; + out_ok: lkb->lkb_exflags = args->flags; lkb->lkb_sbflags = 0; lkb->lkb_astparam = args->astparam; + rv = 0; out: return rv; diff -puN include/linux/dlm.h~dlm-device-interface-dlm-force-unlock include/linux/dlm.h --- devel/include/linux/dlm.h~dlm-device-interface-dlm-force-unlock 2005-11-07 19:20:20.000000000 -0800 +++ devel-akpm/include/linux/dlm.h 2005-11-07 19:20:26.000000000 -0800 @@ -123,6 +123,12 @@ * DLM_LKF_ALTCW * * The same as ALTPR, but the alternate mode is CW. + * + * DLM_LKF_FORCEUNLOCK + * + * Unlock the lock even if it is converting or waiting or has sublocks. + * Only really for use by the userland device.c code. + * */ #define DLM_LKF_NOQUEUE 0x00000001 @@ -142,6 +148,7 @@ #define DLM_LKF_ORPHAN 0x00004000 #define DLM_LKF_ALTPR 0x00008000 #define DLM_LKF_ALTCW 0x00010000 +#define DLM_LKF_FORCEUNLOCK 0x00020000 /* * Some return codes that are not in errno.h _