Commit 64651309 authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-fixes

* git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-fixes:
  [DLM] fix oops in kref_put when removing a lockspace
  [DLM] Fix kref_put oops
  [GFS2] Fix OOM error handling
  [GFS2] Fix incorrect fs sync behaviour.
  [GFS2] don't panic needlessly
parents b7651030 e2de7f56
...@@ -43,6 +43,10 @@ static ssize_t dlm_control_store(struct dlm_ls *ls, const char *buf, size_t len) ...@@ -43,6 +43,10 @@ static ssize_t dlm_control_store(struct dlm_ls *ls, const char *buf, size_t len)
ssize_t ret = len; ssize_t ret = len;
int n = simple_strtol(buf, NULL, 0); int n = simple_strtol(buf, NULL, 0);
ls = dlm_find_lockspace_local(ls->ls_local_handle);
if (!ls)
return -EINVAL;
switch (n) { switch (n) {
case 0: case 0:
dlm_ls_stop(ls); dlm_ls_stop(ls);
...@@ -53,6 +57,7 @@ static ssize_t dlm_control_store(struct dlm_ls *ls, const char *buf, size_t len) ...@@ -53,6 +57,7 @@ static ssize_t dlm_control_store(struct dlm_ls *ls, const char *buf, size_t len)
default: default:
ret = -EINVAL; ret = -EINVAL;
} }
dlm_put_lockspace(ls);
return ret; return ret;
} }
...@@ -143,6 +148,12 @@ static ssize_t dlm_attr_store(struct kobject *kobj, struct attribute *attr, ...@@ -143,6 +148,12 @@ static ssize_t dlm_attr_store(struct kobject *kobj, struct attribute *attr,
return a->store ? a->store(ls, buf, len) : len; return a->store ? a->store(ls, buf, len) : len;
} }
static void lockspace_kobj_release(struct kobject *k)
{
struct dlm_ls *ls = container_of(k, struct dlm_ls, ls_kobj);
kfree(ls);
}
static struct sysfs_ops dlm_attr_ops = { static struct sysfs_ops dlm_attr_ops = {
.show = dlm_attr_show, .show = dlm_attr_show,
.store = dlm_attr_store, .store = dlm_attr_store,
...@@ -151,6 +162,7 @@ static struct sysfs_ops dlm_attr_ops = { ...@@ -151,6 +162,7 @@ static struct sysfs_ops dlm_attr_ops = {
static struct kobj_type dlm_ktype = { static struct kobj_type dlm_ktype = {
.default_attrs = dlm_attrs, .default_attrs = dlm_attrs,
.sysfs_ops = &dlm_attr_ops, .sysfs_ops = &dlm_attr_ops,
.release = lockspace_kobj_release,
}; };
static struct kset dlm_kset = { static struct kset dlm_kset = {
...@@ -678,7 +690,7 @@ static int release_lockspace(struct dlm_ls *ls, int force) ...@@ -678,7 +690,7 @@ static int release_lockspace(struct dlm_ls *ls, int force)
dlm_clear_members_gone(ls); dlm_clear_members_gone(ls);
kfree(ls->ls_node_array); kfree(ls->ls_node_array);
kobject_unregister(&ls->ls_kobj); kobject_unregister(&ls->ls_kobj);
kfree(ls); /* The ls structure will be freed when the kobject is done with */
mutex_lock(&ls_lock); mutex_lock(&ls_lock);
ls_count--; ls_count--;
......
...@@ -157,6 +157,9 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum *inum, ...@@ -157,6 +157,9 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum *inum,
struct gfs2_glock *io_gl; struct gfs2_glock *io_gl;
int error; int error;
if (!inode)
return ERR_PTR(-ENOBUFS);
if (inode->i_state & I_NEW) { if (inode->i_state & I_NEW) {
struct gfs2_sbd *sdp = GFS2_SB(inode); struct gfs2_sbd *sdp = GFS2_SB(inode);
umode_t mode = DT2IF(type); umode_t mode = DT2IF(type);
......
...@@ -84,8 +84,8 @@ static int __init init_gfs2_fs(void) ...@@ -84,8 +84,8 @@ static int __init init_gfs2_fs(void)
gfs2_inode_cachep = kmem_cache_create("gfs2_inode", gfs2_inode_cachep = kmem_cache_create("gfs2_inode",
sizeof(struct gfs2_inode), sizeof(struct gfs2_inode),
0, (SLAB_RECLAIM_ACCOUNT| 0, SLAB_RECLAIM_ACCOUNT|
SLAB_PANIC|SLAB_MEM_SPREAD), SLAB_MEM_SPREAD,
gfs2_init_inode_once, NULL); gfs2_init_inode_once, NULL);
if (!gfs2_inode_cachep) if (!gfs2_inode_cachep)
goto fail; goto fail;
......
...@@ -138,16 +138,27 @@ static void gfs2_put_super(struct super_block *sb) ...@@ -138,16 +138,27 @@ static void gfs2_put_super(struct super_block *sb)
} }
/** /**
* gfs2_write_super - disk commit all incore transactions * gfs2_write_super
* @sb: the filesystem * @sb: the superblock
* *
* This function is called every time sync(2) is called.
* After this exits, all dirty buffers are synced.
*/ */
static void gfs2_write_super(struct super_block *sb) static void gfs2_write_super(struct super_block *sb)
{ {
sb->s_dirt = 0;
}
/**
* gfs2_sync_fs - sync the filesystem
* @sb: the superblock
*
* Flushes the log to disk.
*/
static int gfs2_sync_fs(struct super_block *sb, int wait)
{
sb->s_dirt = 0;
gfs2_log_flush(sb->s_fs_info, NULL); gfs2_log_flush(sb->s_fs_info, NULL);
return 0;
} }
/** /**
...@@ -458,6 +469,7 @@ struct super_operations gfs2_super_ops = { ...@@ -458,6 +469,7 @@ struct super_operations gfs2_super_ops = {
.delete_inode = gfs2_delete_inode, .delete_inode = gfs2_delete_inode,
.put_super = gfs2_put_super, .put_super = gfs2_put_super,
.write_super = gfs2_write_super, .write_super = gfs2_write_super,
.sync_fs = gfs2_sync_fs,
.write_super_lockfs = gfs2_write_super_lockfs, .write_super_lockfs = gfs2_write_super_lockfs,
.unlockfs = gfs2_unlockfs, .unlockfs = gfs2_unlockfs,
.statfs = gfs2_statfs, .statfs = gfs2_statfs,
......
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