summaryrefslogtreecommitdiffstats
path: root/fs/ubifs/lpt.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-10-20 09:19:03 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-20 09:19:03 -0700
commit396b122f6af3d329df3b4d688f6e66de3e2a399a (patch)
tree0b4185d529c1ba4c8eca1de23f14beecbe460323 /fs/ubifs/lpt.c
parented402af3c23a4804b3f8899263e8d0f97c62ab49 (diff)
parent54779aabb0183bbe049d2b52e96cd148366dfb0b (diff)
Merge branch 'linux-next' of git://git.infradead.org/ubifs-2.6
* 'linux-next' of git://git.infradead.org/ubifs-2.6: (25 commits) UBIFS: fix ubifs_compress commentary UBIFS: amend printk UBIFS: do not read unnecessary bytes when unpacking bits UBIFS: check buffer length when scanning for LPT nodes UBIFS: correct condition to eliminate unecessary assignment UBIFS: add more debugging messages for LPT UBIFS: fix bulk-read handling uptodate pages UBIFS: improve garbage collection UBIFS: allow for sync_fs when read-only UBIFS: commit on sync_fs UBIFS: correct comment for commit_on_unmount UBIFS: update dbg_dump_inode UBIFS: fix commentary UBIFS: fix races in bit-fields UBIFS: ensure data read beyond i_size is zeroed out correctly UBIFS: correct key comparison UBIFS: use bit-fields when possible UBIFS: check data CRC when in error state UBIFS: improve znode splitting rules UBIFS: add no_chk_data_crc mount option ...
Diffstat (limited to 'fs/ubifs/lpt.c')
-rw-r--r--fs/ubifs/lpt.c48
1 files changed, 40 insertions, 8 deletions
diff --git a/fs/ubifs/lpt.c b/fs/ubifs/lpt.c
index 9ff2463177e..db8bd0e518b 100644
--- a/fs/ubifs/lpt.c
+++ b/fs/ubifs/lpt.c
@@ -109,7 +109,8 @@ static void do_calc_lpt_geom(struct ubifs_info *c)
c->lpt_sz = (long long)c->pnode_cnt * c->pnode_sz;
c->lpt_sz += (long long)c->nnode_cnt * c->nnode_sz;
c->lpt_sz += c->ltab_sz;
- c->lpt_sz += c->lsave_sz;
+ if (c->big_lpt)
+ c->lpt_sz += c->lsave_sz;
/* Add wastage */
sz = c->lpt_sz;
@@ -287,25 +288,56 @@ uint32_t ubifs_unpack_bits(uint8_t **addr, int *pos, int nrbits)
const int k = 32 - nrbits;
uint8_t *p = *addr;
int b = *pos;
- uint32_t val;
+ uint32_t uninitialized_var(val);
+ const int bytes = (nrbits + b + 7) >> 3;
ubifs_assert(nrbits > 0);
ubifs_assert(nrbits <= 32);
ubifs_assert(*pos >= 0);
ubifs_assert(*pos < 8);
if (b) {
- val = p[1] | ((uint32_t)p[2] << 8) | ((uint32_t)p[3] << 16) |
- ((uint32_t)p[4] << 24);
+ switch (bytes) {
+ case 2:
+ val = p[1];
+ break;
+ case 3:
+ val = p[1] | ((uint32_t)p[2] << 8);
+ break;
+ case 4:
+ val = p[1] | ((uint32_t)p[2] << 8) |
+ ((uint32_t)p[3] << 16);
+ break;
+ case 5:
+ val = p[1] | ((uint32_t)p[2] << 8) |
+ ((uint32_t)p[3] << 16) |
+ ((uint32_t)p[4] << 24);
+ }
val <<= (8 - b);
val |= *p >> b;
nrbits += b;
- } else
- val = p[0] | ((uint32_t)p[1] << 8) | ((uint32_t)p[2] << 16) |
- ((uint32_t)p[3] << 24);
+ } else {
+ switch (bytes) {
+ case 1:
+ val = p[0];
+ break;
+ case 2:
+ val = p[0] | ((uint32_t)p[1] << 8);
+ break;
+ case 3:
+ val = p[0] | ((uint32_t)p[1] << 8) |
+ ((uint32_t)p[2] << 16);
+ break;
+ case 4:
+ val = p[0] | ((uint32_t)p[1] << 8) |
+ ((uint32_t)p[2] << 16) |
+ ((uint32_t)p[3] << 24);
+ break;
+ }
+ }
val <<= k;
val >>= k;
b = nrbits & 7;
- p += nrbits / 8;
+ p += nrbits >> 3;
*addr = p;
*pos = b;
ubifs_assert((val >> nrbits) == 0 || nrbits - b == 32);