From mboxrd@z Thu Jan 1 00:00:00 1970 From: adas@sourceware.org Date: 12 Jul 2006 21:53:31 -0000 Subject: [Cluster-devel] cluster/gfs-kernel/src/dlm plock.c lock_dlm.h Message-ID: <20060712215331.19375.qmail@sourceware.org> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit CVSROOT: /cvs/cluster Module name: cluster Branch: RHEL4 Changes by: adas at sourceware.org 2006-07-12 21:53:30 Modified files: gfs-kernel/src/dlm: plock.c lock_dlm.h Log message: Fix for bz 198303. F_GETLK was broken, always used to return zero conflicts for local plocks. Also bogus pid was being returned for local locks. Added a new pid field to gfs posix lock to store and return actual pid Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs-kernel/src/dlm/plock.c.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.12&r2=1.12.2.1 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs-kernel/src/dlm/lock_dlm.h.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.18.2.4&r2=1.18.2.5 --- cluster/gfs-kernel/src/dlm/plock.c 2004/10/28 07:14:45 1.12 +++ cluster/gfs-kernel/src/dlm/plock.c 2006/07/12 21:53:30 1.12.2.1 @@ -377,8 +377,9 @@ } } -static int create_lock(struct dlm_resource *r, unsigned long owner, int ex, - uint64_t start, uint64_t end, dlm_lock_t **lpp) +static int create_lock(struct dlm_resource *r, unsigned long owner, + unsigned int pid, int ex, uint64_t start, + uint64_t end, dlm_lock_t **lpp) { dlm_lock_t *lp; struct posix_lock *po; @@ -402,6 +403,7 @@ po->start = start; po->end = end; po->owner = owner; + po->pid = pid; po->ex = ex; list_add_tail(&po->list, &r->locks); @@ -501,13 +503,14 @@ } } -static void add_lock(struct dlm_resource *r, unsigned long owner, int wait, - int ex, uint64_t start, uint64_t end, int head) +static void add_lock(struct dlm_resource *r, unsigned long owner, + unsigned int pid, int wait, int ex, uint64_t start, + uint64_t end, int head) { dlm_lock_t *lp; int error; - error = create_lock(r, owner, ex, start, end, &lp); + error = create_lock(r, owner, pid, ex, start, end, &lp); DLM_ASSERT(!error, ); if (head == HEAD) set_bit(LFL_HEADQUE, &lp->flags); @@ -533,8 +536,8 @@ 2. convert RE to RN range and mode */ static int lock_case1(struct posix_lock *po, struct dlm_resource *r, - unsigned long owner, int wait, int ex, uint64_t start, - uint64_t end) + unsigned long owner, unsigned int pid, int wait, + int ex, uint64_t start, uint64_t end) { uint64_t start2, end2; @@ -548,10 +551,10 @@ po->ex = ex; if (ex) { - add_lock(r, owner, X_WAIT, SH, start2, end2, HEAD); + add_lock(r, owner, pid, X_WAIT, SH, start2, end2, HEAD); update_lock(po->lp, wait); } else { - add_lock(r, owner, WAIT, EX, start2, end2, HEAD); + add_lock(r, owner, pid, WAIT, EX, start2, end2, HEAD); update_lock(po->lp, X_WAIT); } return 0; @@ -563,12 +566,12 @@ 3. convert RE to RN range and mode */ static int lock_case2(struct posix_lock *po, struct dlm_resource *r, - unsigned long owner, int wait, int ex, uint64_t start, - uint64_t end) + unsigned long owner, unsigned int pid, int wait, + int ex, uint64_t start, uint64_t end) { if (ex) { - add_lock(r, owner, X_WAIT, SH, po->start, start-1, HEAD); - add_lock(r, owner, X_WAIT, SH, end+1, po->end, HEAD); + add_lock(r, owner, pid, X_WAIT, SH, po->start, start-1, HEAD); + add_lock(r, owner, pid, X_WAIT, SH, end+1, po->end, HEAD); po->start = start; po->end = end; @@ -576,8 +579,8 @@ update_lock(po->lp, wait); } else { - add_lock(r, owner, WAIT, EX, po->start, start-1, HEAD); - add_lock(r, owner, WAIT, EX, end+1, po->end, HEAD); + add_lock(r, owner, pid, WAIT, EX, po->start, start-1, HEAD); + add_lock(r, owner, pid, WAIT, EX, end+1, po->end, HEAD); po->start = start; po->end = end; @@ -618,7 +621,7 @@ /* adds locks in gaps between existing locks from start to end */ static int fill_gaps(struct list_head *exist, struct dlm_resource *r, - unsigned long owner, int wait, int ex, uint64_t start, + unsigned long owner, unsigned int pid, int wait, int ex, uint64_t start, uint64_t end) { uint64_t exist_start = 0, exist_end = 0; @@ -628,13 +631,13 @@ if (next_exist(exist, &exist_start, &exist_end)) break; if (start < exist_start) - add_lock(r, owner, wait, ex, start, exist_start-1, 0); + add_lock(r, owner, pid, wait, ex, start, exist_start-1, 0); start = exist_end + 1; } /* cover gap after last existing lock */ if (exist_end < end) - add_lock(r, owner, wait, ex, exist_end+1, end, 0); + add_lock(r, owner, pid, wait, ex, exist_end+1, end, 0); return 0; } @@ -642,12 +645,12 @@ /* RE within RN (possibly more than one RE lock, all within RN) */ static int lock_case3(struct list_head *exist, struct dlm_resource *r, - unsigned long owner, int wait, int ex, uint64_t start, - uint64_t end) + unsigned long owner, unsigned int pid, int wait, + int ex, uint64_t start, uint64_t end) { struct posix_lock *po, *safe; - fill_gaps(exist, r, owner, wait, ex, start, end); + fill_gaps(exist, r, owner, pid, wait, ex, start, end); if (!ex) wait = X_WAIT; @@ -671,8 +674,9 @@ the request is sh->ex or ex->sh */ static int lock_case4(struct posix_lock *opo, struct list_head *exist, - struct dlm_resource *r, unsigned long owner, int wait, - int ex, uint64_t start, uint64_t end) + struct dlm_resource *r, unsigned long owner, + unsigned int pid, int wait, int ex, uint64_t start, + uint64_t end) { struct posix_lock *po, *safe; uint64_t over_start = 0, over_end = 0; @@ -700,7 +704,7 @@ opo->start = over_start; opo->end = over_end; - fill_gaps(exist, r, owner, wait, ex, start, end); + fill_gaps(exist, r, owner, pid, wait, ex, start, end); /* update existing locks to new mode and put back in locks list */ list_for_each_entry_safe(po, safe, exist, list) { @@ -722,7 +726,7 @@ /* 1. add a shared lock in the non-overlap range 2. convert RE to overlap range and requested mode */ - add_lock(r, owner, X_WAIT, SH, frag_start, frag_end, HEAD); + add_lock(r, owner, pid, X_WAIT, SH, frag_start, frag_end, HEAD); opo->start = over_start; opo->end = over_end; @@ -734,7 +738,7 @@ 2. convert RE to non-overlap range 3. wait for shared lock to complete */ - add_lock(r, owner, WAIT, SH, over_start, over_end, HEAD); + add_lock(r, owner, pid, WAIT, SH, over_start, over_end, HEAD); opo->start = frag_start; opo->end = frag_end; @@ -749,8 +753,9 @@ shrink, shift, split, etc existing locks (this often involves adding new locks in addition to modifying existing locks. */ -static int plock_internal(struct dlm_resource *r, unsigned long owner, - int wait, int ex, uint64_t start, uint64_t end) +static int plock_internal(struct dlm_resource *r, unsigned long owner, + unsigned int pid, int wait, int ex, uint64_t start, + uint64_t end) { LIST_HEAD(exist); struct posix_lock *po, *safe, *case4_po = NULL; @@ -779,14 +784,14 @@ if (po->ex == ex) goto out; - error = lock_case1(po, r, owner, wait, ex, start, end); + error = lock_case1(po, r, owner, pid, wait, ex, start, end); goto out; case 2: if (po->ex == ex) goto out; - error = lock_case2(po, r, owner, wait, ex, start, end); + error = lock_case2(po, r, owner, pid, wait, ex, start, end); goto out; case 3: @@ -806,19 +811,19 @@ } if (case4_po) - error = lock_case4(case4_po, &exist, r, owner, wait, ex, + error = lock_case4(case4_po, &exist, r, owner, pid, wait, ex, start, end); else if (!list_empty(&exist)) - error = lock_case3(&exist, r, owner, wait, ex, start, end); + error = lock_case3(&exist, r, owner, pid, wait, ex, start, end); else - add_lock(r, owner, wait, ex, start, end, 0); + add_lock(r, owner, pid, wait, ex, start, end, 0); out: return error; } static int punlock_internal(struct dlm_resource *r, unsigned long owner, - uint64_t start, uint64_t end) + unsigned int pid, uint64_t start, uint64_t end) { struct posix_lock *po, *safe; int error = 0; @@ -852,7 +857,7 @@ /* RN within RE - shrink and update RE to be front * fragment, and add a new lock for back fragment */ - add_lock(r, owner, po->ex ? WAIT : X_WAIT, po->ex, + add_lock(r, owner, pid, po->ex ? WAIT : X_WAIT, po->ex, end+1, po->end, HEAD); po->end = start - 1; @@ -921,6 +926,7 @@ { dlm_t *dlm = (dlm_t *) lockspace; unsigned long owner = (unsigned long) fl->fl_owner; + unsigned int pid = fl->fl_pid; int wait = IS_SETLKW(cmd); int ex = (fl->fl_type == F_WRLCK); uint64_t start = fl->fl_start, end = fl->fl_end; @@ -971,7 +977,7 @@ should never block waiting for a plock to be released until we call wait_async_list(). */ - error = plock_internal(r, owner, wait, ex, start, end); + error = plock_internal(r, owner, pid, wait, ex, start, end); unlock_resource(r); if (!error) { @@ -998,6 +1004,7 @@ { dlm_t *dlm = (dlm_t *) lockspace; unsigned long owner = (unsigned long) fl->fl_owner; + unsigned int pid = fl->fl_pid; uint64_t start = fl->fl_start, end = fl->fl_end; struct dlm_resource *r; int error; @@ -1018,7 +1025,7 @@ if (error) goto out_up; - error = punlock_internal(r, owner, start, end); + error = punlock_internal(r, owner, pid, start, end); unlock_resource(r); out_up: @@ -1039,7 +1046,8 @@ static int get_global_conflict(dlm_t *dlm, struct lm_lockname *name, unsigned long owner, uint64_t *start, - uint64_t *end, int *ex, unsigned long *rowner) + uint64_t *end, int *ex, unsigned long *rowner, + unsigned int *rpid) { dlm_lock_t *lp; struct dlm_queryinfo qinfo; @@ -1114,6 +1122,7 @@ *end = lki->lki_grrange.ra_end; *ex = (lki->lki_grmode == DLM_LOCK_EX) ? 1 : 0; *rowner = lki->lki_node; + *rpid = lki->lki_node; /* nodeid for pid as well */ error = -EAGAIN; break; } @@ -1121,8 +1130,8 @@ kfree(qinfo.gqi_lockinfo); - log_debug("global conflict %d %"PRIx64"-%"PRIx64" ex %d own %lu", - error, *start, *end, *ex, *rowner); + log_debug("global conflict %d %"PRIx64"-%"PRIx64" ex %d own %lu, pid %du", + error, *start, *end, *ex, *rowner, *rpid); out: keep_null_lock(dlm, lp); ret: @@ -1132,7 +1141,7 @@ static int get_local_conflict(dlm_t *dlm, struct dlm_resource *r, struct lm_lockname *name, unsigned long owner, uint64_t *start, uint64_t *end, int *ex, - unsigned long *rowner) + unsigned long *rowner, unsigned int *rpid) { struct posix_lock *po; int found = FALSE; @@ -1148,6 +1157,7 @@ *end = po->end; *ex = po->ex; *rowner = po->owner; + *rpid = po->pid; found = TRUE; break; } @@ -1157,7 +1167,7 @@ static int do_plock_get(dlm_t *dlm, struct lm_lockname *name, unsigned long owner, uint64_t *start, uint64_t *end, - int *ex, unsigned long *rowner) + int *ex, unsigned long *rowner, unsigned int *rpid) { struct dlm_resource *r; int error, found; @@ -1169,19 +1179,21 @@ put_resource(r); goto out; } - + found = get_local_conflict(dlm, r, name, owner, start, end, ex, - rowner); + rowner, rpid); up(&r->sema); put_resource(r); - if (found) + if (found) { + error = 1; goto out; + } } - error = get_global_conflict(dlm, name, owner, start, end, ex, rowner); + error = get_global_conflict(dlm, name, owner, start, end, ex, rowner, rpid); if (error == -EAGAIN) { - log_debug("pl get global conflict %"PRIx64"-%"PRIx64" %d %lu", - *start, *end, *ex, *rowner); + log_debug("pl get global conflict %"PRIx64"-%"PRIx64" %d %lu %du", + *start, *end, *ex, *rowner, *rpid); error = 1; } out: @@ -1194,10 +1206,11 @@ { uint64_t get_start = start, get_end = end; unsigned long get_owner = 0; + unsigned int get_pid = 0; int get_ex = ex; - return get_local_conflict(dlm, r, name, owner, - &get_start, &get_end, &get_ex, &get_owner); + return get_local_conflict(dlm, r, name, owner, &get_start, &get_end, + &get_ex, &get_owner, &get_pid); } static int global_conflict(dlm_t *dlm, struct lm_lockname *name, @@ -1206,23 +1219,25 @@ { uint64_t get_start = start, get_end = end; unsigned long get_owner = 0; + unsigned int get_pid = 0; int get_ex = ex; - return get_global_conflict(dlm, name, owner, - &get_start, &get_end, &get_ex, &get_owner); + return get_global_conflict(dlm, name, owner, &get_start, &get_end, + &get_ex, &get_owner, &get_pid); } int lm_dlm_plock_get(lm_lockspace_t *lockspace, struct lm_lockname *name, struct file *file, struct file_lock *fl) { dlm_t *dlm = (dlm_t *) lockspace; - unsigned long pid; + unsigned long owner; + unsigned int pid; int ex, error; ex = (fl->fl_type == F_WRLCK) ? 1 : 0; error = do_plock_get(dlm, name, fl->fl_pid, &fl->fl_start, - &fl->fl_end, &ex, &pid); + &fl->fl_end, &ex, &owner, &pid); if (error < 0) return error; if (error == 0) --- cluster/gfs-kernel/src/dlm/lock_dlm.h 2005/06/29 07:28:21 1.18.2.4 +++ cluster/gfs-kernel/src/dlm/lock_dlm.h 2006/07/12 21:53:30 1.18.2.5 @@ -146,6 +146,7 @@ struct dlm_resource * resource; dlm_lock_t * lp; unsigned long owner; + unsigned int pid; uint64_t start; uint64_t end; int count;