Page MenuHomeFreeBSD

D29932.diff
No OneTemporary

D29932.diff

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

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)

Event Timeline