Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2: (138 commits) ocfs2: Access the right buffer_head in ocfs2_merge_rec_left. ocfs2: use min_t in ocfs2_quota_read() ocfs2: remove unneeded lvb casts ocfs2: Add xattr support checking in init_security ocfs2: alloc xattr bucket in ocfs2_xattr_set_handle ocfs2: calculate and reserve credits for xattr value in mknod ocfs2/xattr: fix credits calculation during index create ocfs2/xattr: Always updating ctime during xattr set. ocfs2/xattr: Remove extend_trans call and add its credits from the beginning ocfs2/dlm: Fix race during lockres mastery ocfs2/dlm: Fix race in adding/removing lockres' to/from the tracking list ocfs2/dlm: Hold off sending lockres drop ref message while lockres is migrating ocfs2/dlm: Clean up errors in dlm_proxy_ast_handler() ocfs2/dlm: Fix a race between migrate request and exit domain ocfs2: One more hamming code optimization. ocfs2: Another hamming code optimization. ocfs2: Don't hand-code xor in ocfs2_hamming_encode(). ocfs2: Enable metadata checksums. ocfs2: Validate superblock with checksum and ecc. ocfs2: Checksum and ECC for directory blocks. ...
This commit is contained in:
@@ -275,6 +275,7 @@ int dlm_proxy_ast_handler(struct o2net_msg *msg, u32 len, void *data,
|
||||
struct list_head *iter, *head=NULL;
|
||||
u64 cookie;
|
||||
u32 flags;
|
||||
u8 node;
|
||||
|
||||
if (!dlm_grab(dlm)) {
|
||||
dlm_error(DLM_REJECTED);
|
||||
@@ -286,18 +287,21 @@ int dlm_proxy_ast_handler(struct o2net_msg *msg, u32 len, void *data,
|
||||
|
||||
name = past->name;
|
||||
locklen = past->namelen;
|
||||
cookie = be64_to_cpu(past->cookie);
|
||||
cookie = past->cookie;
|
||||
flags = be32_to_cpu(past->flags);
|
||||
node = past->node_idx;
|
||||
|
||||
if (locklen > DLM_LOCKID_NAME_MAX) {
|
||||
ret = DLM_IVBUFLEN;
|
||||
mlog(ML_ERROR, "Invalid name length in proxy ast handler!\n");
|
||||
mlog(ML_ERROR, "Invalid name length (%d) in proxy ast "
|
||||
"handler!\n", locklen);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if ((flags & (LKM_PUT_LVB|LKM_GET_LVB)) ==
|
||||
(LKM_PUT_LVB|LKM_GET_LVB)) {
|
||||
mlog(ML_ERROR, "both PUT and GET lvb specified\n");
|
||||
mlog(ML_ERROR, "Both PUT and GET lvb specified, (0x%x)\n",
|
||||
flags);
|
||||
ret = DLM_BADARGS;
|
||||
goto leave;
|
||||
}
|
||||
@@ -310,22 +314,21 @@ int dlm_proxy_ast_handler(struct o2net_msg *msg, u32 len, void *data,
|
||||
if (past->type != DLM_AST &&
|
||||
past->type != DLM_BAST) {
|
||||
mlog(ML_ERROR, "Unknown ast type! %d, cookie=%u:%llu"
|
||||
"name=%.*s\n", past->type,
|
||||
dlm_get_lock_cookie_node(cookie),
|
||||
dlm_get_lock_cookie_seq(cookie),
|
||||
locklen, name);
|
||||
"name=%.*s, node=%u\n", past->type,
|
||||
dlm_get_lock_cookie_node(be64_to_cpu(cookie)),
|
||||
dlm_get_lock_cookie_seq(be64_to_cpu(cookie)),
|
||||
locklen, name, node);
|
||||
ret = DLM_IVLOCKID;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
res = dlm_lookup_lockres(dlm, name, locklen);
|
||||
if (!res) {
|
||||
mlog(0, "got %sast for unknown lockres! "
|
||||
"cookie=%u:%llu, name=%.*s, namelen=%u\n",
|
||||
past->type == DLM_AST ? "" : "b",
|
||||
dlm_get_lock_cookie_node(cookie),
|
||||
dlm_get_lock_cookie_seq(cookie),
|
||||
locklen, name, locklen);
|
||||
mlog(0, "Got %sast for unknown lockres! cookie=%u:%llu, "
|
||||
"name=%.*s, node=%u\n", (past->type == DLM_AST ? "" : "b"),
|
||||
dlm_get_lock_cookie_node(be64_to_cpu(cookie)),
|
||||
dlm_get_lock_cookie_seq(be64_to_cpu(cookie)),
|
||||
locklen, name, node);
|
||||
ret = DLM_IVLOCKID;
|
||||
goto leave;
|
||||
}
|
||||
@@ -337,12 +340,12 @@ int dlm_proxy_ast_handler(struct o2net_msg *msg, u32 len, void *data,
|
||||
|
||||
spin_lock(&res->spinlock);
|
||||
if (res->state & DLM_LOCK_RES_RECOVERING) {
|
||||
mlog(0, "responding with DLM_RECOVERING!\n");
|
||||
mlog(0, "Responding with DLM_RECOVERING!\n");
|
||||
ret = DLM_RECOVERING;
|
||||
goto unlock_out;
|
||||
}
|
||||
if (res->state & DLM_LOCK_RES_MIGRATING) {
|
||||
mlog(0, "responding with DLM_MIGRATING!\n");
|
||||
mlog(0, "Responding with DLM_MIGRATING!\n");
|
||||
ret = DLM_MIGRATING;
|
||||
goto unlock_out;
|
||||
}
|
||||
@@ -351,7 +354,7 @@ int dlm_proxy_ast_handler(struct o2net_msg *msg, u32 len, void *data,
|
||||
lock = NULL;
|
||||
list_for_each(iter, head) {
|
||||
lock = list_entry (iter, struct dlm_lock, list);
|
||||
if (be64_to_cpu(lock->ml.cookie) == cookie)
|
||||
if (lock->ml.cookie == cookie)
|
||||
goto do_ast;
|
||||
}
|
||||
|
||||
@@ -363,15 +366,15 @@ int dlm_proxy_ast_handler(struct o2net_msg *msg, u32 len, void *data,
|
||||
|
||||
list_for_each(iter, head) {
|
||||
lock = list_entry (iter, struct dlm_lock, list);
|
||||
if (be64_to_cpu(lock->ml.cookie) == cookie)
|
||||
if (lock->ml.cookie == cookie)
|
||||
goto do_ast;
|
||||
}
|
||||
|
||||
mlog(0, "got %sast for unknown lock! cookie=%u:%llu, "
|
||||
"name=%.*s, namelen=%u\n", past->type == DLM_AST ? "" : "b",
|
||||
dlm_get_lock_cookie_node(cookie),
|
||||
dlm_get_lock_cookie_seq(cookie),
|
||||
locklen, name, locklen);
|
||||
mlog(0, "Got %sast for unknown lock! cookie=%u:%llu, name=%.*s, "
|
||||
"node=%u\n", past->type == DLM_AST ? "" : "b",
|
||||
dlm_get_lock_cookie_node(be64_to_cpu(cookie)),
|
||||
dlm_get_lock_cookie_seq(be64_to_cpu(cookie)),
|
||||
locklen, name, node);
|
||||
|
||||
ret = DLM_NORMAL;
|
||||
unlock_out:
|
||||
@@ -383,8 +386,8 @@ do_ast:
|
||||
if (past->type == DLM_AST) {
|
||||
/* do not alter lock refcount. switching lists. */
|
||||
list_move_tail(&lock->list, &res->granted);
|
||||
mlog(0, "ast: adding to granted list... type=%d, "
|
||||
"convert_type=%d\n", lock->ml.type, lock->ml.convert_type);
|
||||
mlog(0, "ast: Adding to granted list... type=%d, "
|
||||
"convert_type=%d\n", lock->ml.type, lock->ml.convert_type);
|
||||
if (lock->ml.convert_type != LKM_IVMODE) {
|
||||
lock->ml.type = lock->ml.convert_type;
|
||||
lock->ml.convert_type = LKM_IVMODE;
|
||||
@@ -408,7 +411,6 @@ do_ast:
|
||||
dlm_do_local_bast(dlm, res, lock, past->blocked_type);
|
||||
|
||||
leave:
|
||||
|
||||
if (res)
|
||||
dlm_lockres_put(res);
|
||||
|
||||
|
@@ -140,6 +140,7 @@ struct dlm_ctxt
|
||||
unsigned int purge_count;
|
||||
spinlock_t spinlock;
|
||||
spinlock_t ast_lock;
|
||||
spinlock_t track_lock;
|
||||
char *name;
|
||||
u8 node_num;
|
||||
u32 key;
|
||||
@@ -316,6 +317,8 @@ struct dlm_lock_resource
|
||||
* put on a list for the dlm thread to run. */
|
||||
unsigned long last_used;
|
||||
|
||||
struct dlm_ctxt *dlm;
|
||||
|
||||
unsigned migration_pending:1;
|
||||
atomic_t asts_reserved;
|
||||
spinlock_t spinlock;
|
||||
|
@@ -630,43 +630,38 @@ static void *lockres_seq_start(struct seq_file *m, loff_t *pos)
|
||||
{
|
||||
struct debug_lockres *dl = m->private;
|
||||
struct dlm_ctxt *dlm = dl->dl_ctxt;
|
||||
struct dlm_lock_resource *oldres = dl->dl_res;
|
||||
struct dlm_lock_resource *res = NULL;
|
||||
struct list_head *track_list;
|
||||
|
||||
spin_lock(&dlm->spinlock);
|
||||
spin_lock(&dlm->track_lock);
|
||||
if (oldres)
|
||||
track_list = &oldres->tracking;
|
||||
else
|
||||
track_list = &dlm->tracking_list;
|
||||
|
||||
if (dl->dl_res) {
|
||||
list_for_each_entry(res, &dl->dl_res->tracking, tracking) {
|
||||
if (dl->dl_res) {
|
||||
dlm_lockres_put(dl->dl_res);
|
||||
dl->dl_res = NULL;
|
||||
}
|
||||
if (&res->tracking == &dlm->tracking_list) {
|
||||
mlog(0, "End of list found, %p\n", res);
|
||||
dl = NULL;
|
||||
break;
|
||||
}
|
||||
list_for_each_entry(res, track_list, tracking) {
|
||||
if (&res->tracking == &dlm->tracking_list)
|
||||
res = NULL;
|
||||
else
|
||||
dlm_lockres_get(res);
|
||||
dl->dl_res = res;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (!list_empty(&dlm->tracking_list)) {
|
||||
list_for_each_entry(res, &dlm->tracking_list, tracking)
|
||||
break;
|
||||
dlm_lockres_get(res);
|
||||
dl->dl_res = res;
|
||||
} else
|
||||
dl = NULL;
|
||||
break;
|
||||
}
|
||||
spin_unlock(&dlm->track_lock);
|
||||
|
||||
if (dl) {
|
||||
spin_lock(&dl->dl_res->spinlock);
|
||||
dump_lockres(dl->dl_res, dl->dl_buf, dl->dl_len - 1);
|
||||
spin_unlock(&dl->dl_res->spinlock);
|
||||
}
|
||||
if (oldres)
|
||||
dlm_lockres_put(oldres);
|
||||
|
||||
spin_unlock(&dlm->spinlock);
|
||||
dl->dl_res = res;
|
||||
|
||||
if (res) {
|
||||
spin_lock(&res->spinlock);
|
||||
dump_lockres(res, dl->dl_buf, dl->dl_len - 1);
|
||||
spin_unlock(&res->spinlock);
|
||||
} else
|
||||
dl = NULL;
|
||||
|
||||
/* passed to seq_show */
|
||||
return dl;
|
||||
}
|
||||
|
||||
|
@@ -1550,6 +1550,7 @@ static struct dlm_ctxt *dlm_alloc_ctxt(const char *domain,
|
||||
spin_lock_init(&dlm->spinlock);
|
||||
spin_lock_init(&dlm->master_lock);
|
||||
spin_lock_init(&dlm->ast_lock);
|
||||
spin_lock_init(&dlm->track_lock);
|
||||
INIT_LIST_HEAD(&dlm->list);
|
||||
INIT_LIST_HEAD(&dlm->dirty_list);
|
||||
INIT_LIST_HEAD(&dlm->reco.resources);
|
||||
|
@@ -505,8 +505,10 @@ void dlm_change_lockres_owner(struct dlm_ctxt *dlm,
|
||||
static void dlm_lockres_release(struct kref *kref)
|
||||
{
|
||||
struct dlm_lock_resource *res;
|
||||
struct dlm_ctxt *dlm;
|
||||
|
||||
res = container_of(kref, struct dlm_lock_resource, refs);
|
||||
dlm = res->dlm;
|
||||
|
||||
/* This should not happen -- all lockres' have a name
|
||||
* associated with them at init time. */
|
||||
@@ -515,6 +517,7 @@ static void dlm_lockres_release(struct kref *kref)
|
||||
mlog(0, "destroying lockres %.*s\n", res->lockname.len,
|
||||
res->lockname.name);
|
||||
|
||||
spin_lock(&dlm->track_lock);
|
||||
if (!list_empty(&res->tracking))
|
||||
list_del_init(&res->tracking);
|
||||
else {
|
||||
@@ -522,6 +525,9 @@ static void dlm_lockres_release(struct kref *kref)
|
||||
res->lockname.len, res->lockname.name);
|
||||
dlm_print_one_lock_resource(res);
|
||||
}
|
||||
spin_unlock(&dlm->track_lock);
|
||||
|
||||
dlm_put(dlm);
|
||||
|
||||
if (!hlist_unhashed(&res->hash_node) ||
|
||||
!list_empty(&res->granted) ||
|
||||
@@ -595,6 +601,10 @@ static void dlm_init_lockres(struct dlm_ctxt *dlm,
|
||||
res->migration_pending = 0;
|
||||
res->inflight_locks = 0;
|
||||
|
||||
/* put in dlm_lockres_release */
|
||||
dlm_grab(dlm);
|
||||
res->dlm = dlm;
|
||||
|
||||
kref_init(&res->refs);
|
||||
|
||||
/* just for consistency */
|
||||
@@ -722,14 +732,21 @@ lookup:
|
||||
if (tmpres) {
|
||||
int dropping_ref = 0;
|
||||
|
||||
spin_unlock(&dlm->spinlock);
|
||||
|
||||
spin_lock(&tmpres->spinlock);
|
||||
/* We wait for the other thread that is mastering the resource */
|
||||
if (tmpres->owner == DLM_LOCK_RES_OWNER_UNKNOWN) {
|
||||
__dlm_wait_on_lockres(tmpres);
|
||||
BUG_ON(tmpres->owner == DLM_LOCK_RES_OWNER_UNKNOWN);
|
||||
}
|
||||
|
||||
if (tmpres->owner == dlm->node_num) {
|
||||
BUG_ON(tmpres->state & DLM_LOCK_RES_DROPPING_REF);
|
||||
dlm_lockres_grab_inflight_ref(dlm, tmpres);
|
||||
} else if (tmpres->state & DLM_LOCK_RES_DROPPING_REF)
|
||||
dropping_ref = 1;
|
||||
spin_unlock(&tmpres->spinlock);
|
||||
spin_unlock(&dlm->spinlock);
|
||||
|
||||
/* wait until done messaging the master, drop our ref to allow
|
||||
* the lockres to be purged, start over. */
|
||||
@@ -2949,7 +2966,7 @@ static int dlm_do_migrate_request(struct dlm_ctxt *dlm,
|
||||
struct dlm_node_iter *iter)
|
||||
{
|
||||
struct dlm_migrate_request migrate;
|
||||
int ret, status = 0;
|
||||
int ret, skip, status = 0;
|
||||
int nodenum;
|
||||
|
||||
memset(&migrate, 0, sizeof(migrate));
|
||||
@@ -2966,12 +2983,27 @@ static int dlm_do_migrate_request(struct dlm_ctxt *dlm,
|
||||
nodenum == new_master)
|
||||
continue;
|
||||
|
||||
/* We could race exit domain. If exited, skip. */
|
||||
spin_lock(&dlm->spinlock);
|
||||
skip = (!test_bit(nodenum, dlm->domain_map));
|
||||
spin_unlock(&dlm->spinlock);
|
||||
if (skip) {
|
||||
clear_bit(nodenum, iter->node_map);
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = o2net_send_message(DLM_MIGRATE_REQUEST_MSG, dlm->key,
|
||||
&migrate, sizeof(migrate), nodenum,
|
||||
&status);
|
||||
if (ret < 0)
|
||||
mlog_errno(ret);
|
||||
else if (status < 0) {
|
||||
if (ret < 0) {
|
||||
mlog(0, "migrate_request returned %d!\n", ret);
|
||||
if (!dlm_is_host_down(ret)) {
|
||||
mlog(ML_ERROR, "unhandled error=%d!\n", ret);
|
||||
BUG();
|
||||
}
|
||||
clear_bit(nodenum, iter->node_map);
|
||||
ret = 0;
|
||||
} else if (status < 0) {
|
||||
mlog(0, "migrate request (node %u) returned %d!\n",
|
||||
nodenum, status);
|
||||
ret = status;
|
||||
|
@@ -181,7 +181,8 @@ static int dlm_purge_lockres(struct dlm_ctxt *dlm,
|
||||
|
||||
spin_lock(&res->spinlock);
|
||||
/* This ensures that clear refmap is sent after the set */
|
||||
__dlm_wait_on_lockres_flags(res, DLM_LOCK_RES_SETREF_INPROG);
|
||||
__dlm_wait_on_lockres_flags(res, (DLM_LOCK_RES_SETREF_INPROG |
|
||||
DLM_LOCK_RES_MIGRATING));
|
||||
spin_unlock(&res->spinlock);
|
||||
|
||||
/* clear our bit from the master's refmap, ignore errors */
|
||||
|
Reference in New Issue
Block a user