aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/sys.c
diff options
context:
space:
mode:
authorBob Peterson <rpeterso@redhat.com>2012-06-13 10:27:41 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2012-06-13 10:59:48 -0400
commit0d515210b6969ecfc161f71a4515831d9a6e58f4 (patch)
tree2e5a5da49dae5d8c036d56fc7ae14532044dfac3 /fs/gfs2/sys.c
parent0fe2f1e929ecabf834f4af2ffd300fe70700f4b3 (diff)
GFS2: Add kobject release method
This patch adds a kobject release function that properly maintains the kobject use count, so that accesses to the sysfs files do not cause an access to freed kernel memory after an unmount. Signed-off-by: Bob Peterson <rpeterso@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/sys.c')
-rw-r--r--fs/gfs2/sys.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c
index 9c2592b1d5f..e4bee4bebbf 100644
--- a/fs/gfs2/sys.c
+++ b/fs/gfs2/sys.c
@@ -276,7 +276,15 @@ static struct attribute *gfs2_attrs[] = {
276 NULL, 276 NULL,
277}; 277};
278 278
279static void gfs2_sbd_release(struct kobject *kobj)
280{
281 struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj);
282
283 kfree(sdp);
284}
285
279static struct kobj_type gfs2_ktype = { 286static struct kobj_type gfs2_ktype = {
287 .release = gfs2_sbd_release,
280 .default_attrs = gfs2_attrs, 288 .default_attrs = gfs2_attrs,
281 .sysfs_ops = &gfs2_attr_ops, 289 .sysfs_ops = &gfs2_attr_ops,
282}; 290};
@@ -583,6 +591,7 @@ int gfs2_sys_fs_add(struct gfs2_sbd *sdp)
583 char ro[20]; 591 char ro[20];
584 char spectator[20]; 592 char spectator[20];
585 char *envp[] = { ro, spectator, NULL }; 593 char *envp[] = { ro, spectator, NULL };
594 int sysfs_frees_sdp = 0;
586 595
587 sprintf(ro, "RDONLY=%d", (sb->s_flags & MS_RDONLY) ? 1 : 0); 596 sprintf(ro, "RDONLY=%d", (sb->s_flags & MS_RDONLY) ? 1 : 0);
588 sprintf(spectator, "SPECTATOR=%d", sdp->sd_args.ar_spectator ? 1 : 0); 597 sprintf(spectator, "SPECTATOR=%d", sdp->sd_args.ar_spectator ? 1 : 0);
@@ -591,8 +600,10 @@ int gfs2_sys_fs_add(struct gfs2_sbd *sdp)
591 error = kobject_init_and_add(&sdp->sd_kobj, &gfs2_ktype, NULL, 600 error = kobject_init_and_add(&sdp->sd_kobj, &gfs2_ktype, NULL,
592 "%s", sdp->sd_table_name); 601 "%s", sdp->sd_table_name);
593 if (error) 602 if (error)
594 goto fail; 603 goto fail_reg;
595 604
605 sysfs_frees_sdp = 1; /* Freeing sdp is now done by sysfs calling
606 function gfs2_sbd_release. */
596 error = sysfs_create_group(&sdp->sd_kobj, &tune_group); 607 error = sysfs_create_group(&sdp->sd_kobj, &tune_group);
597 if (error) 608 if (error)
598 goto fail_reg; 609 goto fail_reg;
@@ -615,9 +626,13 @@ fail_lock_module:
615fail_tune: 626fail_tune:
616 sysfs_remove_group(&sdp->sd_kobj, &tune_group); 627 sysfs_remove_group(&sdp->sd_kobj, &tune_group);
617fail_reg: 628fail_reg:
618 kobject_put(&sdp->sd_kobj); 629 free_percpu(sdp->sd_lkstats);
619fail:
620 fs_err(sdp, "error %d adding sysfs files", error); 630 fs_err(sdp, "error %d adding sysfs files", error);
631 if (sysfs_frees_sdp)
632 kobject_put(&sdp->sd_kobj);
633 else
634 kfree(sdp);
635 sb->s_fs_info = NULL;
621 return error; 636 return error;
622} 637}
623 638