Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F106098979
D29932.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D29932.diff
View Options
diff --git a/sys/fs/ext2fs/ext2_extents.h b/sys/fs/ext2fs/ext2_extents.h
--- a/sys/fs/ext2fs/ext2_extents.h
+++ b/sys/fs/ext2fs/ext2_extents.h
@@ -122,15 +122,15 @@
void ext4_ext_tree_init(struct inode *ip);
int ext4_ext_in_cache(struct inode *, daddr_t, struct ext4_extent *);
void ext4_ext_put_cache(struct inode *, struct ext4_extent *, int);
-int ext4_ext_find_extent(struct inode *, daddr_t, struct ext4_extent_path **);
-void ext4_ext_path_free(struct ext4_extent_path *path);
-int ext4_ext_remove_space(struct inode *ip, off_t length, int flags,
+int ext4_ext_find_extent(struct inode *, daddr_t, struct ext4_extent_path **);
+void ext4_ext_path_free(struct ext4_extent_path *path);
+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,
+int ext4_ext_get_blocks(struct inode *ip, int64_t iblock,
unsigned long max_blocks, struct ucred *cred, struct buf **bpp,
int *allocate, daddr_t *);
#ifdef EXT2FS_PRINT_EXTENTS
-void ext4_ext_print_extent_tree_status(struct inode *ip);
+int ext4_ext_walk(struct inode *ip);
#endif
#endif /* !_FS_EXT2FS_EXT2_EXTENTS_H_ */
diff --git a/sys/fs/ext2fs/ext2_extents.c b/sys/fs/ext2fs/ext2_extents.c
--- a/sys/fs/ext2fs/ext2_extents.c
+++ b/sys/fs/ext2fs/ext2_extents.c
@@ -59,94 +59,140 @@
static MALLOC_DEFINE(M_EXT2EXTENTS, "ext2_extents", "EXT2 extents");
#ifdef EXT2FS_PRINT_EXTENTS
-static void
-ext4_ext_print_extent(struct ext4_extent *ep)
+static const bool print_extents_walk = true;
+
+static int ext4_ext_check_header(struct inode *, struct ext4_extent_header *);
+static int ext4_ext_walk_header(struct inode *, struct ext4_extent_header *);
+static inline e4fs_daddr_t ext4_ext_index_pblock(struct ext4_extent_index *);
+static inline e4fs_daddr_t ext4_ext_extent_pblock(struct ext4_extent *);
+
+static int
+ext4_ext_blk_check(struct inode *ip, e4fs_daddr_t blk)
{
+ struct m_ext2fs *fs;
- printf(" ext %p => (blk %u len %u start %ju)\n",
- ep, le32toh(ep->e_blk), le16toh(ep->e_len),
- (uint64_t)le16toh(ep->e_start_hi) << 32 | le32toh(ep->e_start_lo));
-}
+ fs = ip->i_e2fs;
-static void ext4_ext_print_header(struct inode *ip, struct ext4_extent_header *ehp);
+ if (blk < fs->e2fs->e2fs_first_dblock || blk >= fs->e2fs_bcount)
+ return (EIO);
-static void
-ext4_ext_print_index(struct inode *ip, struct ext4_extent_index *ex, int do_walk)
+ return (0);
+}
+
+static int
+ext4_ext_walk_index(struct inode *ip, struct ext4_extent_index *ex, bool do_walk)
{
struct m_ext2fs *fs;
struct buf *bp;
+ e4fs_daddr_t blk;
int error;
fs = ip->i_e2fs;
- printf(" index %p => (blk %u pblk %ju)\n",
- ex, le32toh(ex->ei_blk), (uint64_t)le16toh(ex->ei_leaf_hi) << 32 |
- le32toh(ex->ei_leaf_lo));
+ if (print_extents_walk)
+ printf(" index %p => (blk %u pblk %ju)\n", ex,
+ le32toh(ex->ei_blk), (uint64_t)le16toh(ex->ei_leaf_hi) << 32 |
+ le32toh(ex->ei_leaf_lo));
if(!do_walk)
- return;
+ return (0);
+
+ blk = ext4_ext_index_pblock(ex);
+ error = ext4_ext_blk_check(ip, blk);
+ if (error)
+ return (error);
if ((error = bread(ip->i_devvp,
- fsbtodb(fs, ((uint64_t)le16toh(ex->ei_leaf_hi) << 32 |
- le32toh(ex->ei_leaf_lo))), (int)fs->e2fs_bsize, NOCRED, &bp)) != 0) {
+ fsbtodb(fs, blk), (int)fs->e2fs_bsize, NOCRED, &bp)) != 0) {
brelse(bp);
- return;
+ return (error);
}
- ext4_ext_print_header(ip, (struct ext4_extent_header *)bp->b_data);
+ error = ext4_ext_walk_header(ip, (struct ext4_extent_header *)bp->b_data);
brelse(bp);
+ return (error);
}
-static void
-ext4_ext_print_header(struct inode *ip, struct ext4_extent_header *ehp)
+static int
+ext4_ext_walk_extent(struct inode *ip, struct ext4_extent *ep)
+{
+ e4fs_daddr_t blk;
+ int error;
+
+ blk = ext4_ext_extent_pblock(ep);
+ error = ext4_ext_blk_check(ip, blk);
+ if (error)
+ return (error);
+
+ if (print_extents_walk)
+ printf(" ext %p => (blk %u len %u start %ju)\n",
+ ep, le32toh(ep->e_blk), le16toh(ep->e_len),
+ (uint64_t)blk);
+
+ return (0);
+}
+
+static int
+ext4_ext_walk_header(struct inode *ip, struct ext4_extent_header *eh)
{
- int i;
+ int i, error = 0;
- printf("header %p => (magic 0x%x entries %d max %d depth %d gen %d)\n",
- ehp, le16toh(ehp->eh_magic), le16toh(ehp->eh_ecount),
- le16toh(ehp->eh_max), le16toh(ehp->eh_depth), le32toh(ehp->eh_gen));
+ error = ext4_ext_check_header(ip, eh);
+ if (error)
+ return (error);
+
+ if (print_extents_walk)
+ printf("header %p => (entries %d max %d depth %d gen %d)\n",
+ eh, le16toh(eh->eh_ecount),
+ le16toh(eh->eh_max), le16toh(eh->eh_depth), le32toh(eh->eh_gen));
- for (i = 0; i < le16toh(ehp->eh_ecount); i++)
- if (ehp->eh_depth != 0)
- ext4_ext_print_index(ip,
- (struct ext4_extent_index *)(ehp + 1 + i), 1);
+ for (i = 0; i < le16toh(eh->eh_ecount) && error == 0; i++)
+ if (eh->eh_depth != 0)
+ error = ext4_ext_walk_index(ip,
+ (struct ext4_extent_index *)(eh + 1 + i), true);
else
- ext4_ext_print_extent((struct ext4_extent *)(ehp + 1 + i));
+ error = ext4_ext_walk_extent(ip, (struct ext4_extent *)(eh + 1 + i));
+
+ return (error);
}
-static void
+static int
ext4_ext_print_path(struct inode *ip, struct ext4_extent_path *path)
{
- int k, l;
+ int k, l, error = 0;
l = path->ep_depth;
- printf("ip=%ju, Path:\n", ip->i_number);
- for (k = 0; k <= l; k++, path++) {
+ if (print_extents_walk)
+ printf("ip=%ju, Path:\n", ip->i_number);
+
+ for (k = 0; k <= l && error == 0; k++, path++) {
if (path->ep_index) {
- ext4_ext_print_index(ip, path->ep_index, 0);
+ error = ext4_ext_walk_index(ip, path->ep_index, false);
} else if (path->ep_ext) {
- ext4_ext_print_extent(path->ep_ext);
+ error = ext4_ext_walk_extent(ip, path->ep_ext);
}
}
+
+ return (error);
}
-void
-ext4_ext_print_extent_tree_status(struct inode *ip)
+int
+ext4_ext_walk(struct inode *ip)
{
struct ext4_extent_header *ehp;
- ehp = (struct ext4_extent_header *)(char *)ip->i_db;
+ ehp = (struct ext4_extent_header *)ip->i_db;
- printf("Extent status:ip=%ju\n", ip->i_number);
- if (!(ip->i_flag & IN_E4EXTENTS))
- return;
+ if (print_extents_walk)
+ printf("Extent status:ip=%ju\n", ip->i_number);
- ext4_ext_print_header(ip, ehp);
+ if (!(ip->i_flag & IN_E4EXTENTS))
+ return (0);
- return;
+ return (ext4_ext_walk_header(ip, ehp));
}
#endif
diff --git a/sys/fs/ext2fs/ext2_inode_cnv.c b/sys/fs/ext2fs/ext2_inode_cnv.c
--- a/sys/fs/ext2fs/ext2_inode_cnv.c
+++ b/sys/fs/ext2fs/ext2_inode_cnv.c
@@ -86,7 +86,7 @@
le16toh(ep->e_start_hi));
printf("\n");
} else {
- printf("BLOCKS:");
+ printf("Blocks:");
for (i = 0; i < (in->i_blocks <= 24 ? (in->i_blocks + 1) / 2 : 12); i++)
printf(" %d", in->i_db[i]);
printf("\n");
diff --git a/sys/fs/ext2fs/ext2_vfsops.c b/sys/fs/ext2fs/ext2_vfsops.c
--- a/sys/fs/ext2fs/ext2_vfsops.c
+++ b/sys/fs/ext2fs/ext2_vfsops.c
@@ -1283,11 +1283,18 @@
for (i = used_blocks; i < EXT2_NDIR_BLOCKS; i++)
ip->i_db[i] = 0;
}
+
+ bqrelse(bp);
+
#ifdef EXT2FS_PRINT_EXTENTS
ext2_print_inode(ip);
- ext4_ext_print_extent_tree_status(ip);
+ error = ext4_ext_walk(ip);
+ if (error) {
+ vput(vp);
+ *vpp = NULL;
+ return (error);
+ }
#endif
- bqrelse(bp);
/*
* Initialize the vnode from the inode, check for aliases.
diff --git a/sys/fs/ext2fs/fs.h b/sys/fs/ext2fs/fs.h
--- a/sys/fs/ext2fs/fs.h
+++ b/sys/fs/ext2fs/fs.h
@@ -164,6 +164,6 @@
/*
* Use if additional debug logging is required.
*/
-/* #define EXT2FS_PRINT_EXTENTS */
+/* #define EXT2FS_PRINT_EXTENTS */
#endif /* !_FS_EXT2FS_FS_H_ */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Dec 26, 9:27 AM (12 h, 16 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15603340
Default Alt Text
D29932.diff (7 KB)
Attached To
Mode
D29932: Improve extents verification logic.
Attached
Detach File
Event Timeline
Log In to Comment