Skip to content

Commit 57c7310

Browse files
teiglandswhiteho
authored andcommitted
GFS2: use kmalloc for lvb bitmap
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]>
1 parent 66ade47 commit 57c7310

File tree

2 files changed

+19
-13
lines changed

2 files changed

+19
-13
lines changed

fs/gfs2/incore.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,7 @@ struct lm_lockstruct {
588588
struct dlm_lksb ls_control_lksb; /* control_lock */
589589
char ls_control_lvb[GDLM_LVB_SIZE]; /* control_lock lvb */
590590
struct completion ls_sync_wait; /* {control,mounted}_{lock,unlock} */
591+
char *ls_lvb_bits;
591592

592593
spinlock_t ls_recover_spin; /* protects following fields */
593594
unsigned long ls_recover_flags; /* DFL_ */

fs/gfs2/lock_dlm.c

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,6 @@ static void gfs2_control_func(struct work_struct *work)
580580
{
581581
struct gfs2_sbd *sdp = container_of(work, struct gfs2_sbd, sd_control_work.work);
582582
struct lm_lockstruct *ls = &sdp->sd_lockstruct;
583-
char lvb_bits[GDLM_LVB_SIZE];
584583
uint32_t block_gen, start_gen, lvb_gen, flags;
585584
int recover_set = 0;
586585
int write_lvb = 0;
@@ -634,7 +633,7 @@ static void gfs2_control_func(struct work_struct *work)
634633
return;
635634
}
636635

637-
control_lvb_read(ls, &lvb_gen, lvb_bits);
636+
control_lvb_read(ls, &lvb_gen, ls->ls_lvb_bits);
638637

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

665664
ls->ls_recover_result[i] = 0;
666665

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

670-
__clear_bit_le(i, lvb_bits + JID_BITMAP_OFFSET);
669+
__clear_bit_le(i, ls->ls_lvb_bits + JID_BITMAP_OFFSET);
671670
write_lvb = 1;
672671
}
673672
}
@@ -691,7 +690,7 @@ static void gfs2_control_func(struct work_struct *work)
691690
continue;
692691
if (ls->ls_recover_submit[i] < start_gen) {
693692
ls->ls_recover_submit[i] = 0;
694-
__set_bit_le(i, lvb_bits + JID_BITMAP_OFFSET);
693+
__set_bit_le(i, ls->ls_lvb_bits + JID_BITMAP_OFFSET);
695694
}
696695
}
697696
/* even if there are no bits to set, we need to write the
@@ -705,7 +704,7 @@ static void gfs2_control_func(struct work_struct *work)
705704
spin_unlock(&ls->ls_recover_spin);
706705

707706
if (write_lvb) {
708-
control_lvb_write(ls, start_gen, lvb_bits);
707+
control_lvb_write(ls, start_gen, ls->ls_lvb_bits);
709708
flags = DLM_LKF_CONVERT | DLM_LKF_VALBLK;
710709
} else {
711710
flags = DLM_LKF_CONVERT;
@@ -725,7 +724,7 @@ static void gfs2_control_func(struct work_struct *work)
725724
*/
726725

727726
for (i = 0; i < recover_size; i++) {
728-
if (test_bit_le(i, lvb_bits + JID_BITMAP_OFFSET)) {
727+
if (test_bit_le(i, ls->ls_lvb_bits + JID_BITMAP_OFFSET)) {
729728
fs_info(sdp, "recover generation %u jid %d\n",
730729
start_gen, i);
731730
gfs2_recover_set(sdp, i);
@@ -758,7 +757,6 @@ static void gfs2_control_func(struct work_struct *work)
758757
static int control_mount(struct gfs2_sbd *sdp)
759758
{
760759
struct lm_lockstruct *ls = &sdp->sd_lockstruct;
761-
char lvb_bits[GDLM_LVB_SIZE];
762760
uint32_t start_gen, block_gen, mount_gen, lvb_gen;
763761
int mounted_mode;
764762
int retries = 0;
@@ -857,7 +855,7 @@ static int control_mount(struct gfs2_sbd *sdp)
857855
* lvb_gen will be non-zero.
858856
*/
859857

860-
control_lvb_read(ls, &lvb_gen, lvb_bits);
858+
control_lvb_read(ls, &lvb_gen, ls->ls_lvb_bits);
861859

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

890-
if (!all_jid_bits_clear(lvb_bits)) {
888+
if (!all_jid_bits_clear(ls->ls_lvb_bits)) {
891889
/* journals need recovery, wait until all are clear */
892890
fs_info(sdp, "control_mount wait for journal recovery\n");
893891
goto restart;
@@ -949,7 +947,6 @@ static int dlm_recovery_wait(void *word)
949947
static int control_first_done(struct gfs2_sbd *sdp)
950948
{
951949
struct lm_lockstruct *ls = &sdp->sd_lockstruct;
952-
char lvb_bits[GDLM_LVB_SIZE];
953950
uint32_t start_gen, block_gen;
954951
int error;
955952

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

994-
memset(lvb_bits, 0, sizeof(lvb_bits));
995-
control_lvb_write(ls, start_gen, lvb_bits);
991+
memset(ls->ls_lvb_bits, 0, GDLM_LVB_SIZE);
992+
control_lvb_write(ls, start_gen, ls->ls_lvb_bits);
996993

997994
error = mounted_lock(sdp, DLM_LOCK_PR, DLM_LKF_CONVERT);
998995
if (error)
@@ -1022,6 +1019,12 @@ static int set_recover_size(struct gfs2_sbd *sdp, struct dlm_slot *slots,
10221019
uint32_t old_size, new_size;
10231020
int i, max_jid;
10241021

1022+
if (!ls->ls_lvb_bits) {
1023+
ls->ls_lvb_bits = kzalloc(GDLM_LVB_SIZE, GFP_NOFS);
1024+
if (!ls->ls_lvb_bits)
1025+
return -ENOMEM;
1026+
}
1027+
10251028
max_jid = 0;
10261029
for (i = 0; i < num_slots; i++) {
10271030
if (max_jid < slots[i].slot - 1)
@@ -1057,6 +1060,7 @@ static int set_recover_size(struct gfs2_sbd *sdp, struct dlm_slot *slots,
10571060

10581061
static void free_recover_size(struct lm_lockstruct *ls)
10591062
{
1063+
kfree(ls->ls_lvb_bits);
10601064
kfree(ls->ls_recover_submit);
10611065
kfree(ls->ls_recover_result);
10621066
ls->ls_recover_submit = NULL;
@@ -1205,6 +1209,7 @@ static int gdlm_mount(struct gfs2_sbd *sdp, const char *table)
12051209
ls->ls_recover_size = 0;
12061210
ls->ls_recover_submit = NULL;
12071211
ls->ls_recover_result = NULL;
1212+
ls->ls_lvb_bits = NULL;
12081213

12091214
error = set_recover_size(sdp, NULL, 0);
12101215
if (error)

0 commit comments

Comments
 (0)