Commit 0016eedc authored by Joel Becker's avatar Joel Becker

ocfs2_dlmfs: Use the stackglue.

Rather than directly using o2dlm, dlmfs can now use the stackglue.  This
allows it to use userspace cluster stacks and fs/dlm.  This commit
forces o2cb for now.  A latter commit will bump the protocol version and
allow non-o2cb stacks.

This is one big sed, really.  LKM_xxMODE becomes DLM_LOCK_xx.  LKM_flag
becomes DLM_LKF_flag.

We also learn to check that the LVB is valid before reading it.  Any DLM
can lose the contents of the LVB during a complicated recovery.  userdlm
should be checking this.  Now it does.  dlmfs will return 0 from read(2)
if the LVB was invalid.
Signed-off-by: default avatarJoel Becker <joel.becker@oracle.com>
parent e8fce482
...@@ -47,21 +47,13 @@ ...@@ -47,21 +47,13 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include "stackglue.h"
#include "cluster/nodemanager.h"
#include "cluster/heartbeat.h"
#include "cluster/tcp.h"
#include "dlm/dlmapi.h"
#include "userdlm.h" #include "userdlm.h"
#include "dlmfsver.h" #include "dlmfsver.h"
#define MLOG_MASK_PREFIX ML_DLMFS #define MLOG_MASK_PREFIX ML_DLMFS
#include "cluster/masklog.h" #include "cluster/masklog.h"
#include "ocfs2_lockingver.h"
static const struct super_operations dlmfs_ops; static const struct super_operations dlmfs_ops;
static const struct file_operations dlmfs_file_operations; static const struct file_operations dlmfs_file_operations;
...@@ -72,15 +64,6 @@ static struct kmem_cache *dlmfs_inode_cache; ...@@ -72,15 +64,6 @@ static struct kmem_cache *dlmfs_inode_cache;
struct workqueue_struct *user_dlm_worker; struct workqueue_struct *user_dlm_worker;
/*
* This is the userdlmfs locking protocol version.
*
* See fs/ocfs2/dlmglue.c for more details on locking versions.
*/
static const struct dlm_protocol_version user_locking_protocol = {
.pv_major = OCFS2_LOCKING_PROTOCOL_MAJOR,
.pv_minor = OCFS2_LOCKING_PROTOCOL_MINOR,
};
/* /*
...@@ -259,7 +242,7 @@ static ssize_t dlmfs_file_read(struct file *filp, ...@@ -259,7 +242,7 @@ static ssize_t dlmfs_file_read(struct file *filp,
loff_t *ppos) loff_t *ppos)
{ {
int bytes_left; int bytes_left;
ssize_t readlen; ssize_t readlen, got;
char *lvb_buf; char *lvb_buf;
struct inode *inode = filp->f_path.dentry->d_inode; struct inode *inode = filp->f_path.dentry->d_inode;
...@@ -285,9 +268,13 @@ static ssize_t dlmfs_file_read(struct file *filp, ...@@ -285,9 +268,13 @@ static ssize_t dlmfs_file_read(struct file *filp,
if (!lvb_buf) if (!lvb_buf)
return -ENOMEM; return -ENOMEM;
user_dlm_read_lvb(inode, lvb_buf, readlen); got = user_dlm_read_lvb(inode, lvb_buf, readlen);
bytes_left = __copy_to_user(buf, lvb_buf, readlen); if (got) {
readlen -= bytes_left; BUG_ON(got != readlen);
bytes_left = __copy_to_user(buf, lvb_buf, readlen);
readlen -= bytes_left;
} else
readlen = 0;
kfree(lvb_buf); kfree(lvb_buf);
...@@ -346,7 +333,7 @@ static void dlmfs_init_once(void *foo) ...@@ -346,7 +333,7 @@ static void dlmfs_init_once(void *foo)
struct dlmfs_inode_private *ip = struct dlmfs_inode_private *ip =
(struct dlmfs_inode_private *) foo; (struct dlmfs_inode_private *) foo;
ip->ip_dlm = NULL; ip->ip_conn = NULL;
ip->ip_parent = NULL; ip->ip_parent = NULL;
inode_init_once(&ip->ip_vfs_inode); inode_init_once(&ip->ip_vfs_inode);
...@@ -388,14 +375,14 @@ static void dlmfs_clear_inode(struct inode *inode) ...@@ -388,14 +375,14 @@ static void dlmfs_clear_inode(struct inode *inode)
goto clear_fields; goto clear_fields;
} }
mlog(0, "we're a directory, ip->ip_dlm = 0x%p\n", ip->ip_dlm); mlog(0, "we're a directory, ip->ip_conn = 0x%p\n", ip->ip_conn);
/* we must be a directory. If required, lets unregister the /* we must be a directory. If required, lets unregister the
* dlm context now. */ * dlm context now. */
if (ip->ip_dlm) if (ip->ip_conn)
user_dlm_unregister_context(ip->ip_dlm); user_dlm_unregister(ip->ip_conn);
clear_fields: clear_fields:
ip->ip_parent = NULL; ip->ip_parent = NULL;
ip->ip_dlm = NULL; ip->ip_conn = NULL;
} }
static struct backing_dev_info dlmfs_backing_dev_info = { static struct backing_dev_info dlmfs_backing_dev_info = {
...@@ -445,7 +432,7 @@ static struct inode *dlmfs_get_inode(struct inode *parent, ...@@ -445,7 +432,7 @@ static struct inode *dlmfs_get_inode(struct inode *parent,
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
ip = DLMFS_I(inode); ip = DLMFS_I(inode);
ip->ip_dlm = DLMFS_I(parent)->ip_dlm; ip->ip_conn = DLMFS_I(parent)->ip_conn;
switch (mode & S_IFMT) { switch (mode & S_IFMT) {
default: default:
...@@ -499,13 +486,12 @@ static int dlmfs_mkdir(struct inode * dir, ...@@ -499,13 +486,12 @@ static int dlmfs_mkdir(struct inode * dir,
struct inode *inode = NULL; struct inode *inode = NULL;
struct qstr *domain = &dentry->d_name; struct qstr *domain = &dentry->d_name;
struct dlmfs_inode_private *ip; struct dlmfs_inode_private *ip;
struct dlm_ctxt *dlm; struct ocfs2_cluster_connection *conn;
struct dlm_protocol_version proto = user_locking_protocol;
mlog(0, "mkdir %.*s\n", domain->len, domain->name); mlog(0, "mkdir %.*s\n", domain->len, domain->name);
/* verify that we have a proper domain */ /* verify that we have a proper domain */
if (domain->len >= O2NM_MAX_NAME_LEN) { if (domain->len >= GROUP_NAME_MAX) {
status = -EINVAL; status = -EINVAL;
mlog(ML_ERROR, "invalid domain name for directory.\n"); mlog(ML_ERROR, "invalid domain name for directory.\n");
goto bail; goto bail;
...@@ -520,14 +506,14 @@ static int dlmfs_mkdir(struct inode * dir, ...@@ -520,14 +506,14 @@ static int dlmfs_mkdir(struct inode * dir,
ip = DLMFS_I(inode); ip = DLMFS_I(inode);
dlm = user_dlm_register_context(domain, &proto); conn = user_dlm_register(domain);
if (IS_ERR(dlm)) { if (IS_ERR(conn)) {
status = PTR_ERR(dlm); status = PTR_ERR(conn);
mlog(ML_ERROR, "Error %d could not register domain \"%.*s\"\n", mlog(ML_ERROR, "Error %d could not register domain \"%.*s\"\n",
status, domain->len, domain->name); status, domain->len, domain->name);
goto bail; goto bail;
} }
ip->ip_dlm = dlm; ip->ip_conn = conn;
inc_nlink(dir); inc_nlink(dir);
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
...@@ -696,6 +682,7 @@ static int __init init_dlmfs_fs(void) ...@@ -696,6 +682,7 @@ static int __init init_dlmfs_fs(void)
} }
cleanup_worker = 1; cleanup_worker = 1;
user_dlm_set_locking_protocol();
status = register_filesystem(&dlmfs_fs_type); status = register_filesystem(&dlmfs_fs_type);
bail: bail:
if (status) { if (status) {
......
This diff is collapsed.
...@@ -57,7 +57,7 @@ struct user_lock_res { ...@@ -57,7 +57,7 @@ struct user_lock_res {
int l_level; int l_level;
unsigned int l_ro_holders; unsigned int l_ro_holders;
unsigned int l_ex_holders; unsigned int l_ex_holders;
struct dlm_lockstatus l_lksb; struct ocfs2_dlm_lksb l_lksb;
int l_requested; int l_requested;
int l_blocking; int l_blocking;
...@@ -80,15 +80,15 @@ void user_dlm_cluster_unlock(struct user_lock_res *lockres, ...@@ -80,15 +80,15 @@ void user_dlm_cluster_unlock(struct user_lock_res *lockres,
void user_dlm_write_lvb(struct inode *inode, void user_dlm_write_lvb(struct inode *inode,
const char *val, const char *val,
unsigned int len); unsigned int len);
void user_dlm_read_lvb(struct inode *inode, ssize_t user_dlm_read_lvb(struct inode *inode,
char *val, char *val,
unsigned int len); unsigned int len);
struct dlm_ctxt *user_dlm_register_context(struct qstr *name, struct ocfs2_cluster_connection *user_dlm_register(struct qstr *name);
struct dlm_protocol_version *proto); void user_dlm_unregister(struct ocfs2_cluster_connection *conn);
void user_dlm_unregister_context(struct dlm_ctxt *dlm); void user_dlm_set_locking_protocol(void);
struct dlmfs_inode_private { struct dlmfs_inode_private {
struct dlm_ctxt *ip_dlm; struct ocfs2_cluster_connection *ip_conn;
struct user_lock_res ip_lockres; /* unused for directories. */ struct user_lock_res ip_lockres; /* unused for directories. */
struct inode *ip_parent; struct inode *ip_parent;
......
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