Commit bcbb4ba6 authored by Alexander Aring's avatar Alexander Aring Committed by David Teigland

dlm: cleanup plock_op vs plock_xop

Lately the different casting between plock_op and plock_xop and list
holders which was involved showed some issues which were hard to see.
This patch removes the "plock_xop" structure and introduces a
"struct plock_async_data". This structure will be set in "struct plock_op"
in case of asynchronous lock handling as the original "plock_xop" was
made for. There is no need anymore to cast pointers around for
additional fields in case of asynchronous lock handling.  As disadvantage
another allocation was introduces but only needed in the asynchronous
case which is currently only used in combination with nfs lockd.
Signed-off-by: default avatarAlexander Aring <aahringo@redhat.com>
Signed-off-by: default avatarDavid Teigland <teigland@redhat.com>
parent a559790c
...@@ -19,20 +19,20 @@ static struct list_head recv_list; ...@@ -19,20 +19,20 @@ static struct list_head recv_list;
static wait_queue_head_t send_wq; static wait_queue_head_t send_wq;
static wait_queue_head_t recv_wq; static wait_queue_head_t recv_wq;
struct plock_op { struct plock_async_data {
struct list_head list;
int done;
struct dlm_plock_info info;
int (*callback)(struct file_lock *fl, int result);
};
struct plock_xop {
struct plock_op xop;
void *fl; void *fl;
void *file; void *file;
struct file_lock flc; struct file_lock flc;
int (*callback)(struct file_lock *fl, int result);
}; };
struct plock_op {
struct list_head list;
int done;
struct dlm_plock_info info;
/* if set indicates async handling */
struct plock_async_data *data;
};
static inline void set_version(struct dlm_plock_info *info) static inline void set_version(struct dlm_plock_info *info)
{ {
...@@ -58,6 +58,12 @@ static int check_version(struct dlm_plock_info *info) ...@@ -58,6 +58,12 @@ static int check_version(struct dlm_plock_info *info)
return 0; return 0;
} }
static void dlm_release_plock_op(struct plock_op *op)
{
kfree(op->data);
kfree(op);
}
static void send_op(struct plock_op *op) static void send_op(struct plock_op *op)
{ {
set_version(&op->info); set_version(&op->info);
...@@ -101,22 +107,21 @@ static void do_unlock_close(struct dlm_ls *ls, u64 number, ...@@ -101,22 +107,21 @@ static void do_unlock_close(struct dlm_ls *ls, u64 number,
int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file, int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
int cmd, struct file_lock *fl) int cmd, struct file_lock *fl)
{ {
struct plock_async_data *op_data;
struct dlm_ls *ls; struct dlm_ls *ls;
struct plock_op *op; struct plock_op *op;
struct plock_xop *xop;
int rv; int rv;
ls = dlm_find_lockspace_local(lockspace); ls = dlm_find_lockspace_local(lockspace);
if (!ls) if (!ls)
return -EINVAL; return -EINVAL;
xop = kzalloc(sizeof(*xop), GFP_NOFS); op = kzalloc(sizeof(*op), GFP_NOFS);
if (!xop) { if (!op) {
rv = -ENOMEM; rv = -ENOMEM;
goto out; goto out;
} }
op = &xop->xop;
op->info.optype = DLM_PLOCK_OP_LOCK; op->info.optype = DLM_PLOCK_OP_LOCK;
op->info.pid = fl->fl_pid; op->info.pid = fl->fl_pid;
op->info.ex = (fl->fl_type == F_WRLCK); op->info.ex = (fl->fl_type == F_WRLCK);
...@@ -125,22 +130,32 @@ int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file, ...@@ -125,22 +130,32 @@ int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
op->info.number = number; op->info.number = number;
op->info.start = fl->fl_start; op->info.start = fl->fl_start;
op->info.end = fl->fl_end; op->info.end = fl->fl_end;
/* async handling */
if (fl->fl_lmops && fl->fl_lmops->lm_grant) { if (fl->fl_lmops && fl->fl_lmops->lm_grant) {
op_data = kzalloc(sizeof(*op_data), GFP_NOFS);
if (!op_data) {
dlm_release_plock_op(op);
rv = -ENOMEM;
goto out;
}
/* fl_owner is lockd which doesn't distinguish /* fl_owner is lockd which doesn't distinguish
processes on the nfs client */ processes on the nfs client */
op->info.owner = (__u64) fl->fl_pid; op->info.owner = (__u64) fl->fl_pid;
op->callback = fl->fl_lmops->lm_grant; op_data->callback = fl->fl_lmops->lm_grant;
locks_init_lock(&xop->flc); locks_init_lock(&op_data->flc);
locks_copy_lock(&xop->flc, fl); locks_copy_lock(&op_data->flc, fl);
xop->fl = fl; op_data->fl = fl;
xop->file = file; op_data->file = file;
op->data = op_data;
} else { } else {
op->info.owner = (__u64)(long) fl->fl_owner; op->info.owner = (__u64)(long) fl->fl_owner;
} }
send_op(op); send_op(op);
if (!op->callback) { if (!op->data) {
rv = wait_event_interruptible(recv_wq, (op->done != 0)); rv = wait_event_interruptible(recv_wq, (op->done != 0));
if (rv == -ERESTARTSYS) { if (rv == -ERESTARTSYS) {
log_debug(ls, "dlm_posix_lock: wait killed %llx", log_debug(ls, "dlm_posix_lock: wait killed %llx",
...@@ -148,7 +163,7 @@ int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file, ...@@ -148,7 +163,7 @@ int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
spin_lock(&ops_lock); spin_lock(&ops_lock);
list_del(&op->list); list_del(&op->list);
spin_unlock(&ops_lock); spin_unlock(&ops_lock);
kfree(xop); dlm_release_plock_op(op);
do_unlock_close(ls, number, file, fl); do_unlock_close(ls, number, file, fl);
goto out; goto out;
} }
...@@ -167,7 +182,7 @@ int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file, ...@@ -167,7 +182,7 @@ int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
(unsigned long long)number); (unsigned long long)number);
} }
kfree(xop); dlm_release_plock_op(op);
out: out:
dlm_put_lockspace(ls); dlm_put_lockspace(ls);
return rv; return rv;
...@@ -177,20 +192,20 @@ EXPORT_SYMBOL_GPL(dlm_posix_lock); ...@@ -177,20 +192,20 @@ EXPORT_SYMBOL_GPL(dlm_posix_lock);
/* Returns failure iff a successful lock operation should be canceled */ /* Returns failure iff a successful lock operation should be canceled */
static int dlm_plock_callback(struct plock_op *op) static int dlm_plock_callback(struct plock_op *op)
{ {
struct plock_async_data *op_data = op->data;
struct file *file; struct file *file;
struct file_lock *fl; struct file_lock *fl;
struct file_lock *flc; struct file_lock *flc;
int (*notify)(struct file_lock *fl, int result) = NULL; int (*notify)(struct file_lock *fl, int result) = NULL;
struct plock_xop *xop = (struct plock_xop *)op;
int rv = 0; int rv = 0;
WARN_ON(!list_empty(&op->list)); WARN_ON(!list_empty(&op->list));
/* check if the following 2 are still valid or make a copy */ /* check if the following 2 are still valid or make a copy */
file = xop->file; file = op_data->file;
flc = &xop->flc; flc = &op_data->flc;
fl = xop->fl; fl = op_data->fl;
notify = op->callback; notify = op_data->callback;
if (op->info.rv) { if (op->info.rv) {
notify(fl, op->info.rv); notify(fl, op->info.rv);
...@@ -221,7 +236,7 @@ static int dlm_plock_callback(struct plock_op *op) ...@@ -221,7 +236,7 @@ static int dlm_plock_callback(struct plock_op *op)
} }
out: out:
kfree(xop); dlm_release_plock_op(op);
return rv; return rv;
} }
...@@ -285,7 +300,7 @@ int dlm_posix_unlock(dlm_lockspace_t *lockspace, u64 number, struct file *file, ...@@ -285,7 +300,7 @@ int dlm_posix_unlock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
rv = 0; rv = 0;
out_free: out_free:
kfree(op); dlm_release_plock_op(op);
out: out:
dlm_put_lockspace(ls); dlm_put_lockspace(ls);
fl->fl_flags = fl_flags; fl->fl_flags = fl_flags;
...@@ -345,7 +360,7 @@ int dlm_posix_get(dlm_lockspace_t *lockspace, u64 number, struct file *file, ...@@ -345,7 +360,7 @@ int dlm_posix_get(dlm_lockspace_t *lockspace, u64 number, struct file *file,
rv = 0; rv = 0;
} }
kfree(op); dlm_release_plock_op(op);
out: out:
dlm_put_lockspace(ls); dlm_put_lockspace(ls);
return rv; return rv;
...@@ -381,7 +396,7 @@ static ssize_t dev_read(struct file *file, char __user *u, size_t count, ...@@ -381,7 +396,7 @@ static ssize_t dev_read(struct file *file, char __user *u, size_t count,
(the process did not make an unlock call). */ (the process did not make an unlock call). */
if (op->info.flags & DLM_PLOCK_FL_CLOSE) if (op->info.flags & DLM_PLOCK_FL_CLOSE)
kfree(op); dlm_release_plock_op(op);
if (copy_to_user(u, &info, sizeof(info))) if (copy_to_user(u, &info, sizeof(info)))
return -EFAULT; return -EFAULT;
...@@ -413,7 +428,7 @@ static ssize_t dev_write(struct file *file, const char __user *u, size_t count, ...@@ -413,7 +428,7 @@ static ssize_t dev_write(struct file *file, const char __user *u, size_t count,
op->info.owner == info.owner) { op->info.owner == info.owner) {
list_del_init(&op->list); list_del_init(&op->list);
memcpy(&op->info, &info, sizeof(info)); memcpy(&op->info, &info, sizeof(info));
if (op->callback) if (op->data)
do_callback = 1; do_callback = 1;
else else
op->done = 1; op->done = 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment