Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F153412420
D11530.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
26 KB
Referenced Files
None
Subscribers
None
D11530.diff
View Options
Index: head/sys/fs/ext2fs/ext2_alloc.c
===================================================================
--- head/sys/fs/ext2fs/ext2_alloc.c
+++ head/sys/fs/ext2fs/ext2_alloc.c
@@ -103,12 +103,12 @@
if (cred == NOCRED)
panic("ext2_alloc: missing credential");
#endif /* INVARIANTS */
- if (size == fs->e2fs_bsize && fs->e2fs->e2fs_fbcount == 0)
+ if (size == fs->e2fs_bsize && fs->e2fs_fbcount == 0)
goto nospace;
if (cred->cr_uid != 0 &&
- fs->e2fs->e2fs_fbcount < fs->e2fs->e2fs_rbcount)
+ fs->e2fs_fbcount < fs->e2fs_rbcount)
goto nospace;
- if (bpref >= fs->e2fs->e2fs_bcount)
+ if (bpref >= fs->e2fs_bcount)
bpref = 0;
if (bpref == 0)
cg = ino_to_cg(fs, ip->i_number);
@@ -455,6 +455,96 @@
}
/*
+ * 64-bit compatible getters and setters for struct ext2_gd from ext2fs.h
+ */
+static uint64_t
+e2fs_gd_get_b_bitmap(struct ext2_gd *gd)
+{
+
+ return (((uint64_t)(gd->ext4bgd_b_bitmap_hi) << 32) |
+ gd->ext2bgd_b_bitmap);
+}
+
+static uint64_t
+e2fs_gd_get_i_bitmap(struct ext2_gd *gd)
+{
+
+ return (((uint64_t)(gd->ext4bgd_i_bitmap_hi) << 32) |
+ gd->ext2bgd_i_bitmap);
+}
+
+uint64_t
+e2fs_gd_get_i_tables(struct ext2_gd *gd)
+{
+
+ return (((uint64_t)(gd->ext4bgd_i_tables_hi) << 32) |
+ gd->ext2bgd_i_tables);
+}
+
+static uint32_t
+e2fs_gd_get_nbfree(struct ext2_gd *gd)
+{
+
+ return (((uint32_t)(gd->ext4bgd_nbfree_hi) << 16) |
+ gd->ext2bgd_nbfree);
+}
+
+static void
+e2fs_gd_set_nbfree(struct ext2_gd *gd, uint32_t val)
+{
+
+ gd->ext2bgd_nbfree = val & 0xffff;
+ gd->ext4bgd_nbfree_hi = val >> 16;
+}
+
+static uint32_t
+e2fs_gd_get_nifree(struct ext2_gd *gd)
+{
+
+ return (((uint32_t)(gd->ext4bgd_nifree_hi) << 16) |
+ gd->ext2bgd_nifree);
+}
+
+static void
+e2fs_gd_set_nifree(struct ext2_gd *gd, uint32_t val)
+{
+
+ gd->ext2bgd_nifree = val & 0xffff;
+ gd->ext4bgd_nifree_hi = val >> 16;
+}
+
+uint32_t
+e2fs_gd_get_ndirs(struct ext2_gd *gd)
+{
+
+ return (((uint32_t)(gd->ext4bgd_ndirs_hi) << 16) |
+ gd->ext2bgd_ndirs);
+}
+
+static void
+e2fs_gd_set_ndirs(struct ext2_gd *gd, uint32_t val)
+{
+
+ gd->ext2bgd_ndirs = val & 0xffff;
+ gd->ext4bgd_ndirs_hi = val >> 16;
+}
+
+static uint32_t
+e2fs_gd_get_i_unused(struct ext2_gd *gd)
+{
+ return (((uint32_t)(gd->ext4bgd_i_unused_hi) << 16) |
+ gd->ext4bgd_i_unused);
+}
+
+static void
+e2fs_gd_set_i_unused(struct ext2_gd *gd, uint32_t val)
+{
+
+ gd->ext4bgd_i_unused = val & 0xffff;
+ gd->ext4bgd_i_unused_hi = val >> 16;
+}
+
+/*
* Find a cylinder to place a directory.
*
* The policy implemented by this algorithm is to allocate a
@@ -473,8 +563,9 @@
{
struct m_ext2fs *fs;
int cg, prefcg, cgsize;
- u_int avgifree, avgbfree, avgndir, curdirsize;
- u_int minifree, minbfree, maxndir;
+ uint64_t avgbfree, minbfree;
+ u_int avgifree, avgndir, curdirsize;
+ u_int minifree, maxndir;
u_int mincg, minndir;
u_int dirsize, maxcontigdirs;
@@ -482,7 +573,7 @@
fs = pip->i_e2fs;
avgifree = fs->e2fs->e2fs_ficount / fs->e2fs_gcount;
- avgbfree = fs->e2fs->e2fs_fbcount / fs->e2fs_gcount;
+ avgbfree = fs->e2fs_fbcount / fs->e2fs_gcount;
avgndir = fs->e2fs_total_dir / fs->e2fs_gcount;
/*
@@ -494,18 +585,18 @@
mincg = prefcg;
minndir = fs->e2fs_ipg;
for (cg = prefcg; cg < fs->e2fs_gcount; cg++)
- if (fs->e2fs_gd[cg].ext2bgd_ndirs < minndir &&
- fs->e2fs_gd[cg].ext2bgd_nifree >= avgifree &&
- fs->e2fs_gd[cg].ext2bgd_nbfree >= avgbfree) {
+ if (e2fs_gd_get_ndirs(&fs->e2fs_gd[cg]) < minndir &&
+ e2fs_gd_get_nifree(&fs->e2fs_gd[cg]) >= avgifree &&
+ e2fs_gd_get_nbfree(&fs->e2fs_gd[cg]) >= avgbfree) {
mincg = cg;
- minndir = fs->e2fs_gd[cg].ext2bgd_ndirs;
+ minndir = e2fs_gd_get_ndirs(&fs->e2fs_gd[cg]);
}
for (cg = 0; cg < prefcg; cg++)
- if (fs->e2fs_gd[cg].ext2bgd_ndirs < minndir &&
- fs->e2fs_gd[cg].ext2bgd_nifree >= avgifree &&
- fs->e2fs_gd[cg].ext2bgd_nbfree >= avgbfree) {
+ if (e2fs_gd_get_ndirs(&fs->e2fs_gd[cg]) < minndir &&
+ e2fs_gd_get_nifree(&fs->e2fs_gd[cg]) >= avgifree &&
+ e2fs_gd_get_nbfree(&fs->e2fs_gd[cg]) >= avgbfree) {
mincg = cg;
- minndir = fs->e2fs_gd[cg].ext2bgd_ndirs;
+ minndir = e2fs_gd_get_ndirs(&fs->e2fs_gd[cg]);
}
return (mincg);
}
@@ -537,16 +628,16 @@
*/
prefcg = ino_to_cg(fs, pip->i_number);
for (cg = prefcg; cg < fs->e2fs_gcount; cg++)
- if (fs->e2fs_gd[cg].ext2bgd_ndirs < maxndir &&
- fs->e2fs_gd[cg].ext2bgd_nifree >= minifree &&
- fs->e2fs_gd[cg].ext2bgd_nbfree >= minbfree) {
+ if (e2fs_gd_get_ndirs(&fs->e2fs_gd[cg]) < maxndir &&
+ e2fs_gd_get_nifree(&fs->e2fs_gd[cg]) >= minifree &&
+ e2fs_gd_get_nbfree(&fs->e2fs_gd[cg]) >= minbfree) {
if (fs->e2fs_contigdirs[cg] < maxcontigdirs)
return (cg);
}
for (cg = 0; cg < prefcg; cg++)
- if (fs->e2fs_gd[cg].ext2bgd_ndirs < maxndir &&
- fs->e2fs_gd[cg].ext2bgd_nifree >= minifree &&
- fs->e2fs_gd[cg].ext2bgd_nbfree >= minbfree) {
+ if (e2fs_gd_get_ndirs(&fs->e2fs_gd[cg]) < maxndir &&
+ e2fs_gd_get_nifree(&fs->e2fs_gd[cg]) >= minifree &&
+ e2fs_gd_get_nbfree(&fs->e2fs_gd[cg]) >= minbfree) {
if (fs->e2fs_contigdirs[cg] < maxcontigdirs)
return (cg);
}
@@ -554,10 +645,10 @@
* This is a backstop when we have deficit in space.
*/
for (cg = prefcg; cg < fs->e2fs_gcount; cg++)
- if (fs->e2fs_gd[cg].ext2bgd_nifree >= avgifree)
+ if (e2fs_gd_get_nifree(&fs->e2fs_gd[cg]) >= avgifree)
return (cg);
for (cg = 0; cg < prefcg; cg++)
- if (fs->e2fs_gd[cg].ext2bgd_nifree >= avgifree)
+ if (e2fs_gd_get_nifree(&fs->e2fs_gd[cg]) >= avgifree)
break;
return (cg);
}
@@ -709,19 +800,6 @@
return (num);
}
-static int
-ext2_get_cg_number(struct m_ext2fs *fs, daddr_t blk)
-{
- int cg;
-
- if (fs->e2fs->e2fs_bpg == fs->e2fs_bsize * 8)
- cg = (blk - fs->e2fs->e2fs_first_dblock) / (fs->e2fs_bsize * 8);
- else
- cg = blk - fs->e2fs->e2fs_first_dblock;
-
- return (cg);
-}
-
static void
ext2_mark_bitmap_end(int start_bit, int end_bit, char *bitmap)
{
@@ -740,10 +818,9 @@
ext2_cg_block_bitmap_init(struct m_ext2fs *fs, int cg, struct buf *bp)
{
int bit, bit_max, inodes_per_block;
- uint32_t start, tmp;
+ uint64_t start, tmp;
- if (!EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_GDT_CSUM) ||
- !(fs->e2fs_gd[cg].ext4bgd_flags & EXT2_BG_BLOCK_UNINIT))
+ if (!(fs->e2fs_gd[cg].ext4bgd_flags & EXT2_BG_BLOCK_UNINIT))
return (0);
memset(bp->b_data, 0, fs->e2fs_bsize);
@@ -755,25 +832,25 @@
for (bit = 0; bit < bit_max; bit++)
setbit(bp->b_data, bit);
- start = cg * fs->e2fs->e2fs_bpg + fs->e2fs->e2fs_first_dblock;
+ start = (uint64_t)cg * fs->e2fs->e2fs_bpg + fs->e2fs->e2fs_first_dblock;
- /* Set bits for block and inode bitmaps, and inode table */
- tmp = fs->e2fs_gd[cg].ext2bgd_b_bitmap;
+ /* Set bits for block and inode bitmaps, and inode table. */
+ tmp = e2fs_gd_get_b_bitmap(&fs->e2fs_gd[cg]);
if (!EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_FLEX_BG) ||
- tmp == ext2_get_cg_number(fs, cg))
+ cg == dtogd(fs, tmp))
setbit(bp->b_data, tmp - start);
- tmp = fs->e2fs_gd[cg].ext2bgd_i_bitmap;
+ tmp = e2fs_gd_get_i_bitmap(&fs->e2fs_gd[cg]);
if (!EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_FLEX_BG) ||
- tmp == ext2_get_cg_number(fs, cg))
+ cg == dtogd(fs, tmp))
setbit(bp->b_data, tmp - start);
- tmp = fs->e2fs_gd[cg].ext2bgd_i_tables;
+ tmp = e2fs_gd_get_i_tables(&fs->e2fs_gd[cg]);
inodes_per_block = fs->e2fs_bsize/EXT2_INODE_SIZE(fs);
- while( tmp < fs->e2fs_gd[cg].ext2bgd_i_tables +
+ while( tmp < e2fs_gd_get_i_tables(&fs->e2fs_gd[cg]) +
fs->e2fs->e2fs_ipg / inodes_per_block ) {
if (!EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_FLEX_BG) ||
- tmp == ext2_get_cg_number(fs, cg))
+ cg == dtogd(fs, tmp))
setbit(bp->b_data, tmp - start);
tmp++;
}
@@ -810,11 +887,11 @@
/* XXX ondisk32 */
fs = ip->i_e2fs;
ump = ip->i_ump;
- if (fs->e2fs_gd[cg].ext2bgd_nbfree == 0)
+ if (e2fs_gd_get_nbfree(&fs->e2fs_gd[cg]) == 0)
return (0);
EXT2_UNLOCK(ump);
error = bread(ip->i_devvp, fsbtodb(fs,
- fs->e2fs_gd[cg].ext2bgd_b_bitmap),
+ e2fs_gd_get_b_bitmap(&fs->e2fs_gd[cg])),
(int)fs->e2fs_bsize, NOCRED, &bp);
if (error) {
brelse(bp);
@@ -829,7 +906,7 @@
return (0);
}
}
- if (fs->e2fs_gd[cg].ext2bgd_nbfree == 0) {
+ if (e2fs_gd_get_nbfree(&fs->e2fs_gd[cg]) == 0) {
/*
* Another thread allocated the last block in this
* group while we were waiting for the buffer.
@@ -926,12 +1003,13 @@
setbit(bbp, bno);
EXT2_LOCK(ump);
ext2_clusteracct(fs, bbp, cg, bno, -1);
- fs->e2fs->e2fs_fbcount--;
- fs->e2fs_gd[cg].ext2bgd_nbfree--;
+ fs->e2fs_fbcount--;
+ e2fs_gd_set_nbfree(&fs->e2fs_gd[cg],
+ e2fs_gd_get_nbfree(&fs->e2fs_gd[cg]) - 1);
fs->e2fs_fmod = 1;
EXT2_UNLOCK(ump);
bdwrite(bp);
- return (cg * fs->e2fs->e2fs_fpg + fs->e2fs->e2fs_first_dblock + bno);
+ return (((uint64_t)cg) * fs->e2fs->e2fs_fpg + fs->e2fs->e2fs_first_dblock + bno);
}
/*
@@ -956,7 +1034,7 @@
EXT2_UNLOCK(ump);
error = bread(ip->i_devvp,
- fsbtodb(fs, fs->e2fs_gd[cg].ext2bgd_b_bitmap),
+ fsbtodb(fs, e2fs_gd_get_b_bitmap(&fs->e2fs_gd[cg])),
(int)fs->e2fs_bsize, NOCRED, &bp);
if (error)
goto fail_lock;
@@ -1026,8 +1104,9 @@
for (i = 0; i < len; i += fs->e2fs_fpb) {
setbit(bbp, bno + i);
ext2_clusteracct(fs, bbp, cg, bno + i, -1);
- fs->e2fs->e2fs_fbcount--;
- fs->e2fs_gd[cg].ext2bgd_nbfree--;
+ fs->e2fs_fbcount--;
+ e2fs_gd_set_nbfree(&fs->e2fs_gd[cg],
+ e2fs_gd_get_nbfree(&fs->e2fs_gd[cg]) - 1);
}
fs->e2fs_fmod = 1;
EXT2_UNLOCK(ump);
@@ -1058,12 +1137,12 @@
fs->e2fs_bsize;
used_blks = howmany(fs->e2fs->e2fs_ipg -
- fs->e2fs_gd[cg].ext4bgd_i_unused,
+ e2fs_gd_get_i_unused(&fs->e2fs_gd[cg]),
fs->e2fs_bsize / EXT2_INODE_SIZE(fs));
for (i = 0; i < all_blks - used_blks; i++) {
bp = getblk(ip->i_devvp, fsbtodb(fs,
- fs->e2fs_gd[cg].ext2bgd_i_tables + used_blks + i),
+ e2fs_gd_get_i_tables(&fs->e2fs_gd[cg]) + used_blks + i),
fs->e2fs_bsize, 0, 0, 0);
if (!bp)
return (EIO);
@@ -1097,11 +1176,11 @@
ipref = 0;
fs = ip->i_e2fs;
ump = ip->i_ump;
- if (fs->e2fs_gd[cg].ext2bgd_nifree == 0)
+ if (e2fs_gd_get_nifree(&fs->e2fs_gd[cg]) == 0)
return (0);
EXT2_UNLOCK(ump);
error = bread(ip->i_devvp, fsbtodb(fs,
- fs->e2fs_gd[cg].ext2bgd_i_bitmap),
+ e2fs_gd_get_i_bitmap(&fs->e2fs_gd[cg])),
(int)fs->e2fs_bsize, NOCRED, &bp);
if (error) {
brelse(bp);
@@ -1120,7 +1199,7 @@
return (0);
}
}
- if (fs->e2fs_gd[cg].ext2bgd_nifree == 0) {
+ if (e2fs_gd_get_nifree(&fs->e2fs_gd[cg]) == 0) {
/*
* Another thread allocated the last i-node in this
* group while we were waiting for the buffer.
@@ -1153,18 +1232,21 @@
gotit:
setbit(ibp, ipref);
EXT2_LOCK(ump);
- fs->e2fs_gd[cg].ext2bgd_nifree--;
+ e2fs_gd_set_nifree(&fs->e2fs_gd[cg],
+ e2fs_gd_get_nifree(&fs->e2fs_gd[cg]) - 1);
if (EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_GDT_CSUM))
- fs->e2fs_gd[cg].ext4bgd_i_unused--;
+ e2fs_gd_set_i_unused(&fs->e2fs_gd[cg],
+ e2fs_gd_get_i_unused(&fs->e2fs_gd[cg]) - 1);
fs->e2fs->e2fs_ficount--;
fs->e2fs_fmod = 1;
if ((mode & IFMT) == IFDIR) {
- fs->e2fs_gd[cg].ext2bgd_ndirs++;
+ e2fs_gd_set_ndirs(&fs->e2fs_gd[cg],
+ e2fs_gd_get_ndirs(&fs->e2fs_gd[cg]) + 1);
fs->e2fs_total_dir++;
}
EXT2_UNLOCK(ump);
bdwrite(bp);
- return (cg * fs->e2fs->e2fs_ipg + ipref + 1);
+ return ((uint64_t)cg * fs->e2fs_ipg + ipref + 1);
}
/*
@@ -1183,14 +1265,14 @@
fs = ip->i_e2fs;
ump = ip->i_ump;
cg = dtog(fs, bno);
- if (bno >= fs->e2fs->e2fs_bcount) {
+ if (bno >= fs->e2fs_bcount) {
printf("bad block %lld, ino %ju\n", (long long)bno,
(uintmax_t)ip->i_number);
ext2_fserr(fs, ip->i_uid, "bad block");
return;
}
error = bread(ip->i_devvp,
- fsbtodb(fs, fs->e2fs_gd[cg].ext2bgd_b_bitmap),
+ fsbtodb(fs, e2fs_gd_get_b_bitmap(&fs->e2fs_gd[cg])),
(int)fs->e2fs_bsize, NOCRED, &bp);
if (error) {
brelse(bp);
@@ -1206,8 +1288,9 @@
clrbit(bbp, bno);
EXT2_LOCK(ump);
ext2_clusteracct(fs, bbp, cg, bno, 1);
- fs->e2fs->e2fs_fbcount++;
- fs->e2fs_gd[cg].ext2bgd_nbfree++;
+ fs->e2fs_fbcount++;
+ e2fs_gd_set_nbfree(&fs->e2fs_gd[cg],
+ e2fs_gd_get_nbfree(&fs->e2fs_gd[cg]) + 1);
fs->e2fs_fmod = 1;
EXT2_UNLOCK(ump);
bdwrite(bp);
@@ -1236,7 +1319,7 @@
cg = ino_to_cg(fs, ino);
error = bread(pip->i_devvp,
- fsbtodb(fs, fs->e2fs_gd[cg].ext2bgd_i_bitmap),
+ fsbtodb(fs, e2fs_gd_get_i_bitmap(&fs->e2fs_gd[cg])),
(int)fs->e2fs_bsize, NOCRED, &bp);
if (error) {
brelse(bp);
@@ -1253,11 +1336,14 @@
clrbit(ibp, ino);
EXT2_LOCK(ump);
fs->e2fs->e2fs_ficount++;
- fs->e2fs_gd[cg].ext2bgd_nifree++;
+ e2fs_gd_set_nifree(&fs->e2fs_gd[cg],
+ e2fs_gd_get_nifree(&fs->e2fs_gd[cg]) + 1);
if (EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_GDT_CSUM))
- fs->e2fs_gd[cg].ext4bgd_i_unused++;
+ e2fs_gd_set_i_unused(&fs->e2fs_gd[cg],
+ e2fs_gd_get_i_unused(&fs->e2fs_gd[cg]) + 1);
if ((mode & IFMT) == IFDIR) {
- fs->e2fs_gd[cg].ext2bgd_ndirs--;
+ e2fs_gd_set_ndirs(&fs->e2fs_gd[cg],
+ e2fs_gd_get_ndirs(&fs->e2fs_gd[cg]) - 1);
fs->e2fs_total_dir--;
}
fs->e2fs_fmod = 1;
Index: head/sys/fs/ext2fs/ext2_balloc.c
===================================================================
--- head/sys/fs/ext2fs/ext2_balloc.c
+++ head/sys/fs/ext2fs/ext2_balloc.c
@@ -42,6 +42,7 @@
#include <sys/systm.h>
#include <sys/bio.h>
#include <sys/buf.h>
+#include <sys/limits.h>
#include <sys/lock.h>
#include <sys/mount.h>
#include <sys/vnode.h>
@@ -60,13 +61,13 @@
struct m_ext2fs *fs;
struct buf *bp = NULL;
struct vnode *vp = ITOV(ip);
- uint32_t nb;
+ daddr_t newblk;
int osize, nsize, blks, error, allocated;
fs = ip->i_e2fs;
blks = howmany(size, fs->e2fs_bsize);
- error = ext4_ext_get_blocks(ip, lbn, blks, cred, NULL, &allocated, &nb);
+ error = ext4_ext_get_blocks(ip, lbn, blks, cred, NULL, &allocated, &newblk);
if (error)
return (error);
@@ -80,7 +81,7 @@
if(!bp)
return (EIO);
- bp->b_blkno = fsbtodb(fs, nb);
+ bp->b_blkno = fsbtodb(fs, newblk);
if (flags & BA_CLRBUF)
vfs_bio_clrbuf(bp);
} else {
@@ -91,7 +92,7 @@
brelse(bp);
return (error);
}
- bp->b_blkno = fsbtodb(fs, nb);
+ bp->b_blkno = fsbtodb(fs, newblk);
*bpp = bp;
return (0);
}
@@ -101,21 +102,15 @@
*/
osize = fragroundup(fs, blkoff(fs, ip->i_size));
nsize = fragroundup(fs, size);
- if (nsize <= osize) {
+ if (nsize <= osize)
error = bread(vp, lbn, osize, NOCRED, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
- bp->b_blkno = fsbtodb(fs, nb);
- } else {
+ else
error = bread(vp, lbn, fs->e2fs_bsize, NOCRED, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
- bp->b_blkno = fsbtodb(fs, nb);
+ if (error) {
+ brelse(bp);
+ return (error);
}
+ bp->b_blkno = fsbtodb(fs, newblk);
}
*bpp = bp;
@@ -218,6 +213,12 @@
nsize, cred, &newb);
if (error)
return (error);
+ /*
+ * If the newly allocated block exceeds 32-bit limit,
+ * we can not use it in file block maps.
+ */
+ if (newb > UINT_MAX)
+ return (EFBIG);
bp = getblk(vp, lbn, nsize, 0, 0, 0);
bp->b_blkno = fsbtodb(fs, newb);
if (flags & BA_CLRBUF)
@@ -250,6 +251,8 @@
if ((error = ext2_alloc(ip, lbn, pref, fs->e2fs_bsize, cred,
&newb)))
return (error);
+ if (newb > UINT_MAX)
+ return (EFBIG);
nb = newb;
bp = getblk(vp, indirs[1].in_lbn, fs->e2fs_bsize, 0, 0, 0);
bp->b_blkno = fsbtodb(fs, newb);
@@ -293,6 +296,8 @@
brelse(bp);
return (error);
}
+ if (newb > UINT_MAX)
+ return (EFBIG);
nb = newb;
nbp = getblk(vp, indirs[i].in_lbn, fs->e2fs_bsize, 0, 0, 0);
nbp->b_blkno = fsbtodb(fs, nb);
@@ -332,6 +337,8 @@
brelse(bp);
return (error);
}
+ if (newb > UINT_MAX)
+ return (EFBIG);
nb = newb;
nbp = getblk(vp, lbn, fs->e2fs_bsize, 0, 0, 0);
nbp->b_blkno = fsbtodb(fs, nb);
Index: head/sys/fs/ext2fs/ext2_csum.c
===================================================================
--- head/sys/fs/ext2fs/ext2_csum.c
+++ head/sys/fs/ext2fs/ext2_csum.c
@@ -110,7 +110,7 @@
if (EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_64BIT) &&
offset < fs->e2fs->e3fs_desc_size)
crc = ext2_crc16(crc, (uint8_t *)gd + offset,
- fs->e2fs->e3fs_desc_size - offset);
+ fs->e2fs->e3fs_desc_size - offset);
return (crc);
}
Index: head/sys/fs/ext2fs/ext2_extents.h
===================================================================
--- head/sys/fs/ext2fs/ext2_extents.h
+++ head/sys/fs/ext2fs/ext2_extents.h
@@ -120,7 +120,8 @@
int ext4_ext_remove_space(struct inode *ip, off_t length, int flags,
struct ucred *cred, struct thread *td);
int ext4_ext_get_blocks(struct inode *ip, int64_t iblock,
- unsigned long max_blocks, struct ucred *cred, struct buf **bpp, int *allocate, uint32_t *);
+ unsigned long max_blocks, struct ucred *cred, struct buf **bpp,
+ int *allocate, daddr_t *);
#ifdef EXT2FS_DEBUG
void ext4_ext_print_extent_tree_status(struct inode * ip);
#endif
Index: head/sys/fs/ext2fs/ext2_extents.c
===================================================================
--- head/sys/fs/ext2fs/ext2_extents.c
+++ head/sys/fs/ext2fs/ext2_extents.c
@@ -1188,7 +1188,7 @@
int
ext4_ext_get_blocks(struct inode *ip, e4fs_daddr_t iblk,
unsigned long max_blocks, struct ucred *cred, struct buf **bpp,
- int *pallocated, uint32_t *nb)
+ int *pallocated, daddr_t *nb)
{
struct m_ext2fs *fs;
struct buf *bp = NULL;
Index: head/sys/fs/ext2fs/ext2_extern.h
===================================================================
--- head/sys/fs/ext2fs/ext2_extern.h
+++ head/sys/fs/ext2fs/ext2_extern.h
@@ -102,6 +102,8 @@
int *, doff_t *, doff_t *, doff_t *, struct ext2fs_searchslot *);
int ext2_search_dirblock(struct inode *, void *, int *, const char *, int,
int *, doff_t *, doff_t *, doff_t *, struct ext2fs_searchslot *);
+uint32_t e2fs_gd_get_ndirs(struct ext2_gd *gd);
+uint64_t e2fs_gd_get_i_tables(struct ext2_gd *gd);
int ext2_gd_csum_verify(struct m_ext2fs *fs, struct cdev *dev);
void ext2_gd_csum_set(struct m_ext2fs *fs);
Index: head/sys/fs/ext2fs/ext2_hash.c
===================================================================
--- head/sys/fs/ext2fs/ext2_hash.c
+++ head/sys/fs/ext2fs/ext2_hash.c
@@ -60,6 +60,7 @@
#include <sys/stat.h>
#include <sys/mount.h>
+#include <fs/ext2fs/ext2fs.h>
#include <fs/ext2fs/htree.h>
#include <fs/ext2fs/inode.h>
#include <fs/ext2fs/ext2_mount.h>
Index: head/sys/fs/ext2fs/ext2_subr.c
===================================================================
--- head/sys/fs/ext2fs/ext2_subr.c
+++ head/sys/fs/ext2fs/ext2_subr.c
@@ -49,8 +49,8 @@
#include <sys/vnode.h>
#include <fs/ext2fs/inode.h>
-#include <fs/ext2fs/ext2_extern.h>
#include <fs/ext2fs/ext2fs.h>
+#include <fs/ext2fs/ext2_extern.h>
#include <fs/ext2fs/fs.h>
#include <fs/ext2fs/ext2_extents.h>
#include <fs/ext2fs/ext2_mount.h>
Index: head/sys/fs/ext2fs/ext2_vfsops.c
===================================================================
--- head/sys/fs/ext2fs/ext2_vfsops.c
+++ head/sys/fs/ext2fs/ext2_vfsops.c
@@ -326,12 +326,20 @@
compute_sb_data(struct vnode *devvp, struct ext2fs *es,
struct m_ext2fs *fs)
{
- int db_count, error;
- int i;
+ int g_count = 0, error;
+ int i, j;
int logic_sb_block = 1; /* XXX for now */
struct buf *bp;
- uint32_t e2fs_descpb;
+ uint32_t e2fs_descpb, e2fs_gdbcount_alloc;
+ fs->e2fs_bcount = es->e2fs_bcount;
+ fs->e2fs_rbcount = es->e2fs_rbcount;
+ fs->e2fs_fbcount = es->e2fs_fbcount;
+ if (EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_64BIT)) {
+ fs->e2fs_bcount |= (uint64_t)(es->e4fs_bcount_hi) << 32;
+ fs->e2fs_rbcount |= (uint64_t)(es->e4fs_rbcount_hi) << 32;
+ fs->e2fs_fbcount |= (uint64_t)(es->e4fs_fbcount_hi) << 32;
+ }
fs->e2fs_bshift = EXT2_MIN_BLOCK_LOG_SIZE + es->e2fs_log_bsize;
fs->e2fs_bsize = 1U << fs->e2fs_bshift;
fs->e2fs_fsbtodb = es->e2fs_log_bsize + 1;
@@ -375,13 +383,19 @@
fs->e2fs_ipb = fs->e2fs_bsize / EXT2_INODE_SIZE(fs);
fs->e2fs_itpg = fs->e2fs_ipg / fs->e2fs_ipb;
/* s_resuid / s_resgid ? */
- fs->e2fs_gcount = howmany(es->e2fs_bcount - es->e2fs_first_dblock,
+ fs->e2fs_gcount = howmany(fs->e2fs_bcount - es->e2fs_first_dblock,
EXT2_BLOCKS_PER_GROUP(fs));
- e2fs_descpb = fs->e2fs_bsize / sizeof(struct ext2_gd);
- db_count = howmany(fs->e2fs_gcount, e2fs_descpb);
- fs->e2fs_gdbcount = db_count;
- fs->e2fs_gd = malloc(db_count * fs->e2fs_bsize,
- M_EXT2MNT, M_WAITOK);
+ if (EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_64BIT)) {
+ e2fs_descpb = fs->e2fs_bsize / sizeof(struct ext2_gd);
+ e2fs_gdbcount_alloc = howmany(fs->e2fs_gcount, e2fs_descpb);
+ } else {
+ e2fs_descpb = fs->e2fs_bsize / E2FS_REV0_GD_SIZE;
+ e2fs_gdbcount_alloc = howmany(fs->e2fs_gcount,
+ fs->e2fs_bsize / sizeof(struct ext2_gd));
+ }
+ fs->e2fs_gdbcount = howmany(fs->e2fs_gcount, e2fs_descpb);
+ fs->e2fs_gd = malloc(e2fs_gdbcount_alloc * fs->e2fs_bsize,
+ M_EXT2MNT, M_WAITOK | M_ZERO);
fs->e2fs_contigdirs = malloc(fs->e2fs_gcount *
sizeof(*fs->e2fs_contigdirs), M_EXT2MNT, M_WAITOK | M_ZERO);
@@ -392,7 +406,7 @@
*/
if (fs->e2fs_bsize > SBSIZE)
logic_sb_block = 0;
- for (i = 0; i < db_count; i++) {
+ for (i = 0; i < fs->e2fs_gdbcount; i++) {
error = bread(devvp,
fsbtodb(fs, logic_sb_block + i + 1),
fs->e2fs_bsize, NOCRED, &bp);
@@ -402,10 +416,17 @@
brelse(bp);
return (error);
}
- e2fs_cgload((struct ext2_gd *)bp->b_data,
- &fs->e2fs_gd[
- i * fs->e2fs_bsize / sizeof(struct ext2_gd)],
- fs->e2fs_bsize);
+ if (EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_64BIT)) {
+ memcpy(&fs->e2fs_gd[
+ i * fs->e2fs_bsize / sizeof(struct ext2_gd)],
+ bp->b_data, fs->e2fs_bsize);
+ } else {
+ for (j = 0; j < e2fs_descpb &&
+ g_count < fs->e2fs_gcount; j++, g_count++)
+ memcpy(&fs->e2fs_gd[g_count],
+ bp->b_data + j * E2FS_REV0_GD_SIZE,
+ E2FS_REV0_GD_SIZE);
+ }
brelse(bp);
bp = NULL;
}
@@ -823,9 +844,9 @@
sbp->f_bsize = EXT2_FRAG_SIZE(fs);
sbp->f_iosize = EXT2_BLOCK_SIZE(fs);
- sbp->f_blocks = fs->e2fs->e2fs_bcount - overhead;
- sbp->f_bfree = fs->e2fs->e2fs_fbcount;
- sbp->f_bavail = sbp->f_bfree - fs->e2fs->e2fs_rbcount;
+ sbp->f_blocks = fs->e2fs_bcount - overhead;
+ sbp->f_bfree = fs->e2fs_fbcount;
+ sbp->f_bavail = sbp->f_bfree - fs->e2fs_rbcount;
sbp->f_files = fs->e2fs->e2fs_icount;
sbp->f_ffree = fs->e2fs->e2fs_ficount;
return (0);
@@ -1069,6 +1090,15 @@
struct buf *bp;
int error = 0;
+ es->e2fs_bcount = fs->e2fs_bcount & 0xffffffff;
+ es->e2fs_rbcount = fs->e2fs_rbcount & 0xffffffff;
+ es->e2fs_fbcount = fs->e2fs_fbcount & 0xffffffff;
+ if (EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_64BIT)) {
+ es->e4fs_bcount_hi = fs->e2fs_bcount >> 32;
+ es->e4fs_rbcount_hi = fs->e2fs_rbcount >> 32;
+ es->e4fs_fbcount_hi = fs->e2fs_fbcount >> 32;
+ }
+
bp = getblk(mp->um_devvp, SBLOCK, SBSIZE, 0, 0, 0);
bcopy((caddr_t)es, bp->b_data, (u_int)sizeof(struct ext2fs));
if (waitfor == MNT_WAIT)
@@ -1088,7 +1118,7 @@
{
struct m_ext2fs *fs = mp->um_e2fs;
struct buf *bp;
- int i, error = 0, allerror = 0;
+ int i, j, g_count = 0, error = 0, allerror = 0;
allerror = ext2_sbupdate(mp, waitfor);
@@ -1100,9 +1130,16 @@
bp = getblk(mp->um_devvp, fsbtodb(fs,
fs->e2fs->e2fs_first_dblock +
1 /* superblock */ + i), fs->e2fs_bsize, 0, 0, 0);
- e2fs_cgsave(&fs->e2fs_gd[
- i * fs->e2fs_bsize / sizeof(struct ext2_gd)],
- (struct ext2_gd *)bp->b_data, fs->e2fs_bsize);
+ if (EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_64BIT)) {
+ memcpy(bp->b_data, &fs->e2fs_gd[
+ i * fs->e2fs_bsize / sizeof(struct ext2_gd)],
+ fs->e2fs_bsize);
+ } else {
+ for (j = 0; j < fs->e2fs_bsize / E2FS_REV0_GD_SIZE &&
+ g_count < fs->e2fs_gcount; j++, g_count++)
+ memcpy(bp->b_data + j * E2FS_REV0_GD_SIZE,
+ &fs->e2fs_gd[g_count], E2FS_REV0_GD_SIZE);
+ }
if (waitfor == MNT_WAIT)
error = bwrite(bp);
else
Index: head/sys/fs/ext2fs/ext2_vnops.c
===================================================================
--- head/sys/fs/ext2fs/ext2_vnops.c
+++ head/sys/fs/ext2fs/ext2_vnops.c
@@ -84,8 +84,8 @@
#include <fs/ext2fs/fs.h>
#include <fs/ext2fs/inode.h>
#include <fs/ext2fs/ext2_acl.h>
-#include <fs/ext2fs/ext2_extern.h>
#include <fs/ext2fs/ext2fs.h>
+#include <fs/ext2fs/ext2_extern.h>
#include <fs/ext2fs/ext2_dinode.h>
#include <fs/ext2fs/ext2_dir.h>
#include <fs/ext2fs/ext2_mount.h>
Index: head/sys/fs/ext2fs/ext2fs.h
===================================================================
--- head/sys/fs/ext2fs/ext2fs.h
+++ head/sys/fs/ext2fs/ext2fs.h
@@ -156,6 +156,9 @@
char e2fs_fsmnt[MAXMNTLEN];/* name mounted on */
char e2fs_ronly; /* mounted read-only flag */
char e2fs_fmod; /* super block modified flag */
+ uint64_t e2fs_bcount; /* blocks count */
+ uint64_t e2fs_rbcount; /* reserved blocks count */
+ uint64_t e2fs_fbcount; /* free blocks count */
uint32_t e2fs_bsize; /* Block size */
uint32_t e2fs_bshift; /* calc of logical block no */
uint32_t e2fs_bpg; /* Number of blocks per group */
@@ -323,7 +326,8 @@
EXT2F_ROCOMPAT_DIR_NLINK | \
EXT2F_ROCOMPAT_HUGE_FILE | \
EXT2F_ROCOMPAT_EXTRA_ISIZE)
-#define EXT2F_INCOMPAT_SUPP EXT2F_INCOMPAT_FTYPE
+#define EXT2F_INCOMPAT_SUPP (EXT2F_INCOMPAT_FTYPE | \
+ EXT2F_INCOMPAT_64BIT)
#define EXT4F_RO_INCOMPAT_SUPP (EXT2F_INCOMPAT_EXTENTS | \
EXT2F_INCOMPAT_RECOVER | \
EXT2F_INCOMPAT_FLEX_BG | \
@@ -375,14 +379,20 @@
uint16_t ext4bgd_i_bmap_csum; /* inode bitmap checksum */
uint16_t ext4bgd_i_unused; /* unused inode count */
uint16_t ext4bgd_csum; /* group descriptor checksum */
+ uint32_t ext4bgd_b_bitmap_hi; /* high bits of blocks bitmap block */
+ uint32_t ext4bgd_i_bitmap_hi; /* high bits of inodes bitmap block */
+ uint32_t ext4bgd_i_tables_hi; /* high bits of inodes table block */
+ uint16_t ext4bgd_nbfree_hi; /* high bits of number of free blocks */
+ uint16_t ext4bgd_nifree_hi; /* high bits of number of free inodes */
+ uint16_t ext4bgd_ndirs_hi; /* high bits of number of directories */
+ uint16_t ext4bgd_i_unused_hi; /* high bits of unused inode count */
+ uint32_t ext4bgd_x_bitmap_hi; /* high bits of snapshot exclusion */
+ uint16_t ext4bgd_b_bmap_csum_hi;/* high bits of block bitmap checksum */
+ uint16_t ext4bgd_i_bmap_csum_hi;/* high bits of inode bitmap checksum */
+ uint32_t ext4bgd_reserved;
};
-/* EXT2FS metadata is stored in little-endian byte order. These macros
- * help reading it.
- */
-
-#define e2fs_cgload(old, new, size) memcpy((new), (old), (size));
-#define e2fs_cgsave(old, new, size) memcpy((new), (old), (size));
+#define E2FS_REV0_GD_SIZE (sizeof(struct ext2_gd) / 2)
/*
* Macro-instructions used to manage several block sizes
Index: head/sys/fs/ext2fs/fs.h
===================================================================
--- head/sys/fs/ext2fs/fs.h
+++ head/sys/fs/ext2fs/fs.h
@@ -108,7 +108,7 @@
/* get block containing inode from its number x */
#define ino_to_fsba(fs, x) \
- ((fs)->e2fs_gd[ino_to_cg((fs), (x))].ext2bgd_i_tables + \
+ (e2fs_gd_get_i_tables(&(fs)->e2fs_gd[ino_to_cg((fs), (x))]) + \
(((x) - 1) % (fs)->e2fs->e2fs_ipg) / (fs)->e2fs_ipb)
/* get offset for inode in block */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Apr 22, 12:45 AM (11 h, 32 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31942574
Default Alt Text
D11530.diff (26 KB)
Attached To
Mode
D11530: ext2fs: Add 64bit feature support
Attached
Detach File
Event Timeline
Log In to Comment