Skip to content

Commit 11d8b79

Browse files
keesAndreas Gruenbacher
authored andcommitted
gfs2: Use container_of() for gfs2_glock(aspace)
Clang's structure layout randomization feature gets upset when it sees struct address_space (which is randomized) cast to struct gfs2_glock. This is due to seeing the mapping pointer as being treated as an array of gfs2_glock, rather than "something else, before struct address_space": In file included from fs/gfs2/acl.c:23: fs/gfs2/meta_io.h:44:12: error: casting from randomized structure pointer type 'struct address_space *' to 'struct gfs2_glock *' return (((struct gfs2_glock *)mapping) - 1)->gl_name.ln_sbd; ^ Replace the instances of open-coded pointer math with container_of() usage, and update the allocator to match. Some cleanups and conversion of gfs2_glock_get() and gfs2_glock_dealloc() by Andreas. Reported-by: kernel test robot <[email protected]> Link: https://lore.kernel.org/lkml/[email protected] Cc: Bob Peterson <[email protected]> Cc: Andreas Gruenbacher <[email protected]> Cc: Bill Wendling <[email protected]> Cc: [email protected] Signed-off-by: Kees Cook <[email protected]> Signed-off-by: Andreas Gruenbacher <[email protected]>
1 parent 53bb540 commit 11d8b79

File tree

4 files changed

+38
-27
lines changed

4 files changed

+38
-27
lines changed

fs/gfs2/glock.c

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,11 @@ static void gfs2_glock_dealloc(struct rcu_head *rcu)
127127
struct gfs2_glock *gl = container_of(rcu, struct gfs2_glock, gl_rcu);
128128

129129
kfree(gl->gl_lksb.sb_lvbptr);
130-
if (gl->gl_ops->go_flags & GLOF_ASPACE)
131-
kmem_cache_free(gfs2_glock_aspace_cachep, gl);
132-
else
130+
if (gl->gl_ops->go_flags & GLOF_ASPACE) {
131+
struct gfs2_glock_aspace *gla =
132+
container_of(gl, struct gfs2_glock_aspace, glock);
133+
kmem_cache_free(gfs2_glock_aspace_cachep, gla);
134+
} else
133135
kmem_cache_free(gfs2_glock_cachep, gl);
134136
}
135137

@@ -1159,7 +1161,6 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
11591161
.ln_sbd = sdp };
11601162
struct gfs2_glock *gl, *tmp;
11611163
struct address_space *mapping;
1162-
struct kmem_cache *cachep;
11631164
int ret = 0;
11641165

11651166
gl = find_insert_glock(&name, NULL);
@@ -1170,20 +1171,24 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
11701171
if (!create)
11711172
return -ENOENT;
11721173

1173-
if (glops->go_flags & GLOF_ASPACE)
1174-
cachep = gfs2_glock_aspace_cachep;
1175-
else
1176-
cachep = gfs2_glock_cachep;
1177-
gl = kmem_cache_alloc(cachep, GFP_NOFS);
1178-
if (!gl)
1179-
return -ENOMEM;
1180-
1174+
if (glops->go_flags & GLOF_ASPACE) {
1175+
struct gfs2_glock_aspace *gla =
1176+
kmem_cache_alloc(gfs2_glock_aspace_cachep, GFP_NOFS);
1177+
if (!gla)
1178+
return -ENOMEM;
1179+
gl = &gla->glock;
1180+
} else {
1181+
gl = kmem_cache_alloc(gfs2_glock_cachep, GFP_NOFS);
1182+
if (!gl)
1183+
return -ENOMEM;
1184+
}
11811185
memset(&gl->gl_lksb, 0, sizeof(struct dlm_lksb));
1186+
gl->gl_ops = glops;
11821187

11831188
if (glops->go_flags & GLOF_LVB) {
11841189
gl->gl_lksb.sb_lvbptr = kzalloc(GDLM_LVB_SIZE, GFP_NOFS);
11851190
if (!gl->gl_lksb.sb_lvbptr) {
1186-
kmem_cache_free(cachep, gl);
1191+
gfs2_glock_dealloc(&gl->gl_rcu);
11871192
return -ENOMEM;
11881193
}
11891194
}
@@ -1197,7 +1202,6 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
11971202
gl->gl_state = LM_ST_UNLOCKED;
11981203
gl->gl_target = LM_ST_UNLOCKED;
11991204
gl->gl_demote_state = LM_ST_EXCLUSIVE;
1200-
gl->gl_ops = glops;
12011205
gl->gl_dstamp = 0;
12021206
preempt_disable();
12031207
/* We use the global stats to estimate the initial per-glock stats */
@@ -1234,8 +1238,7 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
12341238
*glp = tmp;
12351239

12361240
out_free:
1237-
kfree(gl->gl_lksb.sb_lvbptr);
1238-
kmem_cache_free(cachep, gl);
1241+
gfs2_glock_dealloc(&gl->gl_rcu);
12391242
if (atomic_dec_and_test(&sdp->sd_glock_disposal))
12401243
wake_up(&sdp->sd_glock_wait);
12411244

fs/gfs2/glock.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,11 @@ struct lm_lockops {
138138
const match_table_t *lm_tokens;
139139
};
140140

141+
struct gfs2_glock_aspace {
142+
struct gfs2_glock glock;
143+
struct address_space mapping;
144+
};
145+
141146
extern struct workqueue_struct *gfs2_delete_workqueue;
142147
static inline struct gfs2_holder *gfs2_glock_is_locked_by_me(struct gfs2_glock *gl)
143148
{
@@ -179,8 +184,11 @@ static inline int gfs2_glock_is_held_shrd(struct gfs2_glock *gl)
179184

180185
static inline struct address_space *gfs2_glock2aspace(struct gfs2_glock *gl)
181186
{
182-
if (gl->gl_ops->go_flags & GLOF_ASPACE)
183-
return (struct address_space *)(gl + 1);
187+
if (gl->gl_ops->go_flags & GLOF_ASPACE) {
188+
struct gfs2_glock_aspace *gla =
189+
container_of(gl, struct gfs2_glock_aspace, glock);
190+
return &gla->mapping;
191+
}
184192
return NULL;
185193
}
186194

fs/gfs2/main.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,10 @@ static void gfs2_init_glock_once(void *foo)
6262

6363
static void gfs2_init_gl_aspace_once(void *foo)
6464
{
65-
struct gfs2_glock *gl = foo;
66-
struct address_space *mapping = (struct address_space *)(gl + 1);
65+
struct gfs2_glock_aspace *gla = foo;
6766

68-
gfs2_init_glock_once(gl);
69-
address_space_init_once(mapping);
67+
gfs2_init_glock_once(&gla->glock);
68+
address_space_init_once(&gla->mapping);
7069
}
7170

7271
/**
@@ -104,8 +103,7 @@ static int __init init_gfs2_fs(void)
104103
goto fail_cachep1;
105104

106105
gfs2_glock_aspace_cachep = kmem_cache_create("gfs2_glock(aspace)",
107-
sizeof(struct gfs2_glock) +
108-
sizeof(struct address_space),
106+
sizeof(struct gfs2_glock_aspace),
109107
0, 0, gfs2_init_gl_aspace_once);
110108

111109
if (!gfs2_glock_aspace_cachep)

fs/gfs2/meta_io.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,11 @@ extern const struct address_space_operations gfs2_rgrp_aops;
4040
static inline struct gfs2_sbd *gfs2_mapping2sbd(struct address_space *mapping)
4141
{
4242
struct inode *inode = mapping->host;
43-
if (mapping->a_ops == &gfs2_meta_aops)
44-
return (((struct gfs2_glock *)mapping) - 1)->gl_name.ln_sbd;
45-
else if (mapping->a_ops == &gfs2_rgrp_aops)
43+
if (mapping->a_ops == &gfs2_meta_aops) {
44+
struct gfs2_glock_aspace *gla =
45+
container_of(mapping, struct gfs2_glock_aspace, mapping);
46+
return gla->glock.gl_name.ln_sbd;
47+
} else if (mapping->a_ops == &gfs2_rgrp_aops)
4648
return container_of(mapping, struct gfs2_sbd, sd_aspace);
4749
else
4850
return inode->i_sb->s_fs_info;

0 commit comments

Comments
 (0)