Skip to content

Commit

Permalink
GFS2: use kmalloc for lvb bitmap
Browse files Browse the repository at this point in the history
The temp lvb bitmap was on the stack, which could
be an alignment problem for __set_bit_le.  Use
kmalloc for it instead.

Signed-off-by: David Teigland <[email protected]>
Signed-off-by: Steven Whitehouse <[email protected]>
  • Loading branch information
teigland authored and swhiteho committed Apr 4, 2013
1 parent 66ade47 commit 57c7310
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 13 deletions.
1 change: 1 addition & 0 deletions fs/gfs2/incore.h
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,7 @@ struct lm_lockstruct {
struct dlm_lksb ls_control_lksb; /* control_lock */
char ls_control_lvb[GDLM_LVB_SIZE]; /* control_lock lvb */
struct completion ls_sync_wait; /* {control,mounted}_{lock,unlock} */
char *ls_lvb_bits;

spinlock_t ls_recover_spin; /* protects following fields */
unsigned long ls_recover_flags; /* DFL_ */
Expand Down
31 changes: 18 additions & 13 deletions fs/gfs2/lock_dlm.c
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,6 @@ static void gfs2_control_func(struct work_struct *work)
{
struct gfs2_sbd *sdp = container_of(work, struct gfs2_sbd, sd_control_work.work);
struct lm_lockstruct *ls = &sdp->sd_lockstruct;
char lvb_bits[GDLM_LVB_SIZE];
uint32_t block_gen, start_gen, lvb_gen, flags;
int recover_set = 0;
int write_lvb = 0;
Expand Down Expand Up @@ -634,7 +633,7 @@ static void gfs2_control_func(struct work_struct *work)
return;
}

control_lvb_read(ls, &lvb_gen, lvb_bits);
control_lvb_read(ls, &lvb_gen, ls->ls_lvb_bits);

spin_lock(&ls->ls_recover_spin);
if (block_gen != ls->ls_recover_block ||
Expand Down Expand Up @@ -664,10 +663,10 @@ static void gfs2_control_func(struct work_struct *work)

ls->ls_recover_result[i] = 0;

if (!test_bit_le(i, lvb_bits + JID_BITMAP_OFFSET))
if (!test_bit_le(i, ls->ls_lvb_bits + JID_BITMAP_OFFSET))
continue;

__clear_bit_le(i, lvb_bits + JID_BITMAP_OFFSET);
__clear_bit_le(i, ls->ls_lvb_bits + JID_BITMAP_OFFSET);
write_lvb = 1;
}
}
Expand All @@ -691,7 +690,7 @@ static void gfs2_control_func(struct work_struct *work)
continue;
if (ls->ls_recover_submit[i] < start_gen) {
ls->ls_recover_submit[i] = 0;
__set_bit_le(i, lvb_bits + JID_BITMAP_OFFSET);
__set_bit_le(i, ls->ls_lvb_bits + JID_BITMAP_OFFSET);
}
}
/* even if there are no bits to set, we need to write the
Expand All @@ -705,7 +704,7 @@ static void gfs2_control_func(struct work_struct *work)
spin_unlock(&ls->ls_recover_spin);

if (write_lvb) {
control_lvb_write(ls, start_gen, lvb_bits);
control_lvb_write(ls, start_gen, ls->ls_lvb_bits);
flags = DLM_LKF_CONVERT | DLM_LKF_VALBLK;
} else {
flags = DLM_LKF_CONVERT;
Expand All @@ -725,7 +724,7 @@ static void gfs2_control_func(struct work_struct *work)
*/

for (i = 0; i < recover_size; i++) {
if (test_bit_le(i, lvb_bits + JID_BITMAP_OFFSET)) {
if (test_bit_le(i, ls->ls_lvb_bits + JID_BITMAP_OFFSET)) {
fs_info(sdp, "recover generation %u jid %d\n",
start_gen, i);
gfs2_recover_set(sdp, i);
Expand Down Expand Up @@ -758,7 +757,6 @@ static void gfs2_control_func(struct work_struct *work)
static int control_mount(struct gfs2_sbd *sdp)
{
struct lm_lockstruct *ls = &sdp->sd_lockstruct;
char lvb_bits[GDLM_LVB_SIZE];
uint32_t start_gen, block_gen, mount_gen, lvb_gen;
int mounted_mode;
int retries = 0;
Expand Down Expand Up @@ -857,7 +855,7 @@ static int control_mount(struct gfs2_sbd *sdp)
* lvb_gen will be non-zero.
*/

control_lvb_read(ls, &lvb_gen, lvb_bits);
control_lvb_read(ls, &lvb_gen, ls->ls_lvb_bits);

if (lvb_gen == 0xFFFFFFFF) {
/* special value to force mount attempts to fail */
Expand Down Expand Up @@ -887,7 +885,7 @@ static int control_mount(struct gfs2_sbd *sdp)
* and all lvb bits to be clear (no pending journal recoveries.)
*/

if (!all_jid_bits_clear(lvb_bits)) {
if (!all_jid_bits_clear(ls->ls_lvb_bits)) {
/* journals need recovery, wait until all are clear */
fs_info(sdp, "control_mount wait for journal recovery\n");
goto restart;
Expand Down Expand Up @@ -949,7 +947,6 @@ static int dlm_recovery_wait(void *word)
static int control_first_done(struct gfs2_sbd *sdp)
{
struct lm_lockstruct *ls = &sdp->sd_lockstruct;
char lvb_bits[GDLM_LVB_SIZE];
uint32_t start_gen, block_gen;
int error;

Expand Down Expand Up @@ -991,8 +988,8 @@ static int control_first_done(struct gfs2_sbd *sdp)
memset(ls->ls_recover_result, 0, ls->ls_recover_size*sizeof(uint32_t));
spin_unlock(&ls->ls_recover_spin);

memset(lvb_bits, 0, sizeof(lvb_bits));
control_lvb_write(ls, start_gen, lvb_bits);
memset(ls->ls_lvb_bits, 0, GDLM_LVB_SIZE);
control_lvb_write(ls, start_gen, ls->ls_lvb_bits);

error = mounted_lock(sdp, DLM_LOCK_PR, DLM_LKF_CONVERT);
if (error)
Expand Down Expand Up @@ -1022,6 +1019,12 @@ static int set_recover_size(struct gfs2_sbd *sdp, struct dlm_slot *slots,
uint32_t old_size, new_size;
int i, max_jid;

if (!ls->ls_lvb_bits) {
ls->ls_lvb_bits = kzalloc(GDLM_LVB_SIZE, GFP_NOFS);
if (!ls->ls_lvb_bits)
return -ENOMEM;
}

max_jid = 0;
for (i = 0; i < num_slots; i++) {
if (max_jid < slots[i].slot - 1)
Expand Down Expand Up @@ -1057,6 +1060,7 @@ static int set_recover_size(struct gfs2_sbd *sdp, struct dlm_slot *slots,

static void free_recover_size(struct lm_lockstruct *ls)
{
kfree(ls->ls_lvb_bits);
kfree(ls->ls_recover_submit);
kfree(ls->ls_recover_result);
ls->ls_recover_submit = NULL;
Expand Down Expand Up @@ -1205,6 +1209,7 @@ static int gdlm_mount(struct gfs2_sbd *sdp, const char *table)
ls->ls_recover_size = 0;
ls->ls_recover_submit = NULL;
ls->ls_recover_result = NULL;
ls->ls_lvb_bits = NULL;

error = set_recover_size(sdp, NULL, 0);
if (error)
Expand Down

0 comments on commit 57c7310

Please sign in to comment.