int lm_rem_lockspace_dlm(struct lockspace *ls, int free_vg) { struct lm_dlm *lmd = (struct lm_dlm *)ls->lm_data; int rv; if (daemon_test) goto out; /* * If free_vg is set, it means we are doing vgremove, and we may want * to tell any other nodes to leave the lockspace. This is not really * necessary since there should be no harm in having an unused * lockspace sitting around. A new "notification lock" would need to * be added with a callback to signal this. */ rv = dlm_release_lockspace(ls->name, lmd->dh, 1); if (rv < 0) { log_error("rem_lockspace_dlm error %d", rv); return rv; } out: free(lmd); ls->lm_data = NULL; return 0; }
static int leave(struct mddev *mddev) { struct md_cluster_info *cinfo = mddev->cluster_info; if (!cinfo) return 0; /* BITMAP_NEEDS_SYNC message should be sent when node * is leaving the cluster with dirty bitmap, also we * can only deliver it when dlm connection is available */ if (cinfo->slot_number > 0 && mddev->recovery_cp != MaxSector) resync_bitmap(mddev); md_unregister_thread(&cinfo->recovery_thread); md_unregister_thread(&cinfo->recv_thread); lockres_free(cinfo->message_lockres); lockres_free(cinfo->token_lockres); lockres_free(cinfo->ack_lockres); lockres_free(cinfo->no_new_dev_lockres); lockres_free(cinfo->resync_lockres); lockres_free(cinfo->bitmap_lockres); unlock_all_bitmaps(mddev); dlm_release_lockspace(cinfo->lockspace, 2); return 0; }
static void _cluster_closedown(void) { DEBUGLOG("cluster_closedown\n"); destroy_lvhash(); dlm_release_lockspace(LOCKSPACE_NAME, lockspace, 1); cpg_finalize(cpg_handle); quorum_finalize(quorum_handle); }
static void gdlm_unmount(struct gfs2_sbd *sdp) { struct lm_lockstruct *ls = &sdp->sd_lockstruct; if (ls->ls_dlm) { dlm_release_lockspace(ls->ls_dlm, 2); ls->ls_dlm = NULL; } }
static void gdlm_withdraw(void *lockspace) { struct gdlm_ls *ls = lockspace; kobject_uevent(&ls->kobj, KOBJ_OFFLINE); wait_event_interruptible(ls->wait_control, test_bit(DFL_WITHDRAW, &ls->flags)); dlm_release_lockspace(ls->dlm_lockspace, 2); gdlm_release_threads(ls); gdlm_release_all_locks(ls); gdlm_kobject_release(ls); }
static int leave(struct mddev *mddev) { struct md_cluster_info *cinfo = mddev->cluster_info; if (!cinfo) return 0; md_unregister_thread(&cinfo->recovery_thread); md_unregister_thread(&cinfo->recv_thread); lockres_free(cinfo->message_lockres); lockres_free(cinfo->token_lockres); lockres_free(cinfo->ack_lockres); lockres_free(cinfo->no_new_dev_lockres); lockres_free(cinfo->sb_lock); lockres_free(cinfo->bitmap_lockres); dlm_release_lockspace(cinfo->lockspace, 2); return 0; }
static void do_leave(char *name) { dlm_lshandle_t *dh; printf("Leaving lockspace \"%s\"\n", name); fflush(stdout); dh = dlm_open_lockspace(name); if (!dh) { fprintf(stderr, "dlm_open_lockspace %s error %p %d\n", name, dh, errno); exit(-1); } dlm_release_lockspace(name, dh, 1); printf("done\n"); }
int main(int argc, char *argv[]) { struct timeval begin, end, diff; char *name; int sec = 0; if (argc < 2) { printf("%s <lockspace name> [sleep sec]\n", argv[0]); exit(-1); } name = argv[1]; if (argc > 2) sec = atoi(argv[2]); printf("Joining lockspace \"%s\" ... ", name); fflush(stdout); gettimeofday(&begin, NULL); dh = dlm_create_lockspace(name, 0600); if (!dh) { printf("dlm_create_lockspace error %p %d\n", dh, errno); return -ENOTCONN; } gettimeofday(&end, NULL); timersub(&end, &begin, &diff); printf("%lu s\n", diff.tv_sec); if (sec) sleep(sec); printf("Leaving lockspace \"%s\" ... ", name); fflush(stdout); gettimeofday(&begin, NULL); dlm_release_lockspace(name, dh, 1); gettimeofday(&end, NULL); timersub(&end, &begin, &diff); printf("%lu s\n", diff.tv_sec); return 0; }
static void gdlm_unmount(struct gfs2_sbd *sdp) { struct lm_lockstruct *ls = &sdp->sd_lockstruct; if (test_bit(DFL_NO_DLM_OPS, &ls->ls_recover_flags)) goto release; /* wait for gfs2_control_wq to be done with this mount */ spin_lock(&ls->ls_recover_spin); set_bit(DFL_UNMOUNT, &ls->ls_recover_flags); spin_unlock(&ls->ls_recover_spin); flush_delayed_work(&sdp->sd_control_work); /* mounted_lock and control_lock will be purged in dlm recovery */ release: if (ls->ls_dlm) { dlm_release_lockspace(ls->ls_dlm, 2); ls->ls_dlm = NULL; } free_recover_size(ls); }
static void gdlm_unmount(struct gfs2_sbd *sdp) { struct lm_lockstruct *ls = &sdp->sd_lockstruct; if (test_bit(DFL_NO_DLM_OPS, &ls->ls_recover_flags)) goto release; spin_lock(&ls->ls_recover_spin); set_bit(DFL_UNMOUNT, &ls->ls_recover_flags); spin_unlock(&ls->ls_recover_spin); flush_delayed_work_sync(&sdp->sd_control_work); release: if (ls->ls_dlm) { dlm_release_lockspace(ls->ls_dlm, 2); ls->ls_dlm = NULL; } free_recover_size(ls); }
static void gdlm_unmount(void *lockspace) { struct gdlm_ls *ls = lockspace; int rv; log_debug("unmount flags %lx", ls->flags); /* FIXME: serialize unmount and withdraw in case they happen at once. Also, if unmount follows withdraw, wait for withdraw to finish. */ if (test_bit(DFL_WITHDRAW, &ls->flags)) goto out; gdlm_kobject_release(ls); dlm_release_lockspace(ls->dlm_lockspace, 2); gdlm_release_threads(ls); rv = gdlm_release_all_locks(ls); if (rv) log_info("gdlm_unmount: %d stray locks freed", rv); out: kfree(ls); }
static void _cluster_closedown(void) { dlm_release_lockspace(LOCKSPACE_NAME, lockspace, 1); cpg_finalize(cpg_handle); quorum_finalize(quorum_handle); }
static int join(struct mddev *mddev, int nodes) { struct md_cluster_info *cinfo; int ret, ops_rv; char str[64]; cinfo = kzalloc(sizeof(struct md_cluster_info), GFP_KERNEL); if (!cinfo) return -ENOMEM; INIT_LIST_HEAD(&cinfo->suspend_list); spin_lock_init(&cinfo->suspend_lock); init_completion(&cinfo->completion); set_bit(MD_CLUSTER_BEGIN_JOIN_CLUSTER, &cinfo->state); init_waitqueue_head(&cinfo->wait); mutex_init(&cinfo->recv_mutex); mddev->cluster_info = cinfo; memset(str, 0, 64); sprintf(str, "%pU", mddev->uuid); ret = dlm_new_lockspace(str, mddev->bitmap_info.cluster_name, DLM_LSFL_FS, LVB_SIZE, &md_ls_ops, mddev, &ops_rv, &cinfo->lockspace); if (ret) goto err; wait_for_completion(&cinfo->completion); if (nodes < cinfo->slot_number) { pr_err("md-cluster: Slot allotted(%d) is greater than available slots(%d).", cinfo->slot_number, nodes); ret = -ERANGE; goto err; } /* Initiate the communication resources */ ret = -ENOMEM; cinfo->recv_thread = md_register_thread(recv_daemon, mddev, "cluster_recv"); if (!cinfo->recv_thread) { pr_err("md-cluster: cannot allocate memory for recv_thread!\n"); goto err; } cinfo->message_lockres = lockres_init(mddev, "message", NULL, 1); if (!cinfo->message_lockres) goto err; cinfo->token_lockres = lockres_init(mddev, "token", NULL, 0); if (!cinfo->token_lockres) goto err; cinfo->no_new_dev_lockres = lockres_init(mddev, "no-new-dev", NULL, 0); if (!cinfo->no_new_dev_lockres) goto err; ret = dlm_lock_sync(cinfo->token_lockres, DLM_LOCK_EX); if (ret) { ret = -EAGAIN; pr_err("md-cluster: can't join cluster to avoid lock issue\n"); goto err; } cinfo->ack_lockres = lockres_init(mddev, "ack", ack_bast, 0); if (!cinfo->ack_lockres) { ret = -ENOMEM; goto err; } /* get sync CR lock on ACK. */ if (dlm_lock_sync(cinfo->ack_lockres, DLM_LOCK_CR)) pr_err("md-cluster: failed to get a sync CR lock on ACK!(%d)\n", ret); dlm_unlock_sync(cinfo->token_lockres); /* get sync CR lock on no-new-dev. */ if (dlm_lock_sync(cinfo->no_new_dev_lockres, DLM_LOCK_CR)) pr_err("md-cluster: failed to get a sync CR lock on no-new-dev!(%d)\n", ret); pr_info("md-cluster: Joined cluster %s slot %d\n", str, cinfo->slot_number); snprintf(str, 64, "bitmap%04d", cinfo->slot_number - 1); cinfo->bitmap_lockres = lockres_init(mddev, str, NULL, 1); if (!cinfo->bitmap_lockres) { ret = -ENOMEM; goto err; } if (dlm_lock_sync(cinfo->bitmap_lockres, DLM_LOCK_PW)) { pr_err("Failed to get bitmap lock\n"); ret = -EINVAL; goto err; } cinfo->resync_lockres = lockres_init(mddev, "resync", NULL, 0); if (!cinfo->resync_lockres) { ret = -ENOMEM; goto err; } return 0; err: md_unregister_thread(&cinfo->recovery_thread); md_unregister_thread(&cinfo->recv_thread); lockres_free(cinfo->message_lockres); lockres_free(cinfo->token_lockres); lockres_free(cinfo->ack_lockres); lockres_free(cinfo->no_new_dev_lockres); lockres_free(cinfo->resync_lockres); lockres_free(cinfo->bitmap_lockres); if (cinfo->lockspace) dlm_release_lockspace(cinfo->lockspace, 2); mddev->cluster_info = NULL; kfree(cinfo); return ret; }
static int _init_cluster(void) { cs_error_t err; #ifdef QUORUM_SET /* corosync/quorum.h */ uint32_t quorum_type; #endif node_hash = dm_hash_create(100); err = cpg_initialize(&cpg_handle, &corosync_cpg_callbacks); if (err != CS_OK) { syslog(LOG_ERR, "Cannot initialise Corosync CPG service: %d", err); DEBUGLOG("Cannot initialise Corosync CPG service: %d", err); return cs_to_errno(err); } #ifdef QUORUM_SET err = quorum_initialize(&quorum_handle, &quorum_callbacks, &quorum_type); if (quorum_type != QUORUM_SET) { syslog(LOG_ERR, "Corosync quorum service is not configured"); DEBUGLOG("Corosync quorum service is not configured"); return EINVAL; } #else err = quorum_initialize(&quorum_handle, &quorum_callbacks); #endif if (err != CS_OK) { syslog(LOG_ERR, "Cannot initialise Corosync quorum service: %d", err); DEBUGLOG("Cannot initialise Corosync quorum service: %d", err); return cs_to_errno(err); } /* Create a lockspace for LV & VG locks to live in */ lockspace = dlm_open_lockspace(LOCKSPACE_NAME); if (!lockspace) { lockspace = dlm_create_lockspace(LOCKSPACE_NAME, 0600); if (!lockspace) { syslog(LOG_ERR, "Unable to create DLM lockspace for CLVM: %m"); return -1; } DEBUGLOG("Created DLM lockspace for CLVMD.\n"); } else DEBUGLOG("Opened existing DLM lockspace for CLVMD.\n"); dlm_ls_pthread_init(lockspace); DEBUGLOG("DLM initialisation complete\n"); /* Connect to the clvmd group */ strcpy((char *)cpg_group_name.value, "clvmd"); cpg_group_name.length = strlen((char *)cpg_group_name.value); err = cpg_join(cpg_handle, &cpg_group_name); if (err != CS_OK) { cpg_finalize(cpg_handle); quorum_finalize(quorum_handle); dlm_release_lockspace(LOCKSPACE_NAME, lockspace, 1); syslog(LOG_ERR, "Cannot join clvmd process group"); DEBUGLOG("Cannot join clvmd process group: %d\n", err); return cs_to_errno(err); } err = cpg_local_get(cpg_handle, &our_nodeid); if (err != CS_OK) { cpg_finalize(cpg_handle); quorum_finalize(quorum_handle); dlm_release_lockspace(LOCKSPACE_NAME, lockspace, 1); syslog(LOG_ERR, "Cannot get local node id\n"); return cs_to_errno(err); } DEBUGLOG("Our local node id is %d\n", our_nodeid); DEBUGLOG("Connected to Corosync\n"); return 0; }
static int _init_cluster(void) { cs_error_t err; node_hash = dm_hash_create(100); err = cpg_initialize(&cpg_handle, &corosync_cpg_callbacks); if (err != CS_OK) { syslog(LOG_ERR, "Cannot initialise Corosync CPG service: %d", err); DEBUGLOG("Cannot initialise Corosync CPG service: %d", err); return cs_to_errno(err); } err = quorum_initialize(&quorum_handle, &quorum_callbacks); if (err != CS_OK) { syslog(LOG_ERR, "Cannot initialise Corosync quorum service: %d", err); DEBUGLOG("Cannot initialise Corosync quorum service: %d", err); return cs_to_errno(err); } /* Create a lockspace for LV & VG locks to live in */ lockspace = dlm_create_lockspace(LOCKSPACE_NAME, 0600); if (!lockspace) { if (errno == EEXIST) { lockspace = dlm_open_lockspace(LOCKSPACE_NAME); } if (!lockspace) { syslog(LOG_ERR, "Unable to create lockspace for CLVM: %m"); quorum_finalize(quorum_handle); return -1; } } dlm_ls_pthread_init(lockspace); DEBUGLOG("DLM initialisation complete\n"); /* Connect to the clvmd group */ strcpy((char *)cpg_group_name.value, "clvmd"); cpg_group_name.length = strlen((char *)cpg_group_name.value); err = cpg_join(cpg_handle, &cpg_group_name); if (err != CS_OK) { cpg_finalize(cpg_handle); quorum_finalize(quorum_handle); dlm_release_lockspace(LOCKSPACE_NAME, lockspace, 1); syslog(LOG_ERR, "Cannot join clvmd process group"); DEBUGLOG("Cannot join clvmd process group: %d\n", err); return cs_to_errno(err); } err = cpg_local_get(cpg_handle, &our_nodeid); if (err != CS_OK) { cpg_finalize(cpg_handle); quorum_finalize(quorum_handle); dlm_release_lockspace(LOCKSPACE_NAME, lockspace, 1); syslog(LOG_ERR, "Cannot get local node id\n"); return cs_to_errno(err); } DEBUGLOG("Our local node id is %d\n", our_nodeid); DEBUGLOG("Connected to Corosync\n"); return 0; }
static int gdlm_mount(struct gfs2_sbd *sdp, const char *table) { struct lm_lockstruct *ls = &sdp->sd_lockstruct; char cluster[GFS2_LOCKNAME_LEN]; const char *fsname; uint32_t flags; int error, ops_result; /* * initialize everything */ INIT_DELAYED_WORK(&sdp->sd_control_work, gfs2_control_func); spin_lock_init(&ls->ls_recover_spin); ls->ls_recover_flags = 0; ls->ls_recover_mount = 0; ls->ls_recover_start = 0; ls->ls_recover_block = 0; ls->ls_recover_size = 0; ls->ls_recover_submit = NULL; ls->ls_recover_result = NULL; ls->ls_lvb_bits = NULL; error = set_recover_size(sdp, NULL, 0); if (error) goto fail; /* * prepare dlm_new_lockspace args */ fsname = strchr(table, ':'); if (!fsname) { fs_info(sdp, "no fsname found\n"); error = -EINVAL; goto fail_free; } memset(cluster, 0, sizeof(cluster)); memcpy(cluster, table, strlen(table) - strlen(fsname)); fsname++; flags = DLM_LSFL_FS | DLM_LSFL_NEWEXCL; /* * create/join lockspace */ error = dlm_new_lockspace(fsname, cluster, flags, GDLM_LVB_SIZE, &gdlm_lockspace_ops, sdp, &ops_result, &ls->ls_dlm); if (error) { fs_err(sdp, "dlm_new_lockspace error %d\n", error); goto fail_free; } if (ops_result < 0) { /* * dlm does not support ops callbacks, * old dlm_controld/gfs_controld are used, try without ops. */ fs_info(sdp, "dlm lockspace ops not used\n"); free_recover_size(ls); set_bit(DFL_NO_DLM_OPS, &ls->ls_recover_flags); return 0; } if (!test_bit(SDF_NOJOURNALID, &sdp->sd_flags)) { fs_err(sdp, "dlm lockspace ops disallow jid preset\n"); error = -EINVAL; goto fail_release; } /* * control_mount() uses control_lock to determine first mounter, * and for later mounts, waits for any recoveries to be cleared. */ error = control_mount(sdp); if (error) { fs_err(sdp, "mount control error %d\n", error); goto fail_release; } ls->ls_first = !!test_bit(DFL_FIRST_MOUNT, &ls->ls_recover_flags); clear_bit(SDF_NOJOURNALID, &sdp->sd_flags); smp_mb__after_atomic(); wake_up_bit(&sdp->sd_flags, SDF_NOJOURNALID); return 0; fail_release: dlm_release_lockspace(ls->ls_dlm, 2); fail_free: free_recover_size(ls); fail: return error; }
static int join(struct mddev *mddev, int nodes) { struct md_cluster_info *cinfo; int ret, ops_rv; char str[64]; if (!try_module_get(THIS_MODULE)) return -ENOENT; cinfo = kzalloc(sizeof(struct md_cluster_info), GFP_KERNEL); if (!cinfo) return -ENOMEM; init_completion(&cinfo->completion); mutex_init(&cinfo->sb_mutex); mddev->cluster_info = cinfo; memset(str, 0, 64); pretty_uuid(str, mddev->uuid); ret = dlm_new_lockspace(str, mddev->bitmap_info.cluster_name, DLM_LSFL_FS, LVB_SIZE, &md_ls_ops, mddev, &ops_rv, &cinfo->lockspace); if (ret) goto err; wait_for_completion(&cinfo->completion); if (nodes < cinfo->slot_number) { pr_err("md-cluster: Slot allotted(%d) is greater than available slots(%d).", cinfo->slot_number, nodes); ret = -ERANGE; goto err; } cinfo->sb_lock = lockres_init(mddev, "cmd-super", NULL, 0); if (!cinfo->sb_lock) { ret = -ENOMEM; goto err; } /* Initiate the communication resources */ ret = -ENOMEM; cinfo->recv_thread = md_register_thread(recv_daemon, mddev, "cluster_recv"); if (!cinfo->recv_thread) { pr_err("md-cluster: cannot allocate memory for recv_thread!\n"); goto err; } cinfo->message_lockres = lockres_init(mddev, "message", NULL, 1); if (!cinfo->message_lockres) goto err; cinfo->token_lockres = lockres_init(mddev, "token", NULL, 0); if (!cinfo->token_lockres) goto err; cinfo->ack_lockres = lockres_init(mddev, "ack", ack_bast, 0); if (!cinfo->ack_lockres) goto err; cinfo->no_new_dev_lockres = lockres_init(mddev, "no-new-dev", NULL, 0); if (!cinfo->no_new_dev_lockres) goto err; /* get sync CR lock on ACK. */ if (dlm_lock_sync(cinfo->ack_lockres, DLM_LOCK_CR)) pr_err("md-cluster: failed to get a sync CR lock on ACK!(%d)\n", ret); /* get sync CR lock on no-new-dev. */ if (dlm_lock_sync(cinfo->no_new_dev_lockres, DLM_LOCK_CR)) pr_err("md-cluster: failed to get a sync CR lock on no-new-dev!(%d)\n", ret); pr_info("md-cluster: Joined cluster %s slot %d\n", str, cinfo->slot_number); snprintf(str, 64, "bitmap%04d", cinfo->slot_number - 1); cinfo->bitmap_lockres = lockres_init(mddev, str, NULL, 1); if (!cinfo->bitmap_lockres) goto err; if (dlm_lock_sync(cinfo->bitmap_lockres, DLM_LOCK_PW)) { pr_err("Failed to get bitmap lock\n"); ret = -EINVAL; goto err; } INIT_LIST_HEAD(&cinfo->suspend_list); spin_lock_init(&cinfo->suspend_lock); ret = gather_all_resync_info(mddev, nodes); if (ret) goto err; return 0; err: lockres_free(cinfo->message_lockres); lockres_free(cinfo->token_lockres); lockres_free(cinfo->ack_lockres); lockres_free(cinfo->no_new_dev_lockres); lockres_free(cinfo->bitmap_lockres); lockres_free(cinfo->sb_lock); if (cinfo->lockspace) dlm_release_lockspace(cinfo->lockspace, 2); mddev->cluster_info = NULL; kfree(cinfo); module_put(THIS_MODULE); return ret; }
int main(int argc, char *argv[]) { uint32_t major, minor, patch; struct lk *lk; int i, rv, maxi = 0, quit = 0; srandom(time(NULL)); decode_arguments(argc, argv); if (maxn < maxr) { printf("number of resources must be >= number of locks\n"); return -1; } if (maxn % maxr) { printf("number of locks must be multiple of number of resources\n"); return -1; } printf("maxn = %d\n", maxn); printf("maxr = %d\n", maxr); printf("locks per resource = %d\n", maxn / maxr); signal(SIGTERM, sigterm_handler); client_init(); locks = malloc(maxn * sizeof(struct lk)); if (!locks) { printf("no mem for %d locks\n", maxn); return 0; } memset(locks, 0, sizeof(*locks)); lk = locks; for (i = 0; i < maxn; i++) { lk->id = i; lk->grmode = -1; lk->rqmode = -1; lk++; } rv = dlm_kernel_version(&major, &minor, &patch); if (rv < 0) { printf("can't detect dlm in kernel %d\n", errno); return -1; } printf("dlm kernel version: %u.%u.%u\n", major, minor, patch); dlm_library_version(&major, &minor, &patch); printf("dlm library version: %u.%u.%u\n", major, minor, patch); if (openclose_ls) { printf("dlm_open_lockspace...\n"); dh = dlm_open_lockspace("test"); if (!dh) { printf("dlm_open_lockspace error %lu %d\n", (unsigned long)dh, errno); return -ENOTCONN; } } else { printf("dlm_new_lockspace...\n"); dh = dlm_new_lockspace("test", 0600, timewarn ? DLM_LSFL_TIMEWARN : 0); if (!dh) { printf("dlm_new_lockspace error %lu %d\n", (unsigned long)dh, errno); return -ENOTCONN; } } rv = dlm_ls_get_fd(dh); if (rv < 0) { printf("dlm_ls_get_fd error %d %d\n", rv, errno); dlm_release_lockspace("test", dh, 1); return rv; } libdlm_fd = rv; client_add(libdlm_fd, &maxi); if (opt_cmd) { process_command(&quit); goto out; } client_add(STDIN_FILENO, &maxi); printf("Type EXIT to finish, help for usage\n"); while (1) { rv = poll(pollfd, maxi + 1, -1); if (rv < 0 && errno == EINTR) continue; if (rv < 0) printf("poll error %d errno %d\n", rv, errno); for (i = 0; i <= maxi; i++) { if (client[i].fd < 0) continue; if (pollfd[i].revents & POLLIN) { if (pollfd[i].fd == libdlm_fd) process_libdlm(); else if (pollfd[i].fd == STDIN_FILENO) process_command(&quit); } if (pollfd[i].revents & (POLLHUP | POLLERR | POLLNVAL)) client_dead(i); } if (quit && all_unlocks_done()) break; } out: if (openclose_ls) { printf("dlm_close_lockspace\n"); rv = dlm_close_lockspace(dh); if (rv < 0) printf("dlm_close_lockspace error %d %d\n", rv, errno); } else { printf("dlm_release_lockspace\n"); rv = dlm_release_lockspace("test", dh, 1); if (rv < 0) printf("dlm_release_lockspace error %d %d\n", rv, errno); } return 0; }
static int gdlm_mount(struct gfs2_sbd *sdp, const char *table) { struct lm_lockstruct *ls = &sdp->sd_lockstruct; char cluster[GFS2_LOCKNAME_LEN]; const char *fsname; uint32_t flags; int error, ops_result; INIT_DELAYED_WORK(&sdp->sd_control_work, gfs2_control_func); spin_lock_init(&ls->ls_recover_spin); ls->ls_recover_flags = 0; ls->ls_recover_mount = 0; ls->ls_recover_start = 0; ls->ls_recover_block = 0; ls->ls_recover_size = 0; ls->ls_recover_submit = NULL; ls->ls_recover_result = NULL; error = set_recover_size(sdp, NULL, 0); if (error) goto fail; fsname = strchr(table, ':'); if (!fsname) { fs_info(sdp, "no fsname found\n"); error = -EINVAL; goto fail_free; } memset(cluster, 0, sizeof(cluster)); memcpy(cluster, table, strlen(table) - strlen(fsname)); fsname++; flags = DLM_LSFL_FS | DLM_LSFL_NEWEXCL; if (ls->ls_nodir) flags |= DLM_LSFL_NODIR; error = dlm_new_lockspace(fsname, cluster, flags, GDLM_LVB_SIZE, &gdlm_lockspace_ops, sdp, &ops_result, &ls->ls_dlm); if (error) { fs_err(sdp, "dlm_new_lockspace error %d\n", error); goto fail_free; } if (ops_result < 0) { fs_info(sdp, "dlm lockspace ops not used\n"); free_recover_size(ls); set_bit(DFL_NO_DLM_OPS, &ls->ls_recover_flags); return 0; } if (!test_bit(SDF_NOJOURNALID, &sdp->sd_flags)) { fs_err(sdp, "dlm lockspace ops disallow jid preset\n"); error = -EINVAL; goto fail_release; } error = control_mount(sdp); if (error) { fs_err(sdp, "mount control error %d\n", error); goto fail_release; } ls->ls_first = !!test_bit(DFL_FIRST_MOUNT, &ls->ls_recover_flags); clear_bit(SDF_NOJOURNALID, &sdp->sd_flags); smp_mb__after_clear_bit(); wake_up_bit(&sdp->sd_flags, SDF_NOJOURNALID); return 0; fail_release: dlm_release_lockspace(ls->ls_dlm, 2); fail_free: free_recover_size(ls); fail: return error; }