diff options
author | Alex Elder <aelder@sgi.com> | 2010-04-13 01:22:29 -0400 |
---|---|---|
committer | Alex Elder <aelder@sgi.com> | 2010-05-19 10:58:12 -0400 |
commit | 6881a229f66f74e4e0a73504389695213987955b (patch) | |
tree | 8faf52f576ab7bfc49712cfd98c49d23a596a98b /fs/xfs/xfs_log_recover.c | |
parent | a0e856b0b4d182c4c52b568bd04bd96a172247a7 (diff) |
xfs: fix min bufsize bugs in two places
This fixes a bug in two places that I found by inspection. In
xlog_find_verify_cycle() and xlog_write_log_records(), the code
attempts to allocate a buffer to hold as many blocks as possible.
It gives up if the number of blocks to be allocated gets too small.
Right now it uses log->l_sectbb_log as that lower bound, but I'm
sure it's supposed to be the actual log sector size instead. That
is, the lower bound should be (1 << log->l_sectbb_log).
Also define a simple macro xlog_sectbb(log) to represent the number
of basic blocks in a sector for the given log.
(No change from original submission; I have implemented Christoph's
suggestion about storing l_sectsize rather than l_sectbb_log in
a new, separate patch in this series.)
Signed-off-by: Alex Elder <aelder@sgi.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Diffstat (limited to 'fs/xfs/xfs_log_recover.c')
-rw-r--r-- | fs/xfs/xfs_log_recover.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index f21eb8ad2d97..0d81a9092552 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c | |||
@@ -66,6 +66,9 @@ STATIC void xlog_recover_check_summary(xlog_t *); | |||
66 | ((bbs + (log)->l_sectbb_mask + 1) & ~(log)->l_sectbb_mask) : (bbs) ) | 66 | ((bbs + (log)->l_sectbb_mask + 1) & ~(log)->l_sectbb_mask) : (bbs) ) |
67 | #define XLOG_SECTOR_ROUNDDOWN_BLKNO(log, bno) ((bno) & ~(log)->l_sectbb_mask) | 67 | #define XLOG_SECTOR_ROUNDDOWN_BLKNO(log, bno) ((bno) & ~(log)->l_sectbb_mask) |
68 | 68 | ||
69 | /* Number of basic blocks in a log sector */ | ||
70 | #define xlog_sectbb(log) (1 << (log)->l_sectbb_log) | ||
71 | |||
69 | STATIC xfs_buf_t * | 72 | STATIC xfs_buf_t * |
70 | xlog_get_bp( | 73 | xlog_get_bp( |
71 | xlog_t *log, | 74 | xlog_t *log, |
@@ -376,12 +379,16 @@ xlog_find_verify_cycle( | |||
376 | xfs_caddr_t buf = NULL; | 379 | xfs_caddr_t buf = NULL; |
377 | int error = 0; | 380 | int error = 0; |
378 | 381 | ||
382 | /* | ||
383 | * Greedily allocate a buffer big enough to handle the full | ||
384 | * range of basic blocks we'll be examining. If that fails, | ||
385 | * try a smaller size. We need to be able to read at least | ||
386 | * a log sector, or we're out of luck. | ||
387 | */ | ||
379 | bufblks = 1 << ffs(nbblks); | 388 | bufblks = 1 << ffs(nbblks); |
380 | |||
381 | while (!(bp = xlog_get_bp(log, bufblks))) { | 389 | while (!(bp = xlog_get_bp(log, bufblks))) { |
382 | /* can't get enough memory to do everything in one big buffer */ | ||
383 | bufblks >>= 1; | 390 | bufblks >>= 1; |
384 | if (bufblks <= log->l_sectbb_log) | 391 | if (bufblks < xlog_sectbb(log)) |
385 | return ENOMEM; | 392 | return ENOMEM; |
386 | } | 393 | } |
387 | 394 | ||
@@ -1158,10 +1165,16 @@ xlog_write_log_records( | |||
1158 | int error = 0; | 1165 | int error = 0; |
1159 | int i, j = 0; | 1166 | int i, j = 0; |
1160 | 1167 | ||
1168 | /* | ||
1169 | * Greedily allocate a buffer big enough to handle the full | ||
1170 | * range of basic blocks to be written. If that fails, try | ||
1171 | * a smaller size. We need to be able to write at least a | ||
1172 | * log sector, or we're out of luck. | ||
1173 | */ | ||
1161 | bufblks = 1 << ffs(blocks); | 1174 | bufblks = 1 << ffs(blocks); |
1162 | while (!(bp = xlog_get_bp(log, bufblks))) { | 1175 | while (!(bp = xlog_get_bp(log, bufblks))) { |
1163 | bufblks >>= 1; | 1176 | bufblks >>= 1; |
1164 | if (bufblks <= log->l_sectbb_log) | 1177 | if (bufblks < xlog_sectbb(log)) |
1165 | return ENOMEM; | 1178 | return ENOMEM; |
1166 | } | 1179 | } |
1167 | 1180 | ||