You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-nmw
* git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-nmw: (34 commits) [GFS2] Uncomment sprintf_symbol calling code [DLM] lowcomms style [GFS2] printk warning fixes [GFS2] Patch to fix mmap of stuffed files [GFS2] use lib/parser for parsing mount options [DLM] Lowcomms nodeid range & initialisation fixes [DLM] Fix dlm_lowcoms_stop hang [DLM] fix mode munging [GFS2] lockdump improvements [GFS2] Patch to detect corrupt number of dir entries in leaf and/or inode blocks [GFS2] bz 236008: Kernel gpf doing cat /debugfs/gfs2/xxx (lock dump) [DLM] fs/dlm/ast.c should #include "ast.h" [DLM] Consolidate transport protocols [DLM] Remove redundant assignment [GFS2] Fix bz 234168 (ignoring rgrp flags) [DLM] change lkid format [DLM] interface for purge (2/2) [DLM] add orphan purging code (1/2) [DLM] split create_message function [GFS2] Set drop_count to 0 (off) by default ...
This commit is contained in:
+7
-24
@@ -3,36 +3,19 @@ menu "Distributed Lock Manager"
|
||||
|
||||
config DLM
|
||||
tristate "Distributed Lock Manager (DLM)"
|
||||
depends on SYSFS && (IPV6 || IPV6=n)
|
||||
depends on IPV6 || IPV6=n
|
||||
select CONFIGFS_FS
|
||||
select IP_SCTP if DLM_SCTP
|
||||
select IP_SCTP
|
||||
help
|
||||
A general purpose distributed lock manager for kernel or userspace
|
||||
applications.
|
||||
|
||||
choice
|
||||
prompt "Select DLM communications protocol"
|
||||
depends on DLM
|
||||
default DLM_TCP
|
||||
help
|
||||
The DLM Can use TCP or SCTP for it's network communications.
|
||||
SCTP supports multi-homed operations whereas TCP doesn't.
|
||||
However, SCTP seems to have stability problems at the moment.
|
||||
|
||||
config DLM_TCP
|
||||
bool "TCP/IP"
|
||||
|
||||
config DLM_SCTP
|
||||
bool "SCTP"
|
||||
|
||||
endchoice
|
||||
A general purpose distributed lock manager for kernel or userspace
|
||||
applications.
|
||||
|
||||
config DLM_DEBUG
|
||||
bool "DLM debugging"
|
||||
depends on DLM
|
||||
help
|
||||
Under the debugfs mount point, the name of each lockspace will
|
||||
appear as a file in the "dlm" directory. The output is the
|
||||
list of resource and locks the local node knows about.
|
||||
Under the debugfs mount point, the name of each lockspace will
|
||||
appear as a file in the "dlm" directory. The output is the
|
||||
list of resource and locks the local node knows about.
|
||||
|
||||
endmenu
|
||||
|
||||
+2
-4
@@ -8,14 +8,12 @@ dlm-y := ast.o \
|
||||
member.o \
|
||||
memory.o \
|
||||
midcomms.o \
|
||||
lowcomms.o \
|
||||
rcom.o \
|
||||
recover.o \
|
||||
recoverd.o \
|
||||
requestqueue.o \
|
||||
user.o \
|
||||
util.o
|
||||
util.o
|
||||
dlm-$(CONFIG_DLM_DEBUG) += debug_fs.o
|
||||
|
||||
dlm-$(CONFIG_DLM_TCP) += lowcomms-tcp.o
|
||||
|
||||
dlm-$(CONFIG_DLM_SCTP) += lowcomms-sctp.o
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "dlm_internal.h"
|
||||
#include "lock.h"
|
||||
#include "user.h"
|
||||
#include "ast.h"
|
||||
|
||||
#define WAKE_ASTS 0
|
||||
|
||||
|
||||
+8
-2
@@ -2,7 +2,7 @@
|
||||
*******************************************************************************
|
||||
**
|
||||
** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
|
||||
** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
|
||||
** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
|
||||
**
|
||||
** This copyrighted material is made available to anyone wishing to use,
|
||||
** modify, copy, or redistribute it subject to the terms and conditions
|
||||
@@ -89,6 +89,7 @@ struct cluster {
|
||||
unsigned int cl_toss_secs;
|
||||
unsigned int cl_scan_secs;
|
||||
unsigned int cl_log_debug;
|
||||
unsigned int cl_protocol;
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -101,6 +102,7 @@ enum {
|
||||
CLUSTER_ATTR_TOSS_SECS,
|
||||
CLUSTER_ATTR_SCAN_SECS,
|
||||
CLUSTER_ATTR_LOG_DEBUG,
|
||||
CLUSTER_ATTR_PROTOCOL,
|
||||
};
|
||||
|
||||
struct cluster_attribute {
|
||||
@@ -159,6 +161,7 @@ CLUSTER_ATTR(recover_timer, 1);
|
||||
CLUSTER_ATTR(toss_secs, 1);
|
||||
CLUSTER_ATTR(scan_secs, 1);
|
||||
CLUSTER_ATTR(log_debug, 0);
|
||||
CLUSTER_ATTR(protocol, 0);
|
||||
|
||||
static struct configfs_attribute *cluster_attrs[] = {
|
||||
[CLUSTER_ATTR_TCP_PORT] = &cluster_attr_tcp_port.attr,
|
||||
@@ -170,6 +173,7 @@ static struct configfs_attribute *cluster_attrs[] = {
|
||||
[CLUSTER_ATTR_TOSS_SECS] = &cluster_attr_toss_secs.attr,
|
||||
[CLUSTER_ATTR_SCAN_SECS] = &cluster_attr_scan_secs.attr,
|
||||
[CLUSTER_ATTR_LOG_DEBUG] = &cluster_attr_log_debug.attr,
|
||||
[CLUSTER_ATTR_PROTOCOL] = &cluster_attr_protocol.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
@@ -904,6 +908,7 @@ int dlm_our_addr(struct sockaddr_storage *addr, int num)
|
||||
#define DEFAULT_TOSS_SECS 10
|
||||
#define DEFAULT_SCAN_SECS 5
|
||||
#define DEFAULT_LOG_DEBUG 0
|
||||
#define DEFAULT_PROTOCOL 0
|
||||
|
||||
struct dlm_config_info dlm_config = {
|
||||
.ci_tcp_port = DEFAULT_TCP_PORT,
|
||||
@@ -914,6 +919,7 @@ struct dlm_config_info dlm_config = {
|
||||
.ci_recover_timer = DEFAULT_RECOVER_TIMER,
|
||||
.ci_toss_secs = DEFAULT_TOSS_SECS,
|
||||
.ci_scan_secs = DEFAULT_SCAN_SECS,
|
||||
.ci_log_debug = DEFAULT_LOG_DEBUG
|
||||
.ci_log_debug = DEFAULT_LOG_DEBUG,
|
||||
.ci_protocol = DEFAULT_PROTOCOL
|
||||
};
|
||||
|
||||
|
||||
+2
-1
@@ -2,7 +2,7 @@
|
||||
*******************************************************************************
|
||||
**
|
||||
** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
|
||||
** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
|
||||
** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
|
||||
**
|
||||
** This copyrighted material is made available to anyone wishing to use,
|
||||
** modify, copy, or redistribute it subject to the terms and conditions
|
||||
@@ -26,6 +26,7 @@ struct dlm_config_info {
|
||||
int ci_toss_secs;
|
||||
int ci_scan_secs;
|
||||
int ci_log_debug;
|
||||
int ci_protocol;
|
||||
};
|
||||
|
||||
extern struct dlm_config_info dlm_config;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
*******************************************************************************
|
||||
**
|
||||
** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
|
||||
** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
|
||||
** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
|
||||
**
|
||||
** This copyrighted material is made available to anyone wishing to use,
|
||||
** modify, copy, or redistribute it subject to the terms and conditions
|
||||
@@ -210,6 +210,9 @@ struct dlm_args {
|
||||
#define DLM_IFL_MSTCPY 0x00010000
|
||||
#define DLM_IFL_RESEND 0x00020000
|
||||
#define DLM_IFL_DEAD 0x00040000
|
||||
#define DLM_IFL_OVERLAP_UNLOCK 0x00080000
|
||||
#define DLM_IFL_OVERLAP_CANCEL 0x00100000
|
||||
#define DLM_IFL_ENDOFLIFE 0x00200000
|
||||
#define DLM_IFL_USER 0x00000001
|
||||
#define DLM_IFL_ORPHAN 0x00000002
|
||||
|
||||
@@ -230,8 +233,8 @@ struct dlm_lkb {
|
||||
int8_t lkb_grmode; /* granted lock mode */
|
||||
int8_t lkb_bastmode; /* requested mode */
|
||||
int8_t lkb_highbast; /* highest mode bast sent for */
|
||||
|
||||
int8_t lkb_wait_type; /* type of reply waiting for */
|
||||
int8_t lkb_wait_count;
|
||||
int8_t lkb_ast_type; /* type of ast queued for */
|
||||
|
||||
struct list_head lkb_idtbl_list; /* lockspace lkbtbl */
|
||||
@@ -339,6 +342,7 @@ struct dlm_header {
|
||||
#define DLM_MSG_LOOKUP 11
|
||||
#define DLM_MSG_REMOVE 12
|
||||
#define DLM_MSG_LOOKUP_REPLY 13
|
||||
#define DLM_MSG_PURGE 14
|
||||
|
||||
struct dlm_message {
|
||||
struct dlm_header m_header;
|
||||
@@ -440,6 +444,9 @@ struct dlm_ls {
|
||||
struct mutex ls_waiters_mutex;
|
||||
struct list_head ls_waiters; /* lkbs needing a reply */
|
||||
|
||||
struct mutex ls_orphans_mutex;
|
||||
struct list_head ls_orphans;
|
||||
|
||||
struct list_head ls_nodes; /* current nodes in ls */
|
||||
struct list_head ls_nodes_gone; /* dead node list, recovery */
|
||||
int ls_num_nodes; /* number of nodes in ls */
|
||||
|
||||
+741
-218
File diff suppressed because it is too large
Load Diff
@@ -41,6 +41,8 @@ int dlm_user_unlock(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
|
||||
uint32_t flags, uint32_t lkid, char *lvb_in);
|
||||
int dlm_user_cancel(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
|
||||
uint32_t flags, uint32_t lkid);
|
||||
int dlm_user_purge(struct dlm_ls *ls, struct dlm_user_proc *proc,
|
||||
int nodeid, int pid);
|
||||
void dlm_clear_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc);
|
||||
|
||||
static inline int is_master(struct dlm_rsb *r)
|
||||
|
||||
+3
-1
@@ -2,7 +2,7 @@
|
||||
*******************************************************************************
|
||||
**
|
||||
** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
|
||||
** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
|
||||
** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
|
||||
**
|
||||
** This copyrighted material is made available to anyone wishing to use,
|
||||
** modify, copy, or redistribute it subject to the terms and conditions
|
||||
@@ -459,6 +459,8 @@ static int new_lockspace(char *name, int namelen, void **lockspace,
|
||||
|
||||
INIT_LIST_HEAD(&ls->ls_waiters);
|
||||
mutex_init(&ls->ls_waiters_mutex);
|
||||
INIT_LIST_HEAD(&ls->ls_orphans);
|
||||
mutex_init(&ls->ls_orphans_mutex);
|
||||
|
||||
INIT_LIST_HEAD(&ls->ls_nodes);
|
||||
INIT_LIST_HEAD(&ls->ls_nodes_gone);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+106
-55
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2006 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2006-2007 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use,
|
||||
* modify, copy, or redistribute it subject to the terms and conditions
|
||||
@@ -56,6 +56,7 @@ struct dlm_write_request32 {
|
||||
union {
|
||||
struct dlm_lock_params32 lock;
|
||||
struct dlm_lspace_params lspace;
|
||||
struct dlm_purge_params purge;
|
||||
} i;
|
||||
};
|
||||
|
||||
@@ -92,6 +93,9 @@ static void compat_input(struct dlm_write_request *kb,
|
||||
kb->i.lspace.flags = kb32->i.lspace.flags;
|
||||
kb->i.lspace.minor = kb32->i.lspace.minor;
|
||||
strcpy(kb->i.lspace.name, kb32->i.lspace.name);
|
||||
} else if (kb->cmd == DLM_USER_PURGE) {
|
||||
kb->i.purge.nodeid = kb32->i.purge.nodeid;
|
||||
kb->i.purge.pid = kb32->i.purge.pid;
|
||||
} else {
|
||||
kb->i.lock.mode = kb32->i.lock.mode;
|
||||
kb->i.lock.namelen = kb32->i.lock.namelen;
|
||||
@@ -111,8 +115,6 @@ static void compat_input(struct dlm_write_request *kb,
|
||||
static void compat_output(struct dlm_lock_result *res,
|
||||
struct dlm_lock_result32 *res32)
|
||||
{
|
||||
res32->length = res->length - (sizeof(struct dlm_lock_result) -
|
||||
sizeof(struct dlm_lock_result32));
|
||||
res32->user_astaddr = (__u32)(long)res->user_astaddr;
|
||||
res32->user_astparam = (__u32)(long)res->user_astparam;
|
||||
res32->user_lksb = (__u32)(long)res->user_lksb;
|
||||
@@ -128,35 +130,30 @@ static void compat_output(struct dlm_lock_result *res,
|
||||
}
|
||||
#endif
|
||||
|
||||
/* we could possibly check if the cancel of an orphan has resulted in the lkb
|
||||
being removed and then remove that lkb from the orphans list and free it */
|
||||
|
||||
void dlm_user_add_ast(struct dlm_lkb *lkb, int type)
|
||||
{
|
||||
struct dlm_ls *ls;
|
||||
struct dlm_user_args *ua;
|
||||
struct dlm_user_proc *proc;
|
||||
int remove_ownqueue = 0;
|
||||
int eol = 0, ast_type;
|
||||
|
||||
/* dlm_clear_proc_locks() sets ORPHAN/DEAD flag on each
|
||||
lkb before dealing with it. We need to check this
|
||||
flag before taking ls_clear_proc_locks mutex because if
|
||||
it's set, dlm_clear_proc_locks() holds the mutex. */
|
||||
|
||||
if (lkb->lkb_flags & (DLM_IFL_ORPHAN | DLM_IFL_DEAD)) {
|
||||
/* log_print("user_add_ast skip1 %x", lkb->lkb_flags); */
|
||||
if (lkb->lkb_flags & (DLM_IFL_ORPHAN | DLM_IFL_DEAD))
|
||||
return;
|
||||
}
|
||||
|
||||
ls = lkb->lkb_resource->res_ls;
|
||||
mutex_lock(&ls->ls_clear_proc_locks);
|
||||
|
||||
/* If ORPHAN/DEAD flag is set, it means the process is dead so an ast
|
||||
can't be delivered. For ORPHAN's, dlm_clear_proc_locks() freed
|
||||
lkb->ua so we can't try to use it. */
|
||||
lkb->ua so we can't try to use it. This second check is necessary
|
||||
for cases where a completion ast is received for an operation that
|
||||
began before clear_proc_locks did its cancel/unlock. */
|
||||
|
||||
if (lkb->lkb_flags & (DLM_IFL_ORPHAN | DLM_IFL_DEAD)) {
|
||||
/* log_print("user_add_ast skip2 %x", lkb->lkb_flags); */
|
||||
if (lkb->lkb_flags & (DLM_IFL_ORPHAN | DLM_IFL_DEAD))
|
||||
goto out;
|
||||
}
|
||||
|
||||
DLM_ASSERT(lkb->lkb_astparam, dlm_print_lkb(lkb););
|
||||
ua = (struct dlm_user_args *)lkb->lkb_astparam;
|
||||
@@ -166,28 +163,42 @@ void dlm_user_add_ast(struct dlm_lkb *lkb, int type)
|
||||
goto out;
|
||||
|
||||
spin_lock(&proc->asts_spin);
|
||||
if (!(lkb->lkb_ast_type & (AST_COMP | AST_BAST))) {
|
||||
|
||||
ast_type = lkb->lkb_ast_type;
|
||||
lkb->lkb_ast_type |= type;
|
||||
|
||||
if (!ast_type) {
|
||||
kref_get(&lkb->lkb_ref);
|
||||
list_add_tail(&lkb->lkb_astqueue, &proc->asts);
|
||||
lkb->lkb_ast_type |= type;
|
||||
wake_up_interruptible(&proc->wait);
|
||||
}
|
||||
if (type == AST_COMP && (ast_type & AST_COMP))
|
||||
log_debug(ls, "ast overlap %x status %x %x",
|
||||
lkb->lkb_id, ua->lksb.sb_status, lkb->lkb_flags);
|
||||
|
||||
/* noqueue requests that fail may need to be removed from the
|
||||
proc's locks list, there should be a better way of detecting
|
||||
this situation than checking all these things... */
|
||||
/* Figure out if this lock is at the end of its life and no longer
|
||||
available for the application to use. The lkb still exists until
|
||||
the final ast is read. A lock becomes EOL in three situations:
|
||||
1. a noqueue request fails with EAGAIN
|
||||
2. an unlock completes with EUNLOCK
|
||||
3. a cancel of a waiting request completes with ECANCEL
|
||||
An EOL lock needs to be removed from the process's list of locks.
|
||||
And we can't allow any new operation on an EOL lock. This is
|
||||
not related to the lifetime of the lkb struct which is managed
|
||||
entirely by refcount. */
|
||||
|
||||
if (type == AST_COMP && lkb->lkb_grmode == DLM_LOCK_IV &&
|
||||
ua->lksb.sb_status == -EAGAIN && !list_empty(&lkb->lkb_ownqueue))
|
||||
remove_ownqueue = 1;
|
||||
|
||||
/* unlocks or cancels of waiting requests need to be removed from the
|
||||
proc's unlocking list, again there must be a better way... */
|
||||
|
||||
if (ua->lksb.sb_status == -DLM_EUNLOCK ||
|
||||
if (type == AST_COMP &&
|
||||
lkb->lkb_grmode == DLM_LOCK_IV &&
|
||||
ua->lksb.sb_status == -EAGAIN)
|
||||
eol = 1;
|
||||
else if (ua->lksb.sb_status == -DLM_EUNLOCK ||
|
||||
(ua->lksb.sb_status == -DLM_ECANCEL &&
|
||||
lkb->lkb_grmode == DLM_LOCK_IV))
|
||||
remove_ownqueue = 1;
|
||||
eol = 1;
|
||||
if (eol) {
|
||||
lkb->lkb_ast_type &= ~AST_BAST;
|
||||
lkb->lkb_flags |= DLM_IFL_ENDOFLIFE;
|
||||
}
|
||||
|
||||
/* We want to copy the lvb to userspace when the completion
|
||||
ast is read if the status is 0, the lock has an lvb and
|
||||
@@ -204,11 +215,13 @@ void dlm_user_add_ast(struct dlm_lkb *lkb, int type)
|
||||
|
||||
spin_unlock(&proc->asts_spin);
|
||||
|
||||
if (remove_ownqueue) {
|
||||
if (eol) {
|
||||
spin_lock(&ua->proc->locks_spin);
|
||||
list_del_init(&lkb->lkb_ownqueue);
|
||||
if (!list_empty(&lkb->lkb_ownqueue)) {
|
||||
list_del_init(&lkb->lkb_ownqueue);
|
||||
dlm_put_lkb(lkb);
|
||||
}
|
||||
spin_unlock(&ua->proc->locks_spin);
|
||||
dlm_put_lkb(lkb);
|
||||
}
|
||||
out:
|
||||
mutex_unlock(&ls->ls_clear_proc_locks);
|
||||
@@ -286,11 +299,50 @@ static int device_user_unlock(struct dlm_user_proc *proc,
|
||||
return error;
|
||||
}
|
||||
|
||||
static int create_misc_device(struct dlm_ls *ls, char *name)
|
||||
{
|
||||
int error, len;
|
||||
|
||||
error = -ENOMEM;
|
||||
len = strlen(name) + strlen(name_prefix) + 2;
|
||||
ls->ls_device.name = kzalloc(len, GFP_KERNEL);
|
||||
if (!ls->ls_device.name)
|
||||
goto fail;
|
||||
|
||||
snprintf((char *)ls->ls_device.name, len, "%s_%s", name_prefix,
|
||||
name);
|
||||
ls->ls_device.fops = &device_fops;
|
||||
ls->ls_device.minor = MISC_DYNAMIC_MINOR;
|
||||
|
||||
error = misc_register(&ls->ls_device);
|
||||
if (error) {
|
||||
kfree(ls->ls_device.name);
|
||||
}
|
||||
fail:
|
||||
return error;
|
||||
}
|
||||
|
||||
static int device_user_purge(struct dlm_user_proc *proc,
|
||||
struct dlm_purge_params *params)
|
||||
{
|
||||
struct dlm_ls *ls;
|
||||
int error;
|
||||
|
||||
ls = dlm_find_lockspace_local(proc->lockspace);
|
||||
if (!ls)
|
||||
return -ENOENT;
|
||||
|
||||
error = dlm_user_purge(ls, proc, params->nodeid, params->pid);
|
||||
|
||||
dlm_put_lockspace(ls);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int device_create_lockspace(struct dlm_lspace_params *params)
|
||||
{
|
||||
dlm_lockspace_t *lockspace;
|
||||
struct dlm_ls *ls;
|
||||
int error, len;
|
||||
int error;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
return -EPERM;
|
||||
@@ -304,29 +356,14 @@ static int device_create_lockspace(struct dlm_lspace_params *params)
|
||||
if (!ls)
|
||||
return -ENOENT;
|
||||
|
||||
error = -ENOMEM;
|
||||
len = strlen(params->name) + strlen(name_prefix) + 2;
|
||||
ls->ls_device.name = kzalloc(len, GFP_KERNEL);
|
||||
if (!ls->ls_device.name)
|
||||
goto fail;
|
||||
snprintf((char *)ls->ls_device.name, len, "%s_%s", name_prefix,
|
||||
params->name);
|
||||
ls->ls_device.fops = &device_fops;
|
||||
ls->ls_device.minor = MISC_DYNAMIC_MINOR;
|
||||
|
||||
error = misc_register(&ls->ls_device);
|
||||
if (error) {
|
||||
kfree(ls->ls_device.name);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
error = ls->ls_device.minor;
|
||||
error = create_misc_device(ls, params->name);
|
||||
dlm_put_lockspace(ls);
|
||||
return error;
|
||||
|
||||
fail:
|
||||
dlm_put_lockspace(ls);
|
||||
dlm_release_lockspace(lockspace, 0);
|
||||
if (error)
|
||||
dlm_release_lockspace(lockspace, 0);
|
||||
else
|
||||
error = ls->ls_device.minor;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -343,6 +380,10 @@ static int device_remove_lockspace(struct dlm_lspace_params *params)
|
||||
if (!ls)
|
||||
return -ENOENT;
|
||||
|
||||
/* Deregister the misc device first, so we don't have
|
||||
* a device that's not attached to a lockspace. If
|
||||
* dlm_release_lockspace fails then we can recreate it
|
||||
*/
|
||||
error = misc_deregister(&ls->ls_device);
|
||||
if (error) {
|
||||
dlm_put_lockspace(ls);
|
||||
@@ -361,6 +402,8 @@ static int device_remove_lockspace(struct dlm_lspace_params *params)
|
||||
|
||||
dlm_put_lockspace(ls);
|
||||
error = dlm_release_lockspace(lockspace, force);
|
||||
if (error)
|
||||
create_misc_device(ls, ls->ls_name);
|
||||
out:
|
||||
return error;
|
||||
}
|
||||
@@ -497,6 +540,14 @@ static ssize_t device_write(struct file *file, const char __user *buf,
|
||||
error = device_remove_lockspace(&kbuf->i.lspace);
|
||||
break;
|
||||
|
||||
case DLM_USER_PURGE:
|
||||
if (!proc) {
|
||||
log_print("no locking on control device");
|
||||
goto out_sig;
|
||||
}
|
||||
error = device_user_purge(proc, &kbuf->i.purge);
|
||||
break;
|
||||
|
||||
default:
|
||||
log_print("Unknown command passed to DLM device : %d\n",
|
||||
kbuf->cmd);
|
||||
|
||||
Reference in New Issue
Block a user