PERFORCE change 180409 for review
Zheng Liu
lz at FreeBSD.org
Fri Jul 2 11:57:17 UTC 2010
http://p4web.freebsd.org/@@180409?ac=10
Change 180409 by lz at gnehzuil-freebsd on 2010/07/02 11:56:16
Modify ext2_read() function to adapt ext4 extent.
Affected files ...
.. //depot/projects/soc2010/ext4fs/src/sys/fs/ext2fs/ext2_extents.c#2 edit
.. //depot/projects/soc2010/ext4fs/src/sys/fs/ext2fs/ext2_extents.h#3 edit
.. //depot/projects/soc2010/ext4fs/src/sys/fs/ext2fs/ext2_inode.c#3 edit
.. //depot/projects/soc2010/ext4fs/src/sys/fs/ext2fs/ext2_inode_cnv.c#4 edit
.. //depot/projects/soc2010/ext4fs/src/sys/fs/ext2fs/ext2_readwrite.c#3 edit
.. //depot/projects/soc2010/ext4fs/src/sys/fs/ext2fs/ext2_rsv_win.h#3 edit
.. //depot/projects/soc2010/ext4fs/src/sys/fs/ext2fs/ext2_vfsops.c#6 edit
.. //depot/projects/soc2010/ext4fs/src/sys/fs/ext2fs/inode.h#4 edit
Differences ...
==== //depot/projects/soc2010/ext4fs/src/sys/fs/ext2fs/ext2_extents.c#2 (text+ko) ====
@@ -26,10 +26,21 @@
* $FreeBSD: src/sys/fs/ext2fs/ext2_extents.c,v 0.1 2010/07/02 17:22:00 lz Exp $
*/
+#include <sys/types.h>
+
+#include <fs/ext2fs/inode.h>
#include <fs/ext2fs/ext2_extents.h>
+/*
+ * find a block in ext4 extent cache.
+ */
int
ext4_ext_in_cache(struct inode *ip, daddr_t lbn, struct ext4_extent *ep)
{
- return (0);
+ struct ext4_extent_cache *ecp;
+ int ret = EXT4_EXT_CACHE_NO;
+
+ ecp = &ip->i_ext_cache;
+
+ return (ret);
}
==== //depot/projects/soc2010/ext4fs/src/sys/fs/ext2fs/ext2_extents.h#3 (text+ko) ====
@@ -28,8 +28,18 @@
#ifndef _FS_EXT2FS_EXT2_EXTENTS_H_
#define _FS_EXT2FS_EXT2_EXTENTS_H_
+#include <sys/types.h>
+
#define EXT4_EXT_MAGIC 0xf30a
+/* lock/unlock ext lock */
+#define EXT4_EXT_LOCK(ip) mtx_lock(&(ip)->i_ext_lock)
+#define EXT4_EXT_UNLOCK(ip) mtx_unlock(&(ip)->i_ext_lock)
+
+#define EXT4_EXT_CACHE_NO 0
+#define EXT4_EXT_CACHE_GAP 1
+#define EXT4_EXT_CACHE_IN 2
+
/*
* ext4 file system extent on disk
*/
@@ -61,4 +71,17 @@
u_int32_t eh_gen; /* generation of extent tree */
};
+/*
+ * save cached extent
+ */
+struct ext4_extent_cache {
+ daddr_t ec_start; /* extent start */
+ u_int32_t ec_blk; /* logical block */
+ u_int32_t ec_len;
+ u_int32_t ec_type;
+};
+
+struct inode;
+int ext4_ext_in_cache(struct inode *, daddr_t, struct ext4_extent *);
+
#endif /* !_FS_EXT2FS_EXT2_EXTENTS_H_ */
==== //depot/projects/soc2010/ext4fs/src/sys/fs/ext2fs/ext2_inode.c#3 (text+ko) ====
@@ -550,6 +550,8 @@
EXT2_RSV_UNLOCK(ip);
mtx_destroy(&ip->i_rsv_lock);
+ mtx_destroy(&ip->i_ext_lock);
+
free(vp->v_data, M_EXT2NODE);
vp->v_data = 0;
vnode_destroy_vobject(vp);
==== //depot/projects/soc2010/ext4fs/src/sys/fs/ext2fs/ext2_inode_cnv.c#4 (text+ko) ====
@@ -83,10 +83,13 @@
ip->i_atime = ei->e2di_atime;
ip->i_mtime = ei->e2di_mtime;
ip->i_ctime = ei->e2di_ctime;
+ ip->i_flags = ei->e2di_flags; /* we need to entire flags to check new features */
+#if 0
ip->i_flags = 0;
ip->i_flags |= (ei->e2di_flags & EXT2_APPEND) ? SF_APPEND : 0;
ip->i_flags |= (ei->e2di_flags & EXT2_IMMUTABLE) ? SF_IMMUTABLE : 0;
ip->i_flags |= (ei->e2di_flags & EXT2_NODUMP) ? UF_NODUMP : 0;
+#endif
if (ip->i_e2fs->e2fs->e2fs_features_incompat & EXT4F_ROCOMPAT_HUGE_FILE)
ip->i_blocks = ((int64_t)(ei->e2di_nblock_high)) << 32 | ei->e2di_nblock_lo;
else
==== //depot/projects/soc2010/ext4fs/src/sys/fs/ext2fs/ext2_readwrite.c#3 (text+ko) ====
@@ -36,6 +36,9 @@
* $FreeBSD: src/sys/fs/ext2fs/ext2_readwrite.c,v 1.1 2010/01/14 14:30:54 lulf Exp $
*/
+#include <fs/ext2fs/ext2_dinode.h>
+#include <fs/ext2fs/ext2_extents.h>
+
/* XXX TODO: remove these obfuscations (as in ffs_vnops.c). */
#define BLKSIZE(a, b, c) blksize(a, b, c)
#define FS struct m_ext2fs
@@ -45,17 +48,53 @@
#define WRITE ext2_write
#define WRITE_S "ext2_write"
+static int ext4_ext_read(struct vop_read_args *);
+static int ext2_ind_read(struct vop_read_args *);
+
+/*
+ * this function handles ext4 extents block mapping
+ */
+static int
+ext4_ext_read(struct vop_read_args *ap)
+{
+ struct vnode *vp;
+ struct inode *ip;
+ struct uio *uio;
+ struct m_ext2fs *fs;
+ struct ext4_extent nex;
+ daddr_t lbn, nextlbn;
+ u_short mode;
+ int cache_type;
+ int orig_resid;
+ int error = 0;
+
+ vp = ap->a_vp;
+ ip = VTOI(vp);
+ mode = ip->i_mode;
+ uio = ap->a_uio;
+
+ orig_resid = uio->uio_resid;
+ KASSERT(orig_resid >= 0, ("ext2_read: uio->uio_resid < 0"));
+ if (orig_resid == 0)
+ return (0);
+ KASSERT(uio->uio_offset >= 0, ("ext2_read: uio->uio_offset < 0"));
+ fs = ip->I_FS;
+ if (uio->uio_offset < ip->i_size && uio->uio_offset >= fs->e2fs_maxfilesize)
+ return (EOVERFLOW);
+
+ lbn = lblkno(fs, uio->uio_offset);
+ nextlbn = lbn + 1;
+
+ cache_type = ext4_ext_in_cache(ip, lbn, &nex);
+
+ return (error);
+}
+
/*
- * Vnode op for reading.
+ * this function handles traditional block mapping
*/
static int
-READ(ap)
- struct vop_read_args /* {
- struct vnode *a_vp;
- struct uio *a_uio;
- int a_ioflag;
- struct ucred *a_cred;
- } */ *ap;
+ext2_ind_read(struct vop_read_args *ap)
{
struct vnode *vp;
struct inode *ip;
@@ -152,6 +191,35 @@
}
/*
+ * Vnode op for reading.
+ */
+static int
+READ(ap)
+ struct vop_read_args /* {
+ struct vnode *a_vp;
+ struct uio *a_uio;
+ int a_ioflag;
+ struct ucred *a_cred;
+ } */ *ap;
+{
+ struct vnode *vp;
+ struct inode *ip;
+ int error;
+
+ vp = ap->a_vp;
+ ip = VTOI(vp);
+
+ EXT4_EXT_LOCK(ip);
+ if (ip->i_flags & EXT4_EXTENTS)
+ error = ext4_ext_read(ap);
+ else
+ error = ext2_ind_read(ap);
+ EXT4_EXT_UNLOCK(ip);
+
+ return (error);
+}
+
+/*
* Vnode op for writing.
*/
static int
==== //depot/projects/soc2010/ext4fs/src/sys/fs/ext2fs/ext2_rsv_win.h#3 (text+ko) ====
@@ -69,6 +69,7 @@
RB_PROTOTYPE(ext2_rsv_win_tree, ext2_rsv_win, rsv_link, ext2_rsv_win_cmp);
struct inode;
+struct ucred;
/* ext2_alloc.c */
void ext2_init_rsv(struct inode *ip);
void ext2_discard_rsv(struct inode *ip);
==== //depot/projects/soc2010/ext4fs/src/sys/fs/ext2fs/ext2_vfsops.c#6 (text+ko) ====
@@ -931,6 +931,7 @@
ip->i_prealloc_count = 0;
ip->i_prealloc_block = 0;
+ /* initialize rsv lock and rsv data structure */
bzero(&ip->i_rsv_lock, sizeof(struct mtx));
mtx_init(&ip->i_rsv_lock, "inode rsv lock", NULL, MTX_DEF);
EXT2_RSV_LOCK(ip);
@@ -939,6 +940,10 @@
ext2_init_rsv(ip);
EXT2_RSV_UNLOCK(ip);
+ /* initialize ext lock */
+ bzero(&ip->i_ext_lock, sizeof(struct mtx));
+ mtx_init(&ip->i_ext_lock, "inode ext lock", NULL, MTX_DEF);
+
/*
* Now we want to make sure that block pointers for unused
* blocks are zeroed out - ext2_balloc depends on this
==== //depot/projects/soc2010/ext4fs/src/sys/fs/ext2fs/inode.h#4 (text+ko) ====
@@ -38,9 +38,13 @@
#ifndef _FS_EXT2FS_INODE_H_
#define _FS_EXT2FS_INODE_H_
+#include <sys/param.h>
#include <sys/lock.h>
+#include <sys/mutex.h>
#include <sys/queue.h>
+
#include <fs/ext2fs/ext2_rsv_win.h>
+#include <fs/ext2fs/ext2_extents.h>
#define ROOTINO ((ino_t)2)
@@ -102,8 +106,14 @@
u_int32_t i_uid; /* File owner. */
u_int32_t i_gid; /* File group. */
+ /* reservation window */
struct mtx i_rsv_lock; /* Protects i_rsv */
struct ext2_rsv_win *i_rsv; /* Reservation window */
+
+ /* ext4 extents support */
+ struct mtx i_ext_lock; /* this lock only is required in read/write mode
+ but we still use it in read-only mode. */
+ struct ext4_extent_cache i_ext_cache; /* cache for ext4 extent */
};
/*
More information about the p4-projects
mailing list