Commit 5b664cb2 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2

* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2:
  [PATCH] ocfs2: fix oops in mmap_truncate testing
  configfs: call drop_link() to cleanup after create_link() failure
  configfs: Allow ->make_item() and ->make_group() to return detailed errors.
  configfs: Fix failing mkdir() making racing rmdir() fail
  configfs: Fix deadlock with racing rmdir() and rename()
  configfs: Make configfs_new_dirent() return error code instead of NULL
  configfs: Protect configfs_dirent s_links list mutations
  configfs: Introduce configfs_dirent_lock
  ocfs2: Don't snprintf() without a format.
  ocfs2: Fix CONFIG_OCFS2_DEBUG_FS #ifdefs
  ocfs2/net: Silence build warnings on sparc64
  ocfs2: Handle error during journal load
  ocfs2: Silence an error message in ocfs2_file_aio_read()
  ocfs2: use simple_read_from_buffer()
  ocfs2: fix printk format warnings with OCFS2_FS_STATS=n
  [PATCH 2/2] ocfs2: Instrument fs cluster locks
  [PATCH 1/2] ocfs2: Add CONFIG_OCFS2_FS_STATS config option
parents f39548a6 c0420ad2
...@@ -233,10 +233,12 @@ accomplished via the group operations specified on the group's ...@@ -233,10 +233,12 @@ accomplished via the group operations specified on the group's
config_item_type. config_item_type.
struct configfs_group_operations { struct configfs_group_operations {
struct config_item *(*make_item)(struct config_group *group, int (*make_item)(struct config_group *group,
const char *name); const char *name,
struct config_group *(*make_group)(struct config_group *group, struct config_item **new_item);
const char *name); int (*make_group)(struct config_group *group,
const char *name,
struct config_group **new_group);
int (*commit_item)(struct config_item *item); int (*commit_item)(struct config_item *item);
void (*disconnect_notify)(struct config_group *group, void (*disconnect_notify)(struct config_group *group,
struct config_item *item); struct config_item *item);
......
...@@ -273,13 +273,13 @@ static inline struct simple_children *to_simple_children(struct config_item *ite ...@@ -273,13 +273,13 @@ static inline struct simple_children *to_simple_children(struct config_item *ite
return item ? container_of(to_config_group(item), struct simple_children, group) : NULL; return item ? container_of(to_config_group(item), struct simple_children, group) : NULL;
} }
static struct config_item *simple_children_make_item(struct config_group *group, const char *name) static int simple_children_make_item(struct config_group *group, const char *name, struct config_item **new_item)
{ {
struct simple_child *simple_child; struct simple_child *simple_child;
simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL); simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL);
if (!simple_child) if (!simple_child)
return NULL; return -ENOMEM;
config_item_init_type_name(&simple_child->item, name, config_item_init_type_name(&simple_child->item, name,
...@@ -287,7 +287,8 @@ static struct config_item *simple_children_make_item(struct config_group *group, ...@@ -287,7 +287,8 @@ static struct config_item *simple_children_make_item(struct config_group *group,
simple_child->storeme = 0; simple_child->storeme = 0;
return &simple_child->item; *new_item = &simple_child->item;
return 0;
} }
static struct configfs_attribute simple_children_attr_description = { static struct configfs_attribute simple_children_attr_description = {
...@@ -359,20 +360,21 @@ static struct configfs_subsystem simple_children_subsys = { ...@@ -359,20 +360,21 @@ static struct configfs_subsystem simple_children_subsys = {
* children of its own. * children of its own.
*/ */
static struct config_group *group_children_make_group(struct config_group *group, const char *name) static int group_children_make_group(struct config_group *group, const char *name, struct config_group **new_group)
{ {
struct simple_children *simple_children; struct simple_children *simple_children;
simple_children = kzalloc(sizeof(struct simple_children), simple_children = kzalloc(sizeof(struct simple_children),
GFP_KERNEL); GFP_KERNEL);
if (!simple_children) if (!simple_children)
return NULL; return -ENOMEM;
config_group_init_type_name(&simple_children->group, name, config_group_init_type_name(&simple_children->group, name,
&simple_children_type); &simple_children_type);
return &simple_children->group; *new_group = &simple_children->group;
return 0;
} }
static struct configfs_attribute group_children_attr_description = { static struct configfs_attribute group_children_attr_description = {
......
...@@ -585,8 +585,9 @@ static struct config_item_type netconsole_target_type = { ...@@ -585,8 +585,9 @@ static struct config_item_type netconsole_target_type = {
* Group operations and type for netconsole_subsys. * Group operations and type for netconsole_subsys.
*/ */
static struct config_item *make_netconsole_target(struct config_group *group, static int make_netconsole_target(struct config_group *group,
const char *name) const char *name,
struct config_item **new_item)
{ {
unsigned long flags; unsigned long flags;
struct netconsole_target *nt; struct netconsole_target *nt;
...@@ -598,7 +599,7 @@ static struct config_item *make_netconsole_target(struct config_group *group, ...@@ -598,7 +599,7 @@ static struct config_item *make_netconsole_target(struct config_group *group,
nt = kzalloc(sizeof(*nt), GFP_KERNEL); nt = kzalloc(sizeof(*nt), GFP_KERNEL);
if (!nt) { if (!nt) {
printk(KERN_ERR "netconsole: failed to allocate memory\n"); printk(KERN_ERR "netconsole: failed to allocate memory\n");
return NULL; return -ENOMEM;
} }
nt->np.name = "netconsole"; nt->np.name = "netconsole";
...@@ -615,7 +616,8 @@ static struct config_item *make_netconsole_target(struct config_group *group, ...@@ -615,7 +616,8 @@ static struct config_item *make_netconsole_target(struct config_group *group,
list_add(&nt->list, &target_list); list_add(&nt->list, &target_list);
spin_unlock_irqrestore(&target_list_lock, flags); spin_unlock_irqrestore(&target_list_lock, flags);
return &nt->item; *new_item = &nt->item;
return 0;
} }
static void drop_netconsole_target(struct config_group *group, static void drop_netconsole_target(struct config_group *group,
......
...@@ -470,6 +470,14 @@ config OCFS2_FS_USERSPACE_CLUSTER ...@@ -470,6 +470,14 @@ config OCFS2_FS_USERSPACE_CLUSTER
It is safe to say Y, as the clustering method is run-time It is safe to say Y, as the clustering method is run-time
selectable. selectable.
config OCFS2_FS_STATS
bool "OCFS2 statistics"
depends on OCFS2_FS
default y
help
This option allows some fs statistics to be captured. Enabling
this option may increase the memory consumption.
config OCFS2_DEBUG_MASKLOG config OCFS2_DEBUG_MASKLOG
bool "OCFS2 logging support" bool "OCFS2 logging support"
depends on OCFS2_FS depends on OCFS2_FS
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/spinlock.h>
struct configfs_dirent { struct configfs_dirent {
atomic_t s_count; atomic_t s_count;
...@@ -47,8 +48,11 @@ struct configfs_dirent { ...@@ -47,8 +48,11 @@ struct configfs_dirent {
#define CONFIGFS_USET_DIR 0x0040 #define CONFIGFS_USET_DIR 0x0040
#define CONFIGFS_USET_DEFAULT 0x0080 #define CONFIGFS_USET_DEFAULT 0x0080
#define CONFIGFS_USET_DROPPING 0x0100 #define CONFIGFS_USET_DROPPING 0x0100
#define CONFIGFS_USET_IN_MKDIR 0x0200
#define CONFIGFS_NOT_PINNED (CONFIGFS_ITEM_ATTR) #define CONFIGFS_NOT_PINNED (CONFIGFS_ITEM_ATTR)
extern spinlock_t configfs_dirent_lock;
extern struct vfsmount * configfs_mount; extern struct vfsmount * configfs_mount;
extern struct kmem_cache *configfs_dir_cachep; extern struct kmem_cache *configfs_dir_cachep;
......
This diff is collapsed.
...@@ -247,7 +247,9 @@ void configfs_hash_and_remove(struct dentry * dir, const char * name) ...@@ -247,7 +247,9 @@ void configfs_hash_and_remove(struct dentry * dir, const char * name)
if (!sd->s_element) if (!sd->s_element)
continue; continue;
if (!strcmp(configfs_get_name(sd), name)) { if (!strcmp(configfs_get_name(sd), name)) {
spin_lock(&configfs_dirent_lock);
list_del_init(&sd->s_sibling); list_del_init(&sd->s_sibling);
spin_unlock(&configfs_dirent_lock);
configfs_drop_dentry(sd, dir); configfs_drop_dentry(sd, dir);
configfs_put(sd); configfs_put(sd);
break; break;
......
...@@ -77,12 +77,15 @@ static int create_link(struct config_item *parent_item, ...@@ -77,12 +77,15 @@ static int create_link(struct config_item *parent_item,
sl = kmalloc(sizeof(struct configfs_symlink), GFP_KERNEL); sl = kmalloc(sizeof(struct configfs_symlink), GFP_KERNEL);
if (sl) { if (sl) {
sl->sl_target = config_item_get(item); sl->sl_target = config_item_get(item);
/* FIXME: needs a lock, I'd bet */ spin_lock(&configfs_dirent_lock);
list_add(&sl->sl_list, &target_sd->s_links); list_add(&sl->sl_list, &target_sd->s_links);
spin_unlock(&configfs_dirent_lock);
ret = configfs_create_link(sl, parent_item->ci_dentry, ret = configfs_create_link(sl, parent_item->ci_dentry,
dentry); dentry);
if (ret) { if (ret) {
spin_lock(&configfs_dirent_lock);
list_del_init(&sl->sl_list); list_del_init(&sl->sl_list);
spin_unlock(&configfs_dirent_lock);
config_item_put(item); config_item_put(item);
kfree(sl); kfree(sl);
} }
...@@ -137,8 +140,12 @@ int configfs_symlink(struct inode *dir, struct dentry *dentry, const char *symna ...@@ -137,8 +140,12 @@ int configfs_symlink(struct inode *dir, struct dentry *dentry, const char *symna
goto out_put; goto out_put;
ret = type->ct_item_ops->allow_link(parent_item, target_item); ret = type->ct_item_ops->allow_link(parent_item, target_item);
if (!ret) if (!ret) {
ret = create_link(parent_item, target_item, dentry); ret = create_link(parent_item, target_item, dentry);
if (ret && type->ct_item_ops->drop_link)
type->ct_item_ops->drop_link(parent_item,
target_item);
}
config_item_put(target_item); config_item_put(target_item);
path_put(&nd.path); path_put(&nd.path);
...@@ -169,7 +176,9 @@ int configfs_unlink(struct inode *dir, struct dentry *dentry) ...@@ -169,7 +176,9 @@ int configfs_unlink(struct inode *dir, struct dentry *dentry)
parent_item = configfs_get_config_item(dentry->d_parent); parent_item = configfs_get_config_item(dentry->d_parent);
type = parent_item->ci_type; type = parent_item->ci_type;
spin_lock(&configfs_dirent_lock);
list_del_init(&sd->s_sibling); list_del_init(&sd->s_sibling);
spin_unlock(&configfs_dirent_lock);
configfs_drop_dentry(sd, dentry->d_parent); configfs_drop_dentry(sd, dentry->d_parent);
dput(dentry); dput(dentry);
configfs_put(sd); configfs_put(sd);
...@@ -184,8 +193,9 @@ int configfs_unlink(struct inode *dir, struct dentry *dentry) ...@@ -184,8 +193,9 @@ int configfs_unlink(struct inode *dir, struct dentry *dentry)
type->ct_item_ops->drop_link(parent_item, type->ct_item_ops->drop_link(parent_item,
sl->sl_target); sl->sl_target);
/* FIXME: Needs lock */ spin_lock(&configfs_dirent_lock);
list_del_init(&sl->sl_list); list_del_init(&sl->sl_list);
spin_unlock(&configfs_dirent_lock);
/* Put reference from create_link() */ /* Put reference from create_link() */
config_item_put(sl->sl_target); config_item_put(sl->sl_target);
......
...@@ -41,16 +41,20 @@ struct comm; ...@@ -41,16 +41,20 @@ struct comm;
struct nodes; struct nodes;
struct node; struct node;
static struct config_group *make_cluster(struct config_group *, const char *); static int make_cluster(struct config_group *, const char *,
struct config_group **);
static void drop_cluster(struct config_group *, struct config_item *); static void drop_cluster(struct config_group *, struct config_item *);
static void release_cluster(struct config_item *); static void release_cluster(struct config_item *);
static struct config_group *make_space(struct config_group *, const char *); static int make_space(struct config_group *, const char *,
struct config_group **);
static void drop_space(struct config_group *, struct config_item *); static void drop_space(struct config_group *, struct config_item *);
static void release_space(struct config_item *); static void release_space(struct config_item *);
static struct config_item *make_comm(struct config_group *, const char *); static int make_comm(struct config_group *, const char *,
struct config_item **);
static void drop_comm(struct config_group *, struct config_item *); static void drop_comm(struct config_group *, struct config_item *);
static void release_comm(struct config_item *); static void release_comm(struct config_item *);
static struct config_item *make_node(struct config_group *, const char *); static int make_node(struct config_group *, const char *,
struct config_item **);
static void drop_node(struct config_group *, struct config_item *); static void drop_node(struct config_group *, struct config_item *);
static void release_node(struct config_item *); static void release_node(struct config_item *);
...@@ -392,8 +396,8 @@ static struct node *to_node(struct config_item *i) ...@@ -392,8 +396,8 @@ static struct node *to_node(struct config_item *i)
return i ? container_of(i, struct node, item) : NULL; return i ? container_of(i, struct node, item) : NULL;
} }
static struct config_group *make_cluster(struct config_group *g, static int make_cluster(struct config_group *g, const char *name,
const char *name) struct config_group **new_g)
{ {
struct cluster *cl = NULL; struct cluster *cl = NULL;
struct spaces *sps = NULL; struct spaces *sps = NULL;
...@@ -431,14 +435,15 @@ static struct config_group *make_cluster(struct config_group *g, ...@@ -431,14 +435,15 @@ static struct config_group *make_cluster(struct config_group *g,
space_list = &sps->ss_group; space_list = &sps->ss_group;
comm_list = &cms->cs_group; comm_list = &cms->cs_group;
return &cl->group; *new_g = &cl->group;
return 0;
fail: fail:
kfree(cl); kfree(cl);
kfree(gps); kfree(gps);
kfree(sps); kfree(sps);
kfree(cms); kfree(cms);
return NULL; return -ENOMEM;
} }
static void drop_cluster(struct config_group *g, struct config_item *i) static void drop_cluster(struct config_group *g, struct config_item *i)
...@@ -466,7 +471,8 @@ static void release_cluster(struct config_item *i) ...@@ -466,7 +471,8 @@ static void release_cluster(struct config_item *i)
kfree(cl); kfree(cl);
} }
static struct config_group *make_space(struct config_group *g, const char *name) static int make_space(struct config_group *g, const char *name,
struct config_group **new_g)
{ {
struct space *sp = NULL; struct space *sp = NULL;
struct nodes *nds = NULL; struct nodes *nds = NULL;
...@@ -489,13 +495,14 @@ static struct config_group *make_space(struct config_group *g, const char *name) ...@@ -489,13 +495,14 @@ static struct config_group *make_space(struct config_group *g, const char *name)
INIT_LIST_HEAD(&sp->members); INIT_LIST_HEAD(&sp->members);
mutex_init(&sp->members_lock); mutex_init(&sp->members_lock);
sp->members_count = 0; sp->members_count = 0;
return &sp->group; *new_g = &sp->group;
return 0;
fail: fail:
kfree(sp); kfree(sp);
kfree(gps); kfree(gps);
kfree(nds); kfree(nds);
return NULL; return -ENOMEM;
} }
static void drop_space(struct config_group *g, struct config_item *i) static void drop_space(struct config_group *g, struct config_item *i)
...@@ -522,19 +529,21 @@ static void release_space(struct config_item *i) ...@@ -522,19 +529,21 @@ static void release_space(struct config_item *i)
kfree(sp); kfree(sp);
} }
static struct config_item *make_comm(struct config_group *g, const char *name) static int make_comm(struct config_group *g, const char *name,
struct config_item **new_i)
{ {
struct comm *cm; struct comm *cm;
cm = kzalloc(sizeof(struct comm), GFP_KERNEL); cm = kzalloc(sizeof(struct comm), GFP_KERNEL);
if (!cm) if (!cm)
return NULL; return -ENOMEM;
config_item_init_type_name(&cm->item, name, &comm_type); config_item_init_type_name(&cm->item, name, &comm_type);
cm->nodeid = -1; cm->nodeid = -1;
cm->local = 0; cm->local = 0;
cm->addr_count = 0; cm->addr_count = 0;
return &cm->item; *new_i = &cm->item;
return 0;
} }
static void drop_comm(struct config_group *g, struct config_item *i) static void drop_comm(struct config_group *g, struct config_item *i)
...@@ -554,14 +563,15 @@ static void release_comm(struct config_item *i) ...@@ -554,14 +563,15 @@ static void release_comm(struct config_item *i)
kfree(cm); kfree(cm);
} }
static struct config_item *make_node(struct config_group *g, const char *name) static int make_node(struct config_group *g, const char *name,
struct config_item **new_i)
{ {
struct space *sp = to_space(g->cg_item.ci_parent); struct space *sp = to_space(g->cg_item.ci_parent);
struct node *nd; struct node *nd;
nd = kzalloc(sizeof(struct node), GFP_KERNEL); nd = kzalloc(sizeof(struct node), GFP_KERNEL);
if (!nd) if (!nd)
return NULL; return -ENOMEM;
config_item_init_type_name(&nd->item, name, &node_type); config_item_init_type_name(&nd->item, name, &node_type);
nd->nodeid = -1; nd->nodeid = -1;
...@@ -573,7 +583,8 @@ static struct config_item *make_node(struct config_group *g, const char *name) ...@@ -573,7 +583,8 @@ static struct config_item *make_node(struct config_group *g, const char *name)
sp->members_count++; sp->members_count++;
mutex_unlock(&sp->members_lock); mutex_unlock(&sp->members_lock);
return &nd->item; *new_i = &nd->item;
return 0;
} }
static void drop_node(struct config_group *g, struct config_item *i) static void drop_node(struct config_group *g, struct config_item *i)
......
...@@ -174,10 +174,17 @@ static int ocfs2_get_block(struct inode *inode, sector_t iblock, ...@@ -174,10 +174,17 @@ static int ocfs2_get_block(struct inode *inode, sector_t iblock,
* need to use BH_New is when we're extending i_size on a file * need to use BH_New is when we're extending i_size on a file
* system which doesn't support holes, in which case BH_New * system which doesn't support holes, in which case BH_New
* allows block_prepare_write() to zero. * allows block_prepare_write() to zero.
*
* If we see this on a sparse file system, then a truncate has
* raced us and removed the cluster. In this case, we clear
* the buffers dirty and uptodate bits and let the buffer code
* ignore it as a hole.
*/ */
mlog_bug_on_msg(create && p_blkno == 0 && ocfs2_sparse_alloc(osb), if (create && p_blkno == 0 && ocfs2_sparse_alloc(osb)) {
"ino %lu, iblock %llu\n", inode->i_ino, clear_buffer_dirty(bh_result);
(unsigned long long)iblock); clear_buffer_uptodate(bh_result);
goto bail;
}
/* Treat the unwritten extent as a hole for zeroing purposes. */ /* Treat the unwritten extent as a hole for zeroing purposes. */
if (p_blkno && !(ext_flags & OCFS2_EXT_UNWRITTEN)) if (p_blkno && !(ext_flags & OCFS2_EXT_UNWRITTEN))
......
...@@ -1489,25 +1489,28 @@ static struct o2hb_heartbeat_group *to_o2hb_heartbeat_group(struct config_group ...@@ -1489,25 +1489,28 @@ static struct o2hb_heartbeat_group *to_o2hb_heartbeat_group(struct config_group
: NULL; : NULL;
} }
static struct config_item *o2hb_heartbeat_group_make_item(struct config_group *group, static int o2hb_heartbeat_group_make_item(struct config_group *group,
const char *name) const char *name,
struct config_item **new_item)
{ {
struct o2hb_region *reg = NULL; struct o2hb_region *reg = NULL;
struct config_item *ret = NULL; int ret = 0;
reg = kzalloc(sizeof(struct o2hb_region), GFP_KERNEL); reg = kzalloc(sizeof(struct o2hb_region), GFP_KERNEL);
if (reg == NULL) if (reg == NULL) {
goto out; /* ENOMEM */ ret = -ENOMEM;
goto out;
}
config_item_init_type_name(&reg->hr_item, name, &o2hb_region_type); config_item_init_type_name(&reg->hr_item, name, &o2hb_region_type);
ret = &reg->hr_item; *new_item = &reg->hr_item;
spin_lock(&o2hb_live_lock); spin_lock(&o2hb_live_lock);
list_add_tail(&reg->hr_all_item, &o2hb_all_regions); list_add_tail(&reg->hr_all_item, &o2hb_all_regions);
spin_unlock(&o2hb_live_lock); spin_unlock(&o2hb_live_lock);
out: out:
if (ret == NULL) if (ret)
kfree(reg); kfree(reg);
return ret; return ret;
......
...@@ -146,8 +146,10 @@ static int nst_seq_show(struct seq_file *seq, void *v) ...@@ -146,8 +146,10 @@ static int nst_seq_show(struct seq_file *seq, void *v)
nst->st_task->comm, nst->st_node, nst->st_task->comm, nst->st_node,
nst->st_sc, nst->st_id, nst->st_msg_type, nst->st_sc, nst->st_id, nst->st_msg_type,
nst->st_msg_key, nst->st_msg_key,
nst->st_sock_time.tv_sec, nst->st_sock_time.tv_usec, nst->st_sock_time.tv_sec,
nst->st_send_time.tv_sec, nst->st_send_time.tv_usec, (unsigned long)nst->st_sock_time.tv_usec,
nst->st_send_time.tv_sec,
(unsigned long)nst->st_send_time.tv_usec,
nst->st_status_time.tv_sec, nst->st_status_time.tv_sec,
nst->st_status_time.tv_usec); nst->st_status_time.tv_usec);
} }
...@@ -274,7 +276,7 @@ static void *sc_seq_next(struct seq_file *seq, void *v, loff_t *pos) ...@@ -274,7 +276,7 @@ static void *sc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
return sc; /* unused, just needs to be null when done */ return sc; /* unused, just needs to be null when done */
} }
#define TV_SEC_USEC(TV) TV.tv_sec, TV.tv_usec #define TV_SEC_USEC(TV) TV.tv_sec, (unsigned long)TV.tv_usec
static int sc_seq_show(struct seq_file *seq, void *v) static int sc_seq_show(struct seq_file *seq, void *v)
{ {
......
...@@ -644,27 +644,32 @@ out: ...@@ -644,27 +644,32 @@ out:
return ret; return ret;
} }
static struct config_item *o2nm_node_group_make_item(struct config_group *group, static int o2nm_node_group_make_item(struct config_group *group,
const char *name) const char *name,
struct config_item **new_item)
{ {
struct o2nm_node *node = NULL; struct o2nm_node *node = NULL;
struct config_item *ret = NULL; int ret = 0;
if (strlen(name) > O2NM_MAX_NAME_LEN) if (strlen(name) > O2NM_MAX_NAME_LEN) {
goto out; /* ENAMETOOLONG */ ret = -ENAMETOOLONG;
goto out;
}
node = kzalloc(sizeof(struct o2nm_node), GFP_KERNEL); node = kzalloc(sizeof(struct o2nm_node), GFP_KERNEL);
if (node == NULL) if (node == NULL) {
goto out; /* ENOMEM */ ret = -ENOMEM;
goto out;
}
strcpy(node->nd_name, name); /* use item.ci_namebuf instead? */ strcpy(node->nd_name, name); /* use item.ci_namebuf instead? */
config_item_init_type_name(&node->nd_item, name, &o2nm_node_type); config_item_init_type_name(&node->nd_item, name, &o2nm_node_type);
spin_lock_init(&node->nd_lock); spin_lock_init(&node->nd_lock);
ret = &node->nd_item; *new_item = &node->nd_item;
out: out:
if (ret == NULL) if (ret)
kfree(node); kfree(node);
return ret; return ret;
...@@ -751,25 +756,31 @@ static struct o2nm_cluster_group *to_o2nm_cluster_group(struct config_group *gro ...@@ -751,25 +756,31 @@ static struct o2nm_cluster_group *to_o2nm_cluster_group(struct config_group *gro
} }
#endif #endif
static struct config_group *o2nm_cluster_group_make_group(struct config_group *group, static int o2nm_cluster_group_make_group(struct config_group *group,
const char *name) const char *name,
struct config_group **new_group)
{ {
struct o2nm_cluster *cluster = NULL; struct o2nm_cluster *cluster = NULL;
struct o2nm_node_group *ns = NULL; struct o2nm_node_group *ns = NULL;
struct config_group *o2hb_group = NULL, *ret = NULL; struct config_group *o2hb_group = NULL;
void *defs = NULL; void *defs = NULL;
int ret = 0;
/* this runs under the parent dir's i_mutex; there can be only /* this runs under the parent dir's i_mutex; there can be only
* one caller in here at a time */ * one caller in here at a time */
if (o2nm_single_cluster) if (o2nm_single_cluster) {
goto out; /* ENOSPC */ ret = -ENOSPC;
goto out;
}
cluster = kzalloc(sizeof(struct o2nm_cluster), GFP_KERNEL); cluster = kzalloc(sizeof(struct o2nm_cluster), GFP_KERNEL);
ns = kzalloc(sizeof(struct o2nm_node_group), GFP_KERNEL); ns = kzalloc(sizeof(struct o2nm_node_group), GFP_KERNEL);
defs = kcalloc(3, sizeof(struct config_group *), GFP_KERNEL); defs = kcalloc(3, sizeof(struct config_group *), GFP_KERNEL);
o2hb_group = o2hb_alloc_hb_set(); o2hb_group = o2hb_alloc_hb_set();
if (cluster == NULL || ns == NULL || o2hb_group == NULL || defs == NULL) if (cluster == NULL || ns == NULL || o2hb_group == NULL || defs == NULL) {
ret = -ENOMEM;
goto out; goto out;
}
config_group_init_type_name(&cluster->cl_group, name, config_group_init_type_name(&cluster->cl_group, name,
&o2nm_cluster_type); &o2nm_cluster_type);
...@@ -786,11 +797,11 @@ static struct config_group *o2nm_cluster_group_make_group(struct config_group *g ...@@ -786,11 +797,11 @@ static struct config_group *o2nm_cluster_group_make_group(struct config_group *g
cluster->cl_idle_timeout_ms = O2NET_IDLE_TIMEOUT_MS_DEFAULT; cluster->cl_idle_timeout_ms = O2NET_IDLE_TIMEOUT_MS_DEFAULT;
cluster->cl_keepalive_delay_ms = O2NET_KEEPALIVE_DELAY_MS_DEFAULT; cluster->cl_keepalive_delay_ms = O2NET_KEEPALIVE_DELAY_MS_DEFAULT;
ret = &cluster->cl_group; *new_group = &cluster->cl_group;
o2nm_single_cluster = cluster; o2nm_single_cluster = cluster;
out: out:
if (ret == NULL) { if (ret) {
kfree(cluster); kfree(cluster);
kfree(ns); kfree(ns);
o2hb_free_hb_set(o2hb_group); o2hb_free_hb_set(o2hb_group);
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/debugfs.h> #include <linux/debugfs.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/time.h>
#define MLOG_MASK_PREFIX ML_DLM_GLUE #define MLOG_MASK_PREFIX ML_DLM_GLUE
#include <cluster/masklog.h> #include <cluster/masklog.h>
...@@ -59,6 +60,9 @@ struct ocfs2_mask_waiter { ...@@ -59,6 +60,9 @@ struct ocfs2_mask_waiter {
struct completion mw_complete; struct completion mw_complete;
unsigned long mw_mask; unsigned long mw_mask;
unsigned long mw_goal; unsigned long mw_goal;
#ifdef CONFIG_OCFS2_FS_STATS
unsigned long long mw_lock_start;
#endif
}; };
static struct ocfs2_super *ocfs2_get_dentry_osb(struct ocfs2_lock_res *lockres); static struct ocfs2_super *ocfs2_get_dentry_osb(struct ocfs2_lock_res *lockres);
...@@ -366,6 +370,75 @@ static void ocfs2_remove_lockres_tracking(struct ocfs2_lock_res *res) ...@@ -366,6 +370,75 @@ static void ocfs2_remove_lockres_tracking(struct ocfs2_lock_res *res)
spin_unlock(&ocfs2_dlm_tracking_lock); spin_unlock(&ocfs2_dlm_tracking_lock);
} }
#ifdef CONFIG_OCFS2_FS_STATS
static void ocfs2_init_lock_stats(struct ocfs2_lock_res *res)
{
res->l_lock_num_prmode = 0;
res->l_lock_num_prmode_failed = 0;
res->l_lock_total_prmode = 0;
res->l_lock_max_prmode = 0;
res->l_lock_num_exmode = 0;
res->l_lock_num_exmode_failed = 0;
res->l_lock_total_exmode = 0;
res->l_lock_max_exmode = 0;
res->l_lock_refresh = 0;
}
static void ocfs2_update_lock_stats(struct ocfs2_lock_res *res, int level,
struct ocfs2_mask_waiter *mw, int ret)
{
unsigned long long *num, *sum;
unsigned int *max, *failed;
struct timespec ts = current_kernel_time();
unsigned long long time = timespec_to_ns(&ts) - mw->mw_lock_start;
if (level == LKM_PRMODE) {
num = &res->l_lock_num_prmode;
sum = &res->l_lock_total_prmode;
max = &res->l_lock_max_prmode;
failed = &res->l_lock_num_prmode_failed;
} else if (level == LKM_EXMODE) {
num = &res->l_lock_num_exmode;
sum = &res->l_lock_total_exmode;
max = &res->l_lock_max_exmode;
failed = &res->l_lock_num_exmode_failed;
} else
return;
(*num)++;
(*sum) += time;
if (time > *max)
*max = time;
if (ret)
(*failed)++;
}
static inline void ocfs2_track_lock_refresh(struct ocfs2_lock_res *lockres)
{
lockres->l_lock_refresh++;
}
static inline void ocfs2_init_start_time(struct ocfs2_mask_waiter *mw)
{
struct timespec ts = current_kernel_time();
mw->mw_lock_start = timespec_to_ns(&ts);
}
#else
static inline void ocfs2_init_lock_stats(struct ocfs2_lock_res *res)
{
}
static inline void ocfs2_update_lock_stats(struct ocfs2_lock_res *res,
int level, struct ocfs2_mask_waiter *mw, int ret)
{
}
static inline void ocfs2_track_lock_refresh(struct ocfs2_lock_res *lockres)
{
}
static inline void ocfs2_init_start_time(struct ocfs2_mask_waiter *mw)
{
}
#endif
static void ocfs2_lock_res_init_common(struct ocfs2_super *osb, static void ocfs2_lock_res_init_common(struct ocfs2_super *osb,
struct ocfs2_lock_res *res, struct ocfs2_lock_res *res,
enum ocfs2_lock_type type, enum ocfs2_lock_type type,
...@@ -385,6 +458,8 @@ static void ocfs2_lock_res_init_common(struct ocfs2_super *osb, ...@@ -385,6 +458,8 @@ static void ocfs2_lock_res_init_common(struct ocfs2_super *osb,
res->l_flags = OCFS2_LOCK_INITIALIZED; res->l_flags = OCFS2_LOCK_INITIALIZED;
ocfs2_add_lockres_tracking(res, osb->osb_dlm_debug); ocfs2_add_lockres_tracking(res, osb->osb_dlm_debug);
ocfs2_init_lock_stats(res);
} }
void ocfs2_lock_res_init_once(struct ocfs2_lock_res *res) void ocfs2_lock_res_init_once(struct ocfs2_lock_res *res)
...@@ -1048,6 +1123,7 @@ static void ocfs2_init_mask_waiter(struct ocfs2_mask_waiter *mw) ...@@ -1048,6 +1123,7 @@ static void ocfs2_init_mask_waiter(struct ocfs2_mask_waiter *mw)
{ {
INIT_LIST_HEAD(&mw->mw_item); INIT_LIST_HEAD(&mw->mw_item);
init_completion(&mw->mw_complete); init_completion(&mw->mw_complete);
ocfs2_init_start_time(mw);
} }
static int ocfs2_wait_for_mask(struct ocfs2_mask_waiter *mw) static int ocfs2_wait_for_mask(struct ocfs2_mask_waiter *mw)
...@@ -1254,6 +1330,7 @@ out: ...@@ -1254,6 +1330,7 @@ out:
goto again; goto again;
mlog_errno(ret); mlog_errno(ret);
} }
ocfs2_update_lock_stats(lockres, level, &mw, ret);
mlog_exit(ret); mlog_exit(ret);
return ret; return ret;
...@@ -1983,6 +2060,7 @@ static int ocfs2_inode_lock_update(struct inode *inode, ...@@ -1983,6 +2060,7 @@ static int ocfs2_inode_lock_update(struct inode *inode,
le32_to_cpu(fe->i_flags)); le32_to_cpu(fe->i_flags));
ocfs2_refresh_inode(inode, fe); ocfs2_refresh_inode(inode, fe);
ocfs2_track_lock_refresh(lockres);
} }
status = 0; status = 0;
...@@ -2267,6 +2345,7 @@ int ocfs2_super_lock(struct ocfs2_super *osb, ...@@ -2267,6 +2345,7 @@ int ocfs2_super_lock(struct ocfs2_super *osb,
if (status < 0) if (status < 0)
mlog_errno(status); mlog_errno(status);
ocfs2_track_lock_refresh(lockres);
} }
bail: bail:
mlog_exit(status); mlog_exit(status);
...@@ -2461,7 +2540,7 @@ static void *ocfs2_dlm_seq_next(struct seq_file *m, void *v, loff_t *pos) ...@@ -2461,7 +2540,7 @@ static void *ocfs2_dlm_seq_next(struct seq_file *m, void *v, loff_t *pos)
} }
/* So that debugfs.ocfs2 can determine which format is being used */ /* So that debugfs.ocfs2 can determine which format is being used */
#define OCFS2_DLM_DEBUG_STR_VERSION 1 #define OCFS2_DLM_DEBUG_STR_VERSION 2
static int ocfs2_dlm_seq_show(struct seq_file *m, void *v) static int ocfs2_dlm_seq_show(struct seq_file *m, void *v)
{ {
int i; int i;
...@@ -2502,6 +2581,47 @@ static int ocfs2_dlm_seq_show(struct seq_file *m, void *v) ...@@ -2502,6 +2581,47 @@ static int ocfs2_dlm_seq_show(struct seq_file *m, void *v)
for(i = 0; i < DLM_LVB_LEN; i++) for(i = 0; i < DLM_LVB_LEN; i++)
seq_printf(m, "0x%x\t", lvb[i]); seq_printf(m, "0x%x\t", lvb[i]);
#ifdef CONFIG_OCFS2_FS_STATS
# define lock_num_prmode(_l) (_l)->l_lock_num_prmode
# define lock_num_exmode(_l) (_l)->l_lock_num_exmode
# define lock_num_prmode_failed(_l) (_l)->l_lock_num_prmode_failed
# define lock_num_exmode_failed(_l) (_l)->l_lock_num_exmode_failed
# define lock_total_prmode(_l) (_l)->l_lock_total_prmode
# define lock_total_exmode(_l) (_l)->l_lock_total_exmode
# define lock_max_prmode(_l) (_l)->l_lock_max_prmode
# define lock_max_exmode(_l) (_l)->l_lock_max_exmode
# define lock_refresh(_l) (_l)->l_lock_refresh
#else
# define lock_num_prmode(_l) (0ULL)
# define lock_num_exmode(_l) (0ULL)
# define lock_num_prmode_failed(_l) (0)
# define lock_num_exmode_failed(_l) (0)
# define lock_total_prmode(_l) (0ULL)
# define lock_total_exmode(_l) (0ULL)
# define lock_max_prmode(_l) (0)
# define lock_max_exmode(_l) (0)
# define lock_refresh(_l) (0)
#endif
/* The following seq_print was added in version 2 of this output */
seq_printf(m, "%llu\t"
"%llu\t"
"%u\t"
"%u\t"
"%llu\t"
"%llu\t"
"%u\t"
"%u\t"
"%u\t",
lock_num_prmode(lockres),
lock_num_exmode(lockres),
lock_num_prmode_failed(lockres),
lock_num_exmode_failed(lockres),
lock_total_prmode(lockres),
lock_total_exmode(lockres),
lock_max_prmode(lockres),
lock_max_exmode(lockres),
lock_refresh(lockres));
/* End the line */ /* End the line */
seq_printf(m, "\n"); seq_printf(m, "\n");
return 0; return 0;
......
...@@ -2202,7 +2202,7 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb, ...@@ -2202,7 +2202,7 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb,
ret = generic_file_aio_read(iocb, iov, nr_segs, iocb->ki_pos); ret = generic_file_aio_read(iocb, iov, nr_segs, iocb->ki_pos);
if (ret == -EINVAL) if (ret == -EINVAL)
mlog(ML_ERROR, "generic_file_aio_read returned -EINVAL\n"); mlog(0, "generic_file_aio_read returned -EINVAL\n");
/* buffered aio wouldn't have proper lock coverage today */ /* buffered aio wouldn't have proper lock coverage today */
BUG_ON(ret == -EIOCBQUEUED && !(filp->f_flags & O_DIRECT)); BUG_ON(ret == -EIOCBQUEUED && !(filp->f_flags & O_DIRECT));
......
...@@ -329,7 +329,7 @@ int ocfs2_extend_trans(handle_t *handle, int nblocks) ...@@ -329,7 +329,7 @@ int ocfs2_extend_trans(handle_t *handle, int nblocks)
mlog(0, "Trying to extend transaction by %d blocks\n", nblocks); mlog(0, "Trying to extend transaction by %d blocks\n", nblocks);
#ifdef OCFS2_DEBUG_FS #ifdef CONFIG_OCFS2_DEBUG_FS
status = 1; status = 1;
#else #else
status = journal_extend(handle, nblocks); status = journal_extend(handle, nblocks);
......
...@@ -498,7 +498,7 @@ int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb, ...@@ -498,7 +498,7 @@ int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb,
alloc = (struct ocfs2_dinode *) osb->local_alloc_bh->b_data; alloc = (struct ocfs2_dinode *) osb->local_alloc_bh->b_data;
#ifdef OCFS2_DEBUG_FS #ifdef CONFIG_OCFS2_DEBUG_FS
if (le32_to_cpu(alloc->id1.bitmap1.i_used) != if (le32_to_cpu(alloc->id1.bitmap1.i_used) !=
ocfs2_local_alloc_count_bits(alloc)) { ocfs2_local_alloc_count_bits(alloc)) {
ocfs2_error(osb->sb, "local alloc inode %llu says it has " ocfs2_error(osb->sb, "local alloc inode %llu says it has "
......
...@@ -132,6 +132,18 @@ struct ocfs2_lock_res { ...@@ -132,6 +132,18 @@ struct ocfs2_lock_res {
wait_queue_head_t l_event; wait_queue_head_t l_event;
struct list_head l_debug_list; struct list_head l_debug_list;
#ifdef CONFIG_OCFS2_FS_STATS
unsigned long long l_lock_num_prmode; /* PR acquires */
unsigned long long l_lock_num_exmode; /* EX acquires */
unsigned int l_lock_num_prmode_failed; /* Failed PR gets */
unsigned int l_lock_num_exmode_failed; /* Failed EX gets */
unsigned long long l_lock_total_prmode; /* Tot wait for PR */
unsigned long long l_lock_total_exmode; /* Tot wait for EX */
unsigned int l_lock_max_prmode; /* Max wait for PR */
unsigned int l_lock_max_exmode; /* Max wait for EX */
unsigned int l_lock_refresh; /* Disk refreshes */
#endif
}; };
struct ocfs2_dlm_debug { struct ocfs2_dlm_debug {
......
...@@ -901,7 +901,7 @@ static inline int ocfs2_sprintf_system_inode_name(char *buf, int len, ...@@ -901,7 +901,7 @@ static inline int ocfs2_sprintf_system_inode_name(char *buf, int len,
* list has a copy per slot. * list has a copy per slot.
*/ */
if (type <= OCFS2_LAST_GLOBAL_SYSTEM_INODE) if (type <= OCFS2_LAST_GLOBAL_SYSTEM_INODE)
chars = snprintf(buf, len, chars = snprintf(buf, len, "%s",
ocfs2_system_inodes[type].si_name); ocfs2_system_inodes[type].si_name);
else else
chars = snprintf(buf, len, chars = snprintf(buf, len,
......
...@@ -550,26 +550,17 @@ static ssize_t ocfs2_control_read(struct file *file, ...@@ -550,26 +550,17 @@ static ssize_t ocfs2_control_read(struct file *file,
size_t count, size_t count,
loff_t *ppos) loff_t *ppos)
{ {
char *proto_string = OCFS2_CONTROL_PROTO; ssize_t ret;
size_t to_write = 0;
if (*ppos >= OCFS2_CONTROL_PROTO_LEN)
return 0;
to_write = OCFS2_CONTROL_PROTO_LEN - *ppos;
if (to_write > count)
to_write = count;
if (copy_to_user(buf, proto_string + *ppos, to_write))
return -EFAULT;
*ppos += to_write; ret = simple_read_from_buffer(buf, count, ppos,
OCFS2_CONTROL_PROTO, OCFS2_CONTROL_PROTO_LEN);
/* Have we read the whole protocol list? */ /* Have we read the whole protocol list? */
if (*ppos >= OCFS2_CONTROL_PROTO_LEN) if (ret > 0 && *ppos >= OCFS2_CONTROL_PROTO_LEN)
ocfs2_control_set_handshake_state(file, ocfs2_control_set_handshake_state(file,
OCFS2_CONTROL_HANDSHAKE_READ); OCFS2_CONTROL_HANDSHAKE_READ);
return to_write; return ret;
} }
static int ocfs2_control_release(struct inode *inode, struct file *file) static int ocfs2_control_release(struct inode *inode, struct file *file)
......
...@@ -1703,7 +1703,11 @@ static int ocfs2_check_volume(struct ocfs2_super *osb) ...@@ -1703,7 +1703,11 @@ static int ocfs2_check_volume(struct ocfs2_super *osb)
local = ocfs2_mount_local(osb); local = ocfs2_mount_local(osb);
/* will play back anything left in the journal. */ /* will play back anything left in the journal. */
ocfs2_journal_load(osb->journal, local); status = ocfs2_journal_load(osb->journal, local);
if (status < 0) {
mlog(ML_ERROR, "ocfs2 journal load failed! %d\n", status);
goto finally;
}
if (dirty) { if (dirty) {
/* recover my local alloc if we didn't unmount cleanly. */ /* recover my local alloc if we didn't unmount cleanly. */
......
...@@ -165,8 +165,8 @@ struct configfs_item_operations { ...@@ -165,8 +165,8 @@ struct configfs_item_operations {
}; };
struct configfs_group_operations { struct configfs_group_operations {
struct config_item *(*make_item)(struct config_group *group, const char *name); int (*make_item)(struct config_group *group, const char *name, struct config_item **new_item);
struct config_group *(*make_group)(struct config_group *group, const char *name); int (*make_group)(struct config_group *group, const char *name, struct config_group **new_group);
int (*commit_item)(struct config_item *item); int (*commit_item)(struct config_item *item);
void (*disconnect_notify)(struct config_group *group, struct config_item *item); void (*disconnect_notify)(struct config_group *group, struct config_item *item);
void (*drop_item)(struct config_group *group, struct config_item *item); void (*drop_item)(struct config_group *group, struct config_item *item);
......
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