diff options
| -rw-r--r-- | fs/dlm/config.c | 77 | ||||
| -rw-r--r-- | fs/dlm/dlm_internal.h | 7 | ||||
| -rw-r--r-- | fs/dlm/lockspace.c | 158 | ||||
| -rw-r--r-- | fs/dlm/lockspace.h | 1 | ||||
| -rw-r--r-- | fs/dlm/user.c | 124 | ||||
| -rw-r--r-- | fs/dlm/user.h | 4 | ||||
| -rw-r--r-- | fs/gfs2/locking/dlm/mount.c | 3 | ||||
| -rw-r--r-- | include/linux/dlm.h | 5 | ||||
| -rw-r--r-- | include/linux/dlm_device.h | 2 |
9 files changed, 281 insertions, 100 deletions
diff --git a/fs/dlm/config.c b/fs/dlm/config.c index 89d2fb7b991a..fd9859f92fad 100644 --- a/fs/dlm/config.c +++ b/fs/dlm/config.c | |||
| @@ -14,6 +14,9 @@ | |||
| 14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
| 15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
| 16 | #include <linux/configfs.h> | 16 | #include <linux/configfs.h> |
| 17 | #include <linux/in.h> | ||
| 18 | #include <linux/in6.h> | ||
| 19 | #include <net/ipv6.h> | ||
| 17 | #include <net/sock.h> | 20 | #include <net/sock.h> |
| 18 | 21 | ||
| 19 | #include "config.h" | 22 | #include "config.h" |
| @@ -377,24 +380,24 @@ static struct config_item_type node_type = { | |||
| 377 | .ct_owner = THIS_MODULE, | 380 | .ct_owner = THIS_MODULE, |
| 378 | }; | 381 | }; |
| 379 | 382 | ||
| 380 | static struct dlm_cluster *to_cluster(struct config_item *i) | 383 | static struct dlm_cluster *config_item_to_cluster(struct config_item *i) |
| 381 | { | 384 | { |
| 382 | return i ? container_of(to_config_group(i), struct dlm_cluster, group) : | 385 | return i ? container_of(to_config_group(i), struct dlm_cluster, group) : |
| 383 | NULL; | 386 | NULL; |
| 384 | } | 387 | } |
| 385 | 388 | ||
| 386 | static struct dlm_space *to_space(struct config_item *i) | 389 | static struct dlm_space *config_item_to_space(struct config_item *i) |
| 387 | { | 390 | { |
| 388 | return i ? container_of(to_config_group(i), struct dlm_space, group) : | 391 | return i ? container_of(to_config_group(i), struct dlm_space, group) : |
| 389 | NULL; | 392 | NULL; |
| 390 | } | 393 | } |
| 391 | 394 | ||
| 392 | static struct dlm_comm *to_comm(struct config_item *i) | 395 | static struct dlm_comm *config_item_to_comm(struct config_item *i) |
| 393 | { | 396 | { |
| 394 | return i ? container_of(i, struct dlm_comm, item) : NULL; | 397 | return i ? container_of(i, struct dlm_comm, item) : NULL; |
| 395 | } | 398 | } |
| 396 | 399 | ||
| 397 | static struct dlm_node *to_node(struct config_item *i) | 400 | static struct dlm_node *config_item_to_node(struct config_item *i) |
| 398 | { | 401 | { |
| 399 | return i ? container_of(i, struct dlm_node, item) : NULL; | 402 | return i ? container_of(i, struct dlm_node, item) : NULL; |
| 400 | } | 403 | } |
| @@ -450,7 +453,7 @@ static struct config_group *make_cluster(struct config_group *g, | |||
| 450 | 453 | ||
| 451 | static void drop_cluster(struct config_group *g, struct config_item *i) | 454 | static void drop_cluster(struct config_group *g, struct config_item *i) |
| 452 | { | 455 | { |
| 453 | struct dlm_cluster *cl = to_cluster(i); | 456 | struct dlm_cluster *cl = config_item_to_cluster(i); |
| 454 | struct config_item *tmp; | 457 | struct config_item *tmp; |
| 455 | int j; | 458 | int j; |
| 456 | 459 | ||
| @@ -468,7 +471,7 @@ static void drop_cluster(struct config_group *g, struct config_item *i) | |||
| 468 | 471 | ||
| 469 | static void release_cluster(struct config_item *i) | 472 | static void release_cluster(struct config_item *i) |
| 470 | { | 473 | { |
| 471 | struct dlm_cluster *cl = to_cluster(i); | 474 | struct dlm_cluster *cl = config_item_to_cluster(i); |
| 472 | kfree(cl->group.default_groups); | 475 | kfree(cl->group.default_groups); |
| 473 | kfree(cl); | 476 | kfree(cl); |
| 474 | } | 477 | } |
| @@ -507,7 +510,7 @@ static struct config_group *make_space(struct config_group *g, const char *name) | |||
| 507 | 510 | ||
| 508 | static void drop_space(struct config_group *g, struct config_item *i) | 511 | static void drop_space(struct config_group *g, struct config_item *i) |
| 509 | { | 512 | { |
| 510 | struct dlm_space *sp = to_space(i); | 513 | struct dlm_space *sp = config_item_to_space(i); |
| 511 | struct config_item *tmp; | 514 | struct config_item *tmp; |
| 512 | int j; | 515 | int j; |
| 513 | 516 | ||
| @@ -524,7 +527,7 @@ static void drop_space(struct config_group *g, struct config_item *i) | |||
| 524 | 527 | ||
| 525 | static void release_space(struct config_item *i) | 528 | static void release_space(struct config_item *i) |
| 526 | { | 529 | { |
| 527 | struct dlm_space *sp = to_space(i); | 530 | struct dlm_space *sp = config_item_to_space(i); |
| 528 | kfree(sp->group.default_groups); | 531 | kfree(sp->group.default_groups); |
| 529 | kfree(sp); | 532 | kfree(sp); |
| 530 | } | 533 | } |
| @@ -546,7 +549,7 @@ static struct config_item *make_comm(struct config_group *g, const char *name) | |||
| 546 | 549 | ||
| 547 | static void drop_comm(struct config_group *g, struct config_item *i) | 550 | static void drop_comm(struct config_group *g, struct config_item *i) |
| 548 | { | 551 | { |
| 549 | struct dlm_comm *cm = to_comm(i); | 552 | struct dlm_comm *cm = config_item_to_comm(i); |
| 550 | if (local_comm == cm) | 553 | if (local_comm == cm) |
| 551 | local_comm = NULL; | 554 | local_comm = NULL; |
| 552 | dlm_lowcomms_close(cm->nodeid); | 555 | dlm_lowcomms_close(cm->nodeid); |
| @@ -557,13 +560,13 @@ static void drop_comm(struct config_group *g, struct config_item *i) | |||
| 557 | 560 | ||
| 558 | static void release_comm(struct config_item *i) | 561 | static void release_comm(struct config_item *i) |
| 559 | { | 562 | { |
| 560 | struct dlm_comm *cm = to_comm(i); | 563 | struct dlm_comm *cm = config_item_to_comm(i); |
| 561 | kfree(cm); | 564 | kfree(cm); |
| 562 | } | 565 | } |
| 563 | 566 | ||
| 564 | static struct config_item *make_node(struct config_group *g, const char *name) | 567 | static struct config_item *make_node(struct config_group *g, const char *name) |
| 565 | { | 568 | { |
| 566 | struct dlm_space *sp = to_space(g->cg_item.ci_parent); | 569 | struct dlm_space *sp = config_item_to_space(g->cg_item.ci_parent); |
| 567 | struct dlm_node *nd; | 570 | struct dlm_node *nd; |
| 568 | 571 | ||
| 569 | nd = kzalloc(sizeof(struct dlm_node), GFP_KERNEL); | 572 | nd = kzalloc(sizeof(struct dlm_node), GFP_KERNEL); |
| @@ -585,8 +588,8 @@ static struct config_item *make_node(struct config_group *g, const char *name) | |||
| 585 | 588 | ||
| 586 | static void drop_node(struct config_group *g, struct config_item *i) | 589 | static void drop_node(struct config_group *g, struct config_item *i) |
| 587 | { | 590 | { |
| 588 | struct dlm_space *sp = to_space(g->cg_item.ci_parent); | 591 | struct dlm_space *sp = config_item_to_space(g->cg_item.ci_parent); |
| 589 | struct dlm_node *nd = to_node(i); | 592 | struct dlm_node *nd = config_item_to_node(i); |
| 590 | 593 | ||
| 591 | mutex_lock(&sp->members_lock); | 594 | mutex_lock(&sp->members_lock); |
| 592 | list_del(&nd->list); | 595 | list_del(&nd->list); |
| @@ -598,7 +601,7 @@ static void drop_node(struct config_group *g, struct config_item *i) | |||
| 598 | 601 | ||
| 599 | static void release_node(struct config_item *i) | 602 | static void release_node(struct config_item *i) |
| 600 | { | 603 | { |
| 601 | struct dlm_node *nd = to_node(i); | 604 | struct dlm_node *nd = config_item_to_node(i); |
| 602 | kfree(nd); | 605 | kfree(nd); |
| 603 | } | 606 | } |
| 604 | 607 | ||
| @@ -632,7 +635,7 @@ void dlm_config_exit(void) | |||
| 632 | static ssize_t show_cluster(struct config_item *i, struct configfs_attribute *a, | 635 | static ssize_t show_cluster(struct config_item *i, struct configfs_attribute *a, |
| 633 | char *buf) | 636 | char *buf) |
| 634 | { | 637 | { |
| 635 | struct dlm_cluster *cl = to_cluster(i); | 638 | struct dlm_cluster *cl = config_item_to_cluster(i); |
| 636 | struct cluster_attribute *cla = | 639 | struct cluster_attribute *cla = |
| 637 | container_of(a, struct cluster_attribute, attr); | 640 | container_of(a, struct cluster_attribute, attr); |
| 638 | return cla->show ? cla->show(cl, buf) : 0; | 641 | return cla->show ? cla->show(cl, buf) : 0; |
| @@ -642,7 +645,7 @@ static ssize_t store_cluster(struct config_item *i, | |||
| 642 | struct configfs_attribute *a, | 645 | struct configfs_attribute *a, |
| 643 | const char *buf, size_t len) | 646 | const char *buf, size_t len) |
| 644 | { | 647 | { |
| 645 | struct dlm_cluster *cl = to_cluster(i); | 648 | struct dlm_cluster *cl = config_item_to_cluster(i); |
| 646 | struct cluster_attribute *cla = | 649 | struct cluster_attribute *cla = |
| 647 | container_of(a, struct cluster_attribute, attr); | 650 | container_of(a, struct cluster_attribute, attr); |
| 648 | return cla->store ? cla->store(cl, buf, len) : -EINVAL; | 651 | return cla->store ? cla->store(cl, buf, len) : -EINVAL; |
| @@ -651,7 +654,7 @@ static ssize_t store_cluster(struct config_item *i, | |||
| 651 | static ssize_t show_comm(struct config_item *i, struct configfs_attribute *a, | 654 | static ssize_t show_comm(struct config_item *i, struct configfs_attribute *a, |
| 652 | char *buf) | 655 | char *buf) |
| 653 | { | 656 | { |
| 654 | struct dlm_comm *cm = to_comm(i); | 657 | struct dlm_comm *cm = config_item_to_comm(i); |
| 655 | struct comm_attribute *cma = | 658 | struct comm_attribute *cma = |
| 656 | container_of(a, struct comm_attribute, attr); | 659 | container_of(a, struct comm_attribute, attr); |
| 657 | return cma->show ? cma->show(cm, buf) : 0; | 660 | return cma->show ? cma->show(cm, buf) : 0; |
| @@ -660,7 +663,7 @@ static ssize_t show_comm(struct config_item *i, struct configfs_attribute *a, | |||
| 660 | static ssize_t store_comm(struct config_item *i, struct configfs_attribute *a, | 663 | static ssize_t store_comm(struct config_item *i, struct configfs_attribute *a, |
| 661 | const char *buf, size_t len) | 664 | const char *buf, size_t len) |
| 662 | { | 665 | { |
| 663 | struct dlm_comm *cm = to_comm(i); | 666 | struct dlm_comm *cm = config_item_to_comm(i); |
| 664 | struct comm_attribute *cma = | 667 | struct comm_attribute *cma = |
| 665 | container_of(a, struct comm_attribute, attr); | 668 | container_of(a, struct comm_attribute, attr); |
| 666 | return cma->store ? cma->store(cm, buf, len) : -EINVAL; | 669 | return cma->store ? cma->store(cm, buf, len) : -EINVAL; |
| @@ -714,7 +717,7 @@ static ssize_t comm_addr_write(struct dlm_comm *cm, const char *buf, size_t len) | |||
| 714 | static ssize_t show_node(struct config_item *i, struct configfs_attribute *a, | 717 | static ssize_t show_node(struct config_item *i, struct configfs_attribute *a, |
| 715 | char *buf) | 718 | char *buf) |
| 716 | { | 719 | { |
| 717 | struct dlm_node *nd = to_node(i); | 720 | struct dlm_node *nd = config_item_to_node(i); |
| 718 | struct node_attribute *nda = | 721 | struct node_attribute *nda = |
| 719 | container_of(a, struct node_attribute, attr); | 722 | container_of(a, struct node_attribute, attr); |
| 720 | return nda->show ? nda->show(nd, buf) : 0; | 723 | return nda->show ? nda->show(nd, buf) : 0; |
| @@ -723,7 +726,7 @@ static ssize_t show_node(struct config_item *i, struct configfs_attribute *a, | |||
| 723 | static ssize_t store_node(struct config_item *i, struct configfs_attribute *a, | 726 | static ssize_t store_node(struct config_item *i, struct configfs_attribute *a, |
| 724 | const char *buf, size_t len) | 727 | const char *buf, size_t len) |
| 725 | { | 728 | { |
| 726 | struct dlm_node *nd = to_node(i); | 729 | struct dlm_node *nd = config_item_to_node(i); |
| 727 | struct node_attribute *nda = | 730 | struct node_attribute *nda = |
| 728 | container_of(a, struct node_attribute, attr); | 731 | container_of(a, struct node_attribute, attr); |
| 729 | return nda->store ? nda->store(nd, buf, len) : -EINVAL; | 732 | return nda->store ? nda->store(nd, buf, len) : -EINVAL; |
| @@ -768,7 +771,7 @@ static struct dlm_space *get_space(char *name) | |||
| 768 | i = config_group_find_item(space_list, name); | 771 | i = config_group_find_item(space_list, name); |
| 769 | mutex_unlock(&space_list->cg_subsys->su_mutex); | 772 | mutex_unlock(&space_list->cg_subsys->su_mutex); |
| 770 | 773 | ||
| 771 | return to_space(i); | 774 | return config_item_to_space(i); |
| 772 | } | 775 | } |
| 773 | 776 | ||
| 774 | static void put_space(struct dlm_space *sp) | 777 | static void put_space(struct dlm_space *sp) |
| @@ -776,6 +779,33 @@ static void put_space(struct dlm_space *sp) | |||
| 776 | config_item_put(&sp->group.cg_item); | 779 | config_item_put(&sp->group.cg_item); |
| 777 | } | 780 | } |
| 778 | 781 | ||
| 782 | static int addr_compare(struct sockaddr_storage *x, struct sockaddr_storage *y) | ||
| 783 | { | ||
| 784 | switch (x->ss_family) { | ||
| 785 | case AF_INET: { | ||
| 786 | struct sockaddr_in *sinx = (struct sockaddr_in *)x; | ||
| 787 | struct sockaddr_in *siny = (struct sockaddr_in *)y; | ||
| 788 | if (sinx->sin_addr.s_addr != siny->sin_addr.s_addr) | ||
| 789 | return 0; | ||
| 790 | if (sinx->sin_port != siny->sin_port) | ||
| 791 | return 0; | ||
| 792 | break; | ||
| 793 | } | ||
| 794 | case AF_INET6: { | ||
| 795 | struct sockaddr_in6 *sinx = (struct sockaddr_in6 *)x; | ||
| 796 | struct sockaddr_in6 *siny = (struct sockaddr_in6 *)y; | ||
| 797 | if (!ipv6_addr_equal(&sinx->sin6_addr, &siny->sin6_addr)) | ||
| 798 | return 0; | ||
| 799 | if (sinx->sin6_port != siny->sin6_port) | ||
| 800 | return 0; | ||
| 801 | break; | ||
| 802 | } | ||
| 803 | default: | ||
| 804 | return 0; | ||
| 805 | } | ||
| 806 | return 1; | ||
| 807 | } | ||
| 808 | |||
| 779 | static struct dlm_comm *get_comm(int nodeid, struct sockaddr_storage *addr) | 809 | static struct dlm_comm *get_comm(int nodeid, struct sockaddr_storage *addr) |
| 780 | { | 810 | { |
| 781 | struct config_item *i; | 811 | struct config_item *i; |
| @@ -788,7 +818,7 @@ static struct dlm_comm *get_comm(int nodeid, struct sockaddr_storage *addr) | |||
| 788 | mutex_lock(&clusters_root.subsys.su_mutex); | 818 | mutex_lock(&clusters_root.subsys.su_mutex); |
| 789 | 819 | ||
| 790 | list_for_each_entry(i, &comm_list->cg_children, ci_entry) { | 820 | list_for_each_entry(i, &comm_list->cg_children, ci_entry) { |
| 791 | cm = to_comm(i); | 821 | cm = config_item_to_comm(i); |
| 792 | 822 | ||
| 793 | if (nodeid) { | 823 | if (nodeid) { |
| 794 | if (cm->nodeid != nodeid) | 824 | if (cm->nodeid != nodeid) |
| @@ -797,8 +827,7 @@ static struct dlm_comm *get_comm(int nodeid, struct sockaddr_storage *addr) | |||
| 797 | config_item_get(i); | 827 | config_item_get(i); |
| 798 | break; | 828 | break; |
| 799 | } else { | 829 | } else { |
| 800 | if (!cm->addr_count || | 830 | if (!cm->addr_count || !addr_compare(cm->addr[0], addr)) |
| 801 | memcmp(cm->addr[0], addr, sizeof(*addr))) | ||
| 802 | continue; | 831 | continue; |
| 803 | found = 1; | 832 | found = 1; |
| 804 | config_item_get(i); | 833 | config_item_get(i); |
diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h index 5a7ac33b629c..868e4c9ef127 100644 --- a/fs/dlm/dlm_internal.h +++ b/fs/dlm/dlm_internal.h | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | ******************************************************************************* | 2 | ******************************************************************************* |
| 3 | ** | 3 | ** |
| 4 | ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | 4 | ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
| 5 | ** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. | 5 | ** Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved. |
| 6 | ** | 6 | ** |
| 7 | ** This copyrighted material is made available to anyone wishing to use, | 7 | ** This copyrighted material is made available to anyone wishing to use, |
| 8 | ** modify, copy, or redistribute it subject to the terms and conditions | 8 | ** modify, copy, or redistribute it subject to the terms and conditions |
| @@ -441,8 +441,11 @@ struct dlm_ls { | |||
| 441 | uint32_t ls_global_id; /* global unique lockspace ID */ | 441 | uint32_t ls_global_id; /* global unique lockspace ID */ |
| 442 | uint32_t ls_exflags; | 442 | uint32_t ls_exflags; |
| 443 | int ls_lvblen; | 443 | int ls_lvblen; |
| 444 | int ls_count; /* reference count */ | 444 | int ls_count; /* refcount of processes in |
| 445 | the dlm using this ls */ | ||
| 446 | int ls_create_count; /* create/release refcount */ | ||
| 445 | unsigned long ls_flags; /* LSFL_ */ | 447 | unsigned long ls_flags; /* LSFL_ */ |
| 448 | unsigned long ls_scan_time; | ||
| 446 | struct kobject ls_kobj; | 449 | struct kobject ls_kobj; |
| 447 | 450 | ||
| 448 | struct dlm_rsbtable *ls_rsbtbl; | 451 | struct dlm_rsbtable *ls_rsbtbl; |
diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c index 499e16759e96..d910501de6d2 100644 --- a/fs/dlm/lockspace.c +++ b/fs/dlm/lockspace.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | ******************************************************************************* | 2 | ******************************************************************************* |
| 3 | ** | 3 | ** |
| 4 | ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | 4 | ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
| 5 | ** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. | 5 | ** Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved. |
| 6 | ** | 6 | ** |
| 7 | ** This copyrighted material is made available to anyone wishing to use, | 7 | ** This copyrighted material is made available to anyone wishing to use, |
| 8 | ** modify, copy, or redistribute it subject to the terms and conditions | 8 | ** modify, copy, or redistribute it subject to the terms and conditions |
| @@ -23,6 +23,7 @@ | |||
| 23 | #include "lock.h" | 23 | #include "lock.h" |
| 24 | #include "recover.h" | 24 | #include "recover.h" |
| 25 | #include "requestqueue.h" | 25 | #include "requestqueue.h" |
| 26 | #include "user.h" | ||
| 26 | 27 | ||
| 27 | static int ls_count; | 28 | static int ls_count; |
| 28 | static struct mutex ls_lock; | 29 | static struct mutex ls_lock; |
| @@ -211,19 +212,41 @@ void dlm_lockspace_exit(void) | |||
| 211 | kset_unregister(dlm_kset); | 212 | kset_unregister(dlm_kset); |
| 212 | } | 213 | } |
| 213 | 214 | ||
| 215 | static struct dlm_ls *find_ls_to_scan(void) | ||
| 216 | { | ||
| 217 | struct dlm_ls *ls; | ||
| 218 | |||
| 219 | spin_lock(&lslist_lock); | ||
| 220 | list_for_each_entry(ls, &lslist, ls_list) { | ||
| 221 | if (time_after_eq(jiffies, ls->ls_scan_time + | ||
| 222 | dlm_config.ci_scan_secs * HZ)) { | ||
| 223 | spin_unlock(&lslist_lock); | ||
| 224 | return ls; | ||
| 225 | } | ||
| 226 | } | ||
| 227 | spin_unlock(&lslist_lock); | ||
| 228 | return NULL; | ||
| 229 | } | ||
| 230 | |||
| 214 | static int dlm_scand(void *data) | 231 | static int dlm_scand(void *data) |
| 215 | { | 232 | { |
| 216 | struct dlm_ls *ls; | 233 | struct dlm_ls *ls; |
| 234 | int timeout_jiffies = dlm_config.ci_scan_secs * HZ; | ||
| 217 | 235 | ||
| 218 | while (!kthread_should_stop()) { | 236 | while (!kthread_should_stop()) { |
| 219 | list_for_each_entry(ls, &lslist, ls_list) { | 237 | ls = find_ls_to_scan(); |
| 238 | if (ls) { | ||
| 220 | if (dlm_lock_recovery_try(ls)) { | 239 | if (dlm_lock_recovery_try(ls)) { |
| 240 | ls->ls_scan_time = jiffies; | ||
| 221 | dlm_scan_rsbs(ls); | 241 | dlm_scan_rsbs(ls); |
| 222 | dlm_scan_timeout(ls); | 242 | dlm_scan_timeout(ls); |
| 223 | dlm_unlock_recovery(ls); | 243 | dlm_unlock_recovery(ls); |
| 244 | } else { | ||
| 245 | ls->ls_scan_time += HZ; | ||
| 224 | } | 246 | } |
| 247 | } else { | ||
| 248 | schedule_timeout_interruptible(timeout_jiffies); | ||
| 225 | } | 249 | } |
| 226 | schedule_timeout_interruptible(dlm_config.ci_scan_secs * HZ); | ||
| 227 | } | 250 | } |
| 228 | return 0; | 251 | return 0; |
| 229 | } | 252 | } |
| @@ -246,23 +269,6 @@ static void dlm_scand_stop(void) | |||
| 246 | kthread_stop(scand_task); | 269 | kthread_stop(scand_task); |
| 247 | } | 270 | } |
| 248 | 271 | ||
| 249 | static struct dlm_ls *dlm_find_lockspace_name(char *name, int namelen) | ||
| 250 | { | ||
| 251 | struct dlm_ls *ls; | ||
| 252 | |||
| 253 | spin_lock(&lslist_lock); | ||
| 254 | |||
| 255 | list_for_each_entry(ls, &lslist, ls_list) { | ||
| 256 | if (ls->ls_namelen == namelen && | ||
| 257 | memcmp(ls->ls_name, name, namelen) == 0) | ||
| 258 | goto out; | ||
| 259 | } | ||
| 260 | ls = NULL; | ||
| 261 | out: | ||
| 262 | spin_unlock(&lslist_lock); | ||
| 263 | return ls; | ||
| 264 | } | ||
| 265 | |||
| 266 | struct dlm_ls *dlm_find_lockspace_global(uint32_t id) | 272 | struct dlm_ls *dlm_find_lockspace_global(uint32_t id) |
| 267 | { | 273 | { |
| 268 | struct dlm_ls *ls; | 274 | struct dlm_ls *ls; |
| @@ -327,6 +333,7 @@ static void remove_lockspace(struct dlm_ls *ls) | |||
| 327 | for (;;) { | 333 | for (;;) { |
| 328 | spin_lock(&lslist_lock); | 334 | spin_lock(&lslist_lock); |
| 329 | if (ls->ls_count == 0) { | 335 | if (ls->ls_count == 0) { |
| 336 | WARN_ON(ls->ls_create_count != 0); | ||
| 330 | list_del(&ls->ls_list); | 337 | list_del(&ls->ls_list); |
| 331 | spin_unlock(&lslist_lock); | 338 | spin_unlock(&lslist_lock); |
| 332 | return; | 339 | return; |
| @@ -381,7 +388,7 @@ static int new_lockspace(char *name, int namelen, void **lockspace, | |||
| 381 | uint32_t flags, int lvblen) | 388 | uint32_t flags, int lvblen) |
| 382 | { | 389 | { |
| 383 | struct dlm_ls *ls; | 390 | struct dlm_ls *ls; |
| 384 | int i, size, error = -ENOMEM; | 391 | int i, size, error; |
| 385 | int do_unreg = 0; | 392 | int do_unreg = 0; |
| 386 | 393 | ||
| 387 | if (namelen > DLM_LOCKSPACE_LEN) | 394 | if (namelen > DLM_LOCKSPACE_LEN) |
| @@ -393,12 +400,37 @@ static int new_lockspace(char *name, int namelen, void **lockspace, | |||
| 393 | if (!try_module_get(THIS_MODULE)) | 400 | if (!try_module_get(THIS_MODULE)) |
| 394 | return -EINVAL; | 401 | return -EINVAL; |
| 395 | 402 | ||
| 396 | ls = dlm_find_lockspace_name(name, namelen); | 403 | if (!dlm_user_daemon_available()) { |
| 397 | if (ls) { | 404 | module_put(THIS_MODULE); |
| 398 | *lockspace = ls; | 405 | return -EUNATCH; |
| 406 | } | ||
| 407 | |||
| 408 | error = 0; | ||
| 409 | |||
| 410 | spin_lock(&lslist_lock); | ||
| 411 | list_for_each_entry(ls, &lslist, ls_list) { | ||
| 412 | WARN_ON(ls->ls_create_count <= 0); | ||
| 413 | if (ls->ls_namelen != namelen) | ||
| 414 | continue; | ||
| 415 | if (memcmp(ls->ls_name, name, namelen)) | ||
| 416 | continue; | ||
| 417 | if (flags & DLM_LSFL_NEWEXCL) { | ||
| 418 | error = -EEXIST; | ||
| 419 | break; | ||
| 420 | } | ||
| 421 | ls->ls_create_count++; | ||
| 399 | module_put(THIS_MODULE); | 422 | module_put(THIS_MODULE); |
| 400 | return -EEXIST; | 423 | error = 1; /* not an error, return 0 */ |
| 424 | break; | ||
| 401 | } | 425 | } |
| 426 | spin_unlock(&lslist_lock); | ||
| 427 | |||
| 428 | if (error < 0) | ||
| 429 | goto out; | ||
| 430 | if (error) | ||
| 431 | goto ret_zero; | ||
| 432 | |||
| 433 | error = -ENOMEM; | ||
| 402 | 434 | ||
| 403 | ls = kzalloc(sizeof(struct dlm_ls) + namelen, GFP_KERNEL); | 435 | ls = kzalloc(sizeof(struct dlm_ls) + namelen, GFP_KERNEL); |
| 404 | if (!ls) | 436 | if (!ls) |
| @@ -408,6 +440,7 @@ static int new_lockspace(char *name, int namelen, void **lockspace, | |||
| 408 | ls->ls_lvblen = lvblen; | 440 | ls->ls_lvblen = lvblen; |
| 409 | ls->ls_count = 0; | 441 | ls->ls_count = 0; |
| 410 | ls->ls_flags = 0; | 442 | ls->ls_flags = 0; |
| 443 | ls->ls_scan_time = jiffies; | ||
| 411 | 444 | ||
| 412 | if (flags & DLM_LSFL_TIMEWARN) | 445 | if (flags & DLM_LSFL_TIMEWARN) |
| 413 | set_bit(LSFL_TIMEWARN, &ls->ls_flags); | 446 | set_bit(LSFL_TIMEWARN, &ls->ls_flags); |
| @@ -418,8 +451,9 @@ static int new_lockspace(char *name, int namelen, void **lockspace, | |||
| 418 | ls->ls_allocation = GFP_KERNEL; | 451 | ls->ls_allocation = GFP_KERNEL; |
| 419 | 452 | ||
| 420 | /* ls_exflags are forced to match among nodes, and we don't | 453 | /* ls_exflags are forced to match among nodes, and we don't |
| 421 | need to require all nodes to have TIMEWARN or FS set */ | 454 | need to require all nodes to have some flags set */ |
| 422 | ls->ls_exflags = (flags & ~(DLM_LSFL_TIMEWARN | DLM_LSFL_FS)); | 455 | ls->ls_exflags = (flags & ~(DLM_LSFL_TIMEWARN | DLM_LSFL_FS | |
| 456 | DLM_LSFL_NEWEXCL)); | ||
| 423 | 457 | ||
| 424 | size = dlm_config.ci_rsbtbl_size; | 458 | size = dlm_config.ci_rsbtbl_size; |
| 425 | ls->ls_rsbtbl_size = size; | 459 | ls->ls_rsbtbl_size = size; |
| @@ -510,6 +544,7 @@ static int new_lockspace(char *name, int namelen, void **lockspace, | |||
| 510 | down_write(&ls->ls_in_recovery); | 544 | down_write(&ls->ls_in_recovery); |
| 511 | 545 | ||
| 512 | spin_lock(&lslist_lock); | 546 | spin_lock(&lslist_lock); |
| 547 | ls->ls_create_count = 1; | ||
| 513 | list_add(&ls->ls_list, &lslist); | 548 | list_add(&ls->ls_list, &lslist); |
| 514 | spin_unlock(&lslist_lock); | 549 | spin_unlock(&lslist_lock); |
| 515 | 550 | ||
| @@ -548,7 +583,7 @@ static int new_lockspace(char *name, int namelen, void **lockspace, | |||
| 548 | dlm_create_debug_file(ls); | 583 | dlm_create_debug_file(ls); |
| 549 | 584 | ||
| 550 | log_debug(ls, "join complete"); | 585 | log_debug(ls, "join complete"); |
| 551 | 586 | ret_zero: | |
| 552 | *lockspace = ls; | 587 | *lockspace = ls; |
| 553 | return 0; | 588 | return 0; |
| 554 | 589 | ||
| @@ -635,13 +670,34 @@ static int release_lockspace(struct dlm_ls *ls, int force) | |||
| 635 | struct dlm_lkb *lkb; | 670 | struct dlm_lkb *lkb; |
| 636 | struct dlm_rsb *rsb; | 671 | struct dlm_rsb *rsb; |
| 637 | struct list_head *head; | 672 | struct list_head *head; |
| 638 | int i; | 673 | int i, busy, rv; |
| 639 | int busy = lockspace_busy(ls); | 674 | |
| 675 | busy = lockspace_busy(ls); | ||
| 676 | |||
| 677 | spin_lock(&lslist_lock); | ||
| 678 | if (ls->ls_create_count == 1) { | ||
| 679 | if (busy > force) | ||
| 680 | rv = -EBUSY; | ||
| 681 | else { | ||
| 682 | /* remove_lockspace takes ls off lslist */ | ||
| 683 | ls->ls_create_count = 0; | ||
| 684 | rv = 0; | ||
| 685 | } | ||
| 686 | } else if (ls->ls_create_count > 1) { | ||
| 687 | rv = --ls->ls_create_count; | ||
| 688 | } else { | ||
| 689 | rv = -EINVAL; | ||
| 690 | } | ||
| 691 | spin_unlock(&lslist_lock); | ||
| 640 | 692 | ||
| 641 | if (busy > force) | 693 | if (rv) { |
| 642 | return -EBUSY; | 694 | log_debug(ls, "release_lockspace no remove %d", rv); |
| 695 | return rv; | ||
| 696 | } | ||
| 697 | |||
| 698 | dlm_device_deregister(ls); | ||
| 643 | 699 | ||
| 644 | if (force < 3) | 700 | if (force < 3 && dlm_user_daemon_available()) |
| 645 | do_uevent(ls, 0); | 701 | do_uevent(ls, 0); |
| 646 | 702 | ||
| 647 | dlm_recoverd_stop(ls); | 703 | dlm_recoverd_stop(ls); |
| @@ -720,15 +776,10 @@ static int release_lockspace(struct dlm_ls *ls, int force) | |||
| 720 | dlm_clear_members(ls); | 776 | dlm_clear_members(ls); |
| 721 | dlm_clear_members_gone(ls); | 777 | dlm_clear_members_gone(ls); |
| 722 | kfree(ls->ls_node_array); | 778 | kfree(ls->ls_node_array); |
| 779 | log_debug(ls, "release_lockspace final free"); | ||
| 723 | kobject_put(&ls->ls_kobj); | 780 | kobject_put(&ls->ls_kobj); |
| 724 | /* The ls structure will be freed when the kobject is done with */ | 781 | /* The ls structure will be freed when the kobject is done with */ |
| 725 | 782 | ||
| 726 | mutex_lock(&ls_lock); | ||
| 727 | ls_count--; | ||
| 728 | if (!ls_count) | ||
| 729 | threads_stop(); | ||
| 730 | mutex_unlock(&ls_lock); | ||
| 731 | |||
| 732 | module_put(THIS_MODULE); | 783 | module_put(THIS_MODULE); |
| 733 | return 0; | 784 | return 0; |
| 734 | } | 785 | } |
| @@ -750,11 +801,38 @@ static int release_lockspace(struct dlm_ls *ls, int force) | |||
| 750 | int dlm_release_lockspace(void *lockspace, int force) | 801 | int dlm_release_lockspace(void *lockspace, int force) |
| 751 | { | 802 | { |
| 752 | struct dlm_ls *ls; | 803 | struct dlm_ls *ls; |
| 804 | int error; | ||
| 753 | 805 | ||
| 754 | ls = dlm_find_lockspace_local(lockspace); | 806 | ls = dlm_find_lockspace_local(lockspace); |
| 755 | if (!ls) | 807 | if (!ls) |
| 756 | return -EINVAL; | 808 | return -EINVAL; |
| 757 | dlm_put_lockspace(ls); | 809 | dlm_put_lockspace(ls); |
| 758 | return release_lockspace(ls, force); | 810 | |
| 811 | mutex_lock(&ls_lock); | ||
| 812 | error = release_lockspace(ls, force); | ||
| 813 | if (!error) | ||
| 814 | ls_count--; | ||
| 815 | else if (!ls_count) | ||
| 816 | threads_stop(); | ||
| 817 | mutex_unlock(&ls_lock); | ||
| 818 | |||
| 819 | return error; | ||
| 820 | } | ||
| 821 | |||
| 822 | void dlm_stop_lockspaces(void) | ||
| 823 | { | ||
| 824 | struct dlm_ls *ls; | ||
| 825 | |||
| 826 | restart: | ||
| 827 | spin_lock(&lslist_lock); | ||
| 828 | list_for_each_entry(ls, &lslist, ls_list) { | ||
| 829 | if (!test_bit(LSFL_RUNNING, &ls->ls_flags)) | ||
| 830 | continue; | ||
| 831 | spin_unlock(&lslist_lock); | ||
| 832 | log_error(ls, "no userland control daemon, stopping lockspace"); | ||
| 833 | dlm_ls_stop(ls); | ||
| 834 | goto restart; | ||
| 835 | } | ||
| 836 | spin_unlock(&lslist_lock); | ||
| 759 | } | 837 | } |
| 760 | 838 | ||
diff --git a/fs/dlm/lockspace.h b/fs/dlm/lockspace.h index 891eabbdd021..f879f87901f8 100644 --- a/fs/dlm/lockspace.h +++ b/fs/dlm/lockspace.h | |||
| @@ -20,6 +20,7 @@ struct dlm_ls *dlm_find_lockspace_global(uint32_t id); | |||
| 20 | struct dlm_ls *dlm_find_lockspace_local(void *id); | 20 | struct dlm_ls *dlm_find_lockspace_local(void *id); |
| 21 | struct dlm_ls *dlm_find_lockspace_device(int minor); | 21 | struct dlm_ls *dlm_find_lockspace_device(int minor); |
| 22 | void dlm_put_lockspace(struct dlm_ls *ls); | 22 | void dlm_put_lockspace(struct dlm_ls *ls); |
| 23 | void dlm_stop_lockspaces(void); | ||
| 23 | 24 | ||
| 24 | #endif /* __LOCKSPACE_DOT_H__ */ | 25 | #endif /* __LOCKSPACE_DOT_H__ */ |
| 25 | 26 | ||
diff --git a/fs/dlm/user.c b/fs/dlm/user.c index 34f14a14fb4e..b3832c67194a 100644 --- a/fs/dlm/user.c +++ b/fs/dlm/user.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 2006-2007 Red Hat, Inc. All rights reserved. | 2 | * Copyright (C) 2006-2008 Red Hat, Inc. All rights reserved. |
| 3 | * | 3 | * |
| 4 | * This copyrighted material is made available to anyone wishing to use, | 4 | * This copyrighted material is made available to anyone wishing to use, |
| 5 | * modify, copy, or redistribute it subject to the terms and conditions | 5 | * modify, copy, or redistribute it subject to the terms and conditions |
| @@ -15,7 +15,6 @@ | |||
| 15 | #include <linux/poll.h> | 15 | #include <linux/poll.h> |
| 16 | #include <linux/signal.h> | 16 | #include <linux/signal.h> |
| 17 | #include <linux/spinlock.h> | 17 | #include <linux/spinlock.h> |
| 18 | #include <linux/smp_lock.h> | ||
| 19 | #include <linux/dlm.h> | 18 | #include <linux/dlm.h> |
| 20 | #include <linux/dlm_device.h> | 19 | #include <linux/dlm_device.h> |
| 21 | 20 | ||
| @@ -27,6 +26,8 @@ | |||
| 27 | 26 | ||
| 28 | static const char name_prefix[] = "dlm"; | 27 | static const char name_prefix[] = "dlm"; |
| 29 | static const struct file_operations device_fops; | 28 | static const struct file_operations device_fops; |
| 29 | static atomic_t dlm_monitor_opened; | ||
| 30 | static int dlm_monitor_unused = 1; | ||
| 30 | 31 | ||
| 31 | #ifdef CONFIG_COMPAT | 32 | #ifdef CONFIG_COMPAT |
| 32 | 33 | ||
| @@ -340,10 +341,15 @@ static int device_user_deadlock(struct dlm_user_proc *proc, | |||
| 340 | return error; | 341 | return error; |
| 341 | } | 342 | } |
| 342 | 343 | ||
| 343 | static int create_misc_device(struct dlm_ls *ls, char *name) | 344 | static int dlm_device_register(struct dlm_ls *ls, char *name) |
| 344 | { | 345 | { |
| 345 | int error, len; | 346 | int error, len; |
| 346 | 347 | ||
| 348 | /* The device is already registered. This happens when the | ||
| 349 | lockspace is created multiple times from userspace. */ | ||
| 350 | if (ls->ls_device.name) | ||
| 351 | return 0; | ||
| 352 | |||
| 347 | error = -ENOMEM; | 353 | error = -ENOMEM; |
| 348 | len = strlen(name) + strlen(name_prefix) + 2; | 354 | len = strlen(name) + strlen(name_prefix) + 2; |
| 349 | ls->ls_device.name = kzalloc(len, GFP_KERNEL); | 355 | ls->ls_device.name = kzalloc(len, GFP_KERNEL); |
| @@ -363,6 +369,22 @@ fail: | |||
| 363 | return error; | 369 | return error; |
| 364 | } | 370 | } |
| 365 | 371 | ||
| 372 | int dlm_device_deregister(struct dlm_ls *ls) | ||
| 373 | { | ||
| 374 | int error; | ||
| 375 | |||
| 376 | /* The device is not registered. This happens when the lockspace | ||
| 377 | was never used from userspace, or when device_create_lockspace() | ||
| 378 | calls dlm_release_lockspace() after the register fails. */ | ||
| 379 | if (!ls->ls_device.name) | ||
| 380 | return 0; | ||
| 381 | |||
| 382 | error = misc_deregister(&ls->ls_device); | ||
| 383 | if (!error) | ||
| 384 | kfree(ls->ls_device.name); | ||
| 385 | return error; | ||
| 386 | } | ||
| 387 | |||
| 366 | static int device_user_purge(struct dlm_user_proc *proc, | 388 | static int device_user_purge(struct dlm_user_proc *proc, |
| 367 | struct dlm_purge_params *params) | 389 | struct dlm_purge_params *params) |
| 368 | { | 390 | { |
| @@ -397,7 +419,7 @@ static int device_create_lockspace(struct dlm_lspace_params *params) | |||
| 397 | if (!ls) | 419 | if (!ls) |
| 398 | return -ENOENT; | 420 | return -ENOENT; |
| 399 | 421 | ||
| 400 | error = create_misc_device(ls, params->name); | 422 | error = dlm_device_register(ls, params->name); |
| 401 | dlm_put_lockspace(ls); | 423 | dlm_put_lockspace(ls); |
| 402 | 424 | ||
| 403 | if (error) | 425 | if (error) |
| @@ -421,31 +443,22 @@ static int device_remove_lockspace(struct dlm_lspace_params *params) | |||
| 421 | if (!ls) | 443 | if (!ls) |
| 422 | return -ENOENT; | 444 | return -ENOENT; |
| 423 | 445 | ||
| 424 | /* Deregister the misc device first, so we don't have | ||
| 425 | * a device that's not attached to a lockspace. If | ||
| 426 | * dlm_release_lockspace fails then we can recreate it | ||
| 427 | */ | ||
| 428 | error = misc_deregister(&ls->ls_device); | ||
| 429 | if (error) { | ||
| 430 | dlm_put_lockspace(ls); | ||
| 431 | goto out; | ||
| 432 | } | ||
| 433 | kfree(ls->ls_device.name); | ||
| 434 | |||
| 435 | if (params->flags & DLM_USER_LSFLG_FORCEFREE) | 446 | if (params->flags & DLM_USER_LSFLG_FORCEFREE) |
| 436 | force = 2; | 447 | force = 2; |
| 437 | 448 | ||
| 438 | lockspace = ls->ls_local_handle; | 449 | lockspace = ls->ls_local_handle; |
| 450 | dlm_put_lockspace(ls); | ||
| 439 | 451 | ||
| 440 | /* dlm_release_lockspace waits for references to go to zero, | 452 | /* The final dlm_release_lockspace waits for references to go to |
| 441 | so all processes will need to close their device for the ls | 453 | zero, so all processes will need to close their device for the |
| 442 | before the release will procede */ | 454 | ls before the release will proceed. release also calls the |
| 455 | device_deregister above. Converting a positive return value | ||
| 456 | from release to zero means that userspace won't know when its | ||
| 457 | release was the final one, but it shouldn't need to know. */ | ||
| 443 | 458 | ||
| 444 | dlm_put_lockspace(ls); | ||
| 445 | error = dlm_release_lockspace(lockspace, force); | 459 | error = dlm_release_lockspace(lockspace, force); |
| 446 | if (error) | 460 | if (error > 0) |
| 447 | create_misc_device(ls, ls->ls_name); | 461 | error = 0; |
| 448 | out: | ||
| 449 | return error; | 462 | return error; |
| 450 | } | 463 | } |
| 451 | 464 | ||
| @@ -623,17 +636,13 @@ static int device_open(struct inode *inode, struct file *file) | |||
| 623 | struct dlm_user_proc *proc; | 636 | struct dlm_user_proc *proc; |
| 624 | struct dlm_ls *ls; | 637 | struct dlm_ls *ls; |
| 625 | 638 | ||
| 626 | lock_kernel(); | ||
| 627 | ls = dlm_find_lockspace_device(iminor(inode)); | 639 | ls = dlm_find_lockspace_device(iminor(inode)); |
| 628 | if (!ls) { | 640 | if (!ls) |
| 629 | unlock_kernel(); | ||
| 630 | return -ENOENT; | 641 | return -ENOENT; |
| 631 | } | ||
| 632 | 642 | ||
| 633 | proc = kzalloc(sizeof(struct dlm_user_proc), GFP_KERNEL); | 643 | proc = kzalloc(sizeof(struct dlm_user_proc), GFP_KERNEL); |
| 634 | if (!proc) { | 644 | if (!proc) { |
| 635 | dlm_put_lockspace(ls); | 645 | dlm_put_lockspace(ls); |
| 636 | unlock_kernel(); | ||
| 637 | return -ENOMEM; | 646 | return -ENOMEM; |
| 638 | } | 647 | } |
| 639 | 648 | ||
| @@ -645,7 +654,6 @@ static int device_open(struct inode *inode, struct file *file) | |||
| 645 | spin_lock_init(&proc->locks_spin); | 654 | spin_lock_init(&proc->locks_spin); |
| 646 | init_waitqueue_head(&proc->wait); | 655 | init_waitqueue_head(&proc->wait); |
| 647 | file->private_data = proc; | 656 | file->private_data = proc; |
| 648 | unlock_kernel(); | ||
| 649 | 657 | ||
| 650 | return 0; | 658 | return 0; |
| 651 | } | 659 | } |
| @@ -878,9 +886,28 @@ static unsigned int device_poll(struct file *file, poll_table *wait) | |||
| 878 | return 0; | 886 | return 0; |
| 879 | } | 887 | } |
| 880 | 888 | ||
| 889 | int dlm_user_daemon_available(void) | ||
| 890 | { | ||
| 891 | /* dlm_controld hasn't started (or, has started, but not | ||
| 892 | properly populated configfs) */ | ||
| 893 | |||
| 894 | if (!dlm_our_nodeid()) | ||
| 895 | return 0; | ||
| 896 | |||
| 897 | /* This is to deal with versions of dlm_controld that don't | ||
| 898 | know about the monitor device. We assume that if the | ||
| 899 | dlm_controld was started (above), but the monitor device | ||
| 900 | was never opened, that it's an old version. dlm_controld | ||
| 901 | should open the monitor device before populating configfs. */ | ||
| 902 | |||
| 903 | if (dlm_monitor_unused) | ||
| 904 | return 1; | ||
| 905 | |||
| 906 | return atomic_read(&dlm_monitor_opened) ? 1 : 0; | ||
| 907 | } | ||
| 908 | |||
| 881 | static int ctl_device_open(struct inode *inode, struct file *file) | 909 | static int ctl_device_open(struct inode *inode, struct file *file) |
| 882 | { | 910 | { |
| 883 | cycle_kernel_lock(); | ||
| 884 | file->private_data = NULL; | 911 | file->private_data = NULL; |
| 885 | return 0; | 912 | return 0; |
| 886 | } | 913 | } |
| @@ -890,6 +917,20 @@ static int ctl_device_close(struct inode *inode, struct file *file) | |||
| 890 | return 0; | 917 | return 0; |
| 891 | } | 918 | } |
| 892 | 919 | ||
| 920 | static int monitor_device_open(struct inode *inode, struct file *file) | ||
| 921 | { | ||
| 922 | atomic_inc(&dlm_monitor_opened); | ||
| 923 | dlm_monitor_unused = 0; | ||
| 924 | return 0; | ||
| 925 | } | ||
| 926 | |||
| 927 | static int monitor_device_close(struct inode *inode, struct file *file) | ||
| 928 | { | ||
| 929 | if (atomic_dec_and_test(&dlm_monitor_opened)) | ||
| 930 | dlm_stop_lockspaces(); | ||
| 931 | return 0; | ||
| 932 | } | ||
| 933 | |||
| 893 | static const struct file_operations device_fops = { | 934 | static const struct file_operations device_fops = { |
| 894 | .open = device_open, | 935 | .open = device_open, |
| 895 | .release = device_close, | 936 | .release = device_close, |
| @@ -913,19 +954,42 @@ static struct miscdevice ctl_device = { | |||
| 913 | .minor = MISC_DYNAMIC_MINOR, | 954 | .minor = MISC_DYNAMIC_MINOR, |
| 914 | }; | 955 | }; |
| 915 | 956 | ||
| 957 | static const struct file_operations monitor_device_fops = { | ||
| 958 | .open = monitor_device_open, | ||
| 959 | .release = monitor_device_close, | ||
| 960 | .owner = THIS_MODULE, | ||
| 961 | }; | ||
| 962 | |||
| 963 | static struct miscdevice monitor_device = { | ||
| 964 | .name = "dlm-monitor", | ||
| 965 | .fops = &monitor_device_fops, | ||
| 966 | .minor = MISC_DYNAMIC_MINOR, | ||
| 967 | }; | ||
| 968 | |||
| 916 | int __init dlm_user_init(void) | 969 | int __init dlm_user_init(void) |
| 917 | { | 970 | { |
| 918 | int error; | 971 | int error; |
| 919 | 972 | ||
| 973 | atomic_set(&dlm_monitor_opened, 0); | ||
| 974 | |||
| 920 | error = misc_register(&ctl_device); | 975 | error = misc_register(&ctl_device); |
| 921 | if (error) | 976 | if (error) { |
| 922 | log_print("misc_register failed for control device"); | 977 | log_print("misc_register failed for control device"); |
| 978 | goto out; | ||
| 979 | } | ||
| 923 | 980 | ||
| 981 | error = misc_register(&monitor_device); | ||
| 982 | if (error) { | ||
| 983 | log_print("misc_register failed for monitor device"); | ||
| 984 | misc_deregister(&ctl_device); | ||
| 985 | } | ||
| 986 | out: | ||
| 924 | return error; | 987 | return error; |
| 925 | } | 988 | } |
| 926 | 989 | ||
| 927 | void dlm_user_exit(void) | 990 | void dlm_user_exit(void) |
| 928 | { | 991 | { |
| 929 | misc_deregister(&ctl_device); | 992 | misc_deregister(&ctl_device); |
| 993 | misc_deregister(&monitor_device); | ||
| 930 | } | 994 | } |
| 931 | 995 | ||
diff --git a/fs/dlm/user.h b/fs/dlm/user.h index d38e9f3e4151..35eb6a13d616 100644 --- a/fs/dlm/user.h +++ b/fs/dlm/user.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 2006 Red Hat, Inc. All rights reserved. | 2 | * Copyright (C) 2006-2008 Red Hat, Inc. All rights reserved. |
| 3 | * | 3 | * |
| 4 | * This copyrighted material is made available to anyone wishing to use, | 4 | * This copyrighted material is made available to anyone wishing to use, |
| 5 | * modify, copy, or redistribute it subject to the terms and conditions | 5 | * modify, copy, or redistribute it subject to the terms and conditions |
| @@ -12,5 +12,7 @@ | |||
| 12 | void dlm_user_add_ast(struct dlm_lkb *lkb, int type); | 12 | void dlm_user_add_ast(struct dlm_lkb *lkb, int type); |
| 13 | int dlm_user_init(void); | 13 | int dlm_user_init(void); |
| 14 | void dlm_user_exit(void); | 14 | void dlm_user_exit(void); |
| 15 | int dlm_device_deregister(struct dlm_ls *ls); | ||
| 16 | int dlm_user_daemon_available(void); | ||
| 15 | 17 | ||
| 16 | #endif | 18 | #endif |
diff --git a/fs/gfs2/locking/dlm/mount.c b/fs/gfs2/locking/dlm/mount.c index 09d78c216f48..0c4cbe6c8285 100644 --- a/fs/gfs2/locking/dlm/mount.c +++ b/fs/gfs2/locking/dlm/mount.c | |||
| @@ -144,7 +144,8 @@ static int gdlm_mount(char *table_name, char *host_data, | |||
| 144 | 144 | ||
| 145 | error = dlm_new_lockspace(ls->fsname, strlen(ls->fsname), | 145 | error = dlm_new_lockspace(ls->fsname, strlen(ls->fsname), |
| 146 | &ls->dlm_lockspace, | 146 | &ls->dlm_lockspace, |
| 147 | DLM_LSFL_FS | (nodir ? DLM_LSFL_NODIR : 0), | 147 | DLM_LSFL_FS | DLM_LSFL_NEWEXCL | |
| 148 | (nodir ? DLM_LSFL_NODIR : 0), | ||
| 148 | GDLM_LVB_SIZE); | 149 | GDLM_LVB_SIZE); |
| 149 | if (error) { | 150 | if (error) { |
| 150 | log_error("dlm_new_lockspace error %d", error); | 151 | log_error("dlm_new_lockspace error %d", error); |
diff --git a/include/linux/dlm.h b/include/linux/dlm.h index 203a025e30e5..b9cd38603fd8 100644 --- a/include/linux/dlm.h +++ b/include/linux/dlm.h | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | ******************************************************************************* | 2 | ******************************************************************************* |
| 3 | ** | 3 | ** |
| 4 | ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | 4 | ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
| 5 | ** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. | 5 | ** Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved. |
| 6 | ** | 6 | ** |
| 7 | ** This copyrighted material is made available to anyone wishing to use, | 7 | ** This copyrighted material is made available to anyone wishing to use, |
| 8 | ** modify, copy, or redistribute it subject to the terms and conditions | 8 | ** modify, copy, or redistribute it subject to the terms and conditions |
| @@ -65,9 +65,12 @@ struct dlm_lksb { | |||
| 65 | char * sb_lvbptr; | 65 | char * sb_lvbptr; |
| 66 | }; | 66 | }; |
| 67 | 67 | ||
| 68 | /* dlm_new_lockspace() flags */ | ||
| 69 | |||
| 68 | #define DLM_LSFL_NODIR 0x00000001 | 70 | #define DLM_LSFL_NODIR 0x00000001 |
| 69 | #define DLM_LSFL_TIMEWARN 0x00000002 | 71 | #define DLM_LSFL_TIMEWARN 0x00000002 |
| 70 | #define DLM_LSFL_FS 0x00000004 | 72 | #define DLM_LSFL_FS 0x00000004 |
| 73 | #define DLM_LSFL_NEWEXCL 0x00000008 | ||
| 71 | 74 | ||
| 72 | #ifdef __KERNEL__ | 75 | #ifdef __KERNEL__ |
| 73 | 76 | ||
diff --git a/include/linux/dlm_device.h b/include/linux/dlm_device.h index c6034508fed9..3060783c4191 100644 --- a/include/linux/dlm_device.h +++ b/include/linux/dlm_device.h | |||
| @@ -26,7 +26,7 @@ | |||
| 26 | /* Version of the device interface */ | 26 | /* Version of the device interface */ |
| 27 | #define DLM_DEVICE_VERSION_MAJOR 6 | 27 | #define DLM_DEVICE_VERSION_MAJOR 6 |
| 28 | #define DLM_DEVICE_VERSION_MINOR 0 | 28 | #define DLM_DEVICE_VERSION_MINOR 0 |
| 29 | #define DLM_DEVICE_VERSION_PATCH 0 | 29 | #define DLM_DEVICE_VERSION_PATCH 1 |
| 30 | 30 | ||
| 31 | /* struct passed to the lock write */ | 31 | /* struct passed to the lock write */ |
| 32 | struct dlm_lock_params { | 32 | struct dlm_lock_params { |
