Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/ufs/ext2fs Add ext4 extent support from GSoC 2016 (Hrish...



details:   https://anonhg.NetBSD.org/src/rev/2fa4a3be1583
branches:  trunk
changeset: 815786:2fa4a3be1583
user:      christos <christos%NetBSD.org@localhost>
date:      Fri Jun 03 15:35:48 2016 +0000

description:
Add ext4 extent support from GSoC 2016 (Hrishikesh Goyal), from the FreeBSD
ext2 code.

diffstat:

 sys/ufs/ext2fs/ext2fs.h         |   69 +++++++++++-
 sys/ufs/ext2fs/ext2fs_bmap.c    |   82 +++++++++++++-
 sys/ufs/ext2fs/ext2fs_extents.c |  232 ++++++++++++++++++++++++++++++++++++++++
 sys/ufs/ext2fs/ext2fs_extents.h |  107 ++++++++++++++++++
 4 files changed, 480 insertions(+), 10 deletions(-)

diffs (truncated from 564 to 300 lines):

diff -r 81c2a9bd9060 -r 2fa4a3be1583 sys/ufs/ext2fs/ext2fs.h
--- a/sys/ufs/ext2fs/ext2fs.h   Fri Jun 03 15:15:22 2016 +0000
+++ b/sys/ufs/ext2fs/ext2fs.h   Fri Jun 03 15:35:48 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ext2fs.h,v 1.36 2013/06/23 07:28:37 dholland Exp $     */
+/*     $NetBSD: ext2fs.h,v 1.37 2016/06/03 15:35:48 christos Exp $     */
 
 /*
  * Copyright (c) 1982, 1986, 1993
@@ -86,6 +86,11 @@
 #define        BBLOCK          ((daddr_t)(0))
 #define        SBLOCK          ((daddr_t)(BBLOCK + BBSIZE / DEV_BSIZE))
 
+#define        fsbtodb(fs, b)  ((daddr_t)(b) << (fs)->e2fs_fsbtodb)
+/* calculates (loc / fs->fs_bsize) */
+#define        lblkno(fs, loc) ((loc) >> (fs->e2fs_bshift))
+#define        blksize(fs, ip, lbn) ((fs)->e2fs_bsize)
+
 /*
  * Addresses stored in inodes are capable of addressing blocks
  * XXX
@@ -132,7 +137,7 @@
        uint32_t  e2fs_fbcount;         /* free blocks count */
        uint32_t  e2fs_ficount;         /* free inodes count */
        uint32_t  e2fs_first_dblock;    /* first data block */
-       uint32_t  e2fs_log_bsize;       /* block size = 1024*(2^e2fs_log_bsize) */
+       uint32_t  e2fs_log_bsize;       /* bsize = 1024*(2^e2fs_log_bsize) */
        uint32_t  e2fs_fsize;           /* fragment size */
        uint32_t  e2fs_bpg;             /* blocks per group */
        uint32_t  e2fs_fpg;             /* frags per group */
@@ -165,7 +170,62 @@
        uint8_t   e2fs_prealloc;        /* # of blocks to preallocate */
        uint8_t   e2fs_dir_prealloc;    /* # of blocks to preallocate for dir */
        uint16_t  e2fs_reserved_ngdb;   /* # of reserved gd blocks for resize */
-       uint32_t  reserved2[204];
+       
+       /* Additional fields */
+       char      e3fs_journal_uuid[16];/* uuid of journal superblock */
+       uint32_t  e3fs_journal_inum;    /* inode number of journal file */
+       uint32_t  e3fs_journal_dev;     /* device number of journal file */
+       uint32_t  e3fs_last_orphan;     /* start of list of inodes to delete */
+       uint32_t  e3fs_hash_seed[4];    /* HTREE hash seed */
+       char      e3fs_def_hash_version;/* Default hash version to use */
+       char      e3fs_jnl_backup_type;
+       uint16_t  e3fs_desc_size;       /* size of group descriptor */
+       uint32_t  e3fs_default_mount_opts;
+       uint32_t  e3fs_first_meta_bg;   /* First metablock block group */
+       uint32_t  e3fs_mkfs_time;       /* when the fs was created */
+       uint32_t  e3fs_jnl_blks[17];    /* backup of the journal inode */
+       uint32_t  e4fs_bcount_hi;       /* high bits of blocks count */
+       uint32_t  e4fs_rbcount_hi;      /* high bits of reserved blocks count */
+       uint32_t  e4fs_fbcount_hi;      /* high bits of free blocks count */
+       uint16_t  e4fs_min_extra_isize; /* all inodes have some bytes */
+       uint16_t  e4fs_want_extra_isize;/* inodes must reserve some bytes */
+       uint32_t  e4fs_flags;           /* miscellaneous flags */
+       uint16_t  e4fs_raid_stride;     /* RAID stride */
+       uint16_t  e4fs_mmpintv;         /* seconds to wait in MMP checking */
+       uint64_t  e4fs_mmpblk;          /* block for multi-mount protection */
+       uint32_t  e4fs_raid_stripe_wid; /* blocks on data disks (N * stride) */
+       uint8_t   e4fs_log_gpf;         /* FLEX_BG group size */
+       uint8_t   e4fs_chksum_type;     /* metadata checksum algorithm used */
+       uint8_t   e4fs_encrypt;         /* versioning level for encryption */
+       uint8_t   e4fs_reserved_pad;
+       uint64_t  e4fs_kbytes_written;  /* number of lifetime kilobytes */
+       uint32_t  e4fs_snapinum;        /* inode number of active snapshot */
+       uint32_t  e4fs_snapid;          /* sequential ID of active snapshot */
+       uint64_t  e4fs_snaprbcount;     /* rsvd blocks for active snapshot */
+       uint32_t  e4fs_snaplist;        /* inode number for on-disk snapshot */
+       uint32_t  e4fs_errcount;        /* number of file system errors */
+       uint32_t  e4fs_first_errtime;   /* first time an error happened */
+       uint32_t  e4fs_first_errino;    /* inode involved in first error */
+       uint64_t  e4fs_first_errblk;    /* block involved of first error */
+       uint8_t   e4fs_first_errfunc[32];/* function where error happened */
+       uint32_t  e4fs_first_errline;   /* line number where error happened */
+       uint32_t  e4fs_last_errtime;    /* most recent time of an error */
+       uint32_t  e4fs_last_errino;     /* inode involved in last error */
+       uint32_t  e4fs_last_errline;    /* line number where error happened */
+       uint64_t  e4fs_last_errblk;     /* block involved of last error */
+       uint8_t   e4fs_last_errfunc[32];/* function where error happened */
+       uint8_t   e4fs_mount_opts[64];
+       uint32_t  e4fs_usrquota_inum;   /* inode for tracking user quota */
+       uint32_t  e4fs_grpquota_inum;   /* inode for tracking group quota */
+       uint32_t  e4fs_overhead_clusters;/* overhead blocks/clusters */
+       uint32_t  e4fs_backup_bgs[2];   /* groups with sparse_super2 SBs */
+       uint8_t   e4fs_encrypt_algos[4];/* encryption algorithms in use */
+       uint8_t   e4fs_encrypt_pw_salt[16];/* salt used for string2key */
+       uint32_t  e4fs_lpf_ino;         /* location of the lost+found inode */
+       uint32_t  e4fs_proj_quota_inum; /* inode for tracking project quota */
+       uint32_t  e4fs_chksum_seed;     /* checksum seed */
+       uint32_t  e4fs_reserved[98];    /* padding to the end of the block */
+       uint32_t  e4fs_sbchksum;        /* superblock checksum */
 };
 
 
@@ -267,7 +327,8 @@
 #define EXT2F_ROCOMPAT_SUPP            (EXT2F_ROCOMPAT_SPARSESUPER \
                                         | EXT2F_ROCOMPAT_LARGEFILE \
                                         | EXT2F_ROCOMPAT_HUGE_FILE)
-#define EXT2F_INCOMPAT_SUPP            EXT2F_INCOMPAT_FTYPE
+#define EXT2F_INCOMPAT_SUPP            (EXT2F_INCOMPAT_FTYPE \
+                                        | EXT2F_INCOMPAT_EXTENTS)
 
 /*
  * Definitions of behavior on errors
diff -r 81c2a9bd9060 -r 2fa4a3be1583 sys/ufs/ext2fs/ext2fs_bmap.c
--- a/sys/ufs/ext2fs/ext2fs_bmap.c      Fri Jun 03 15:15:22 2016 +0000
+++ b/sys/ufs/ext2fs/ext2fs_bmap.c      Fri Jun 03 15:35:48 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ext2fs_bmap.c,v 1.26 2013/01/22 09:39:15 dholland Exp $        */
+/*     $NetBSD: ext2fs_bmap.c,v 1.27 2016/06/03 15:35:48 christos Exp $        */
 
 /*
  * Copyright (c) 1989, 1991, 1993
@@ -65,7 +65,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ext2fs_bmap.c,v 1.26 2013/01/22 09:39:15 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ext2fs_bmap.c,v 1.27 2016/06/03 15:35:48 christos Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -84,8 +84,10 @@
 #include <ufs/ext2fs/ext2fs.h>
 #include <ufs/ext2fs/ext2fs_extern.h>
 
-static int ext2fs_bmaparray(struct vnode *, daddr_t, daddr_t *,
-                               struct indir *, int *, int *);
+
+static int ext4_bmapext(struct vnode *, int32_t, int64_t *, int *, int *);
+static int ext2fs_bmaparray(struct vnode *, daddr_t, daddr_t *, struct indir *,
+    int *, int *);
 
 #define        is_sequential(ump, a, b)        ((b) == (a) + ump->um_seqinc)
 
@@ -112,11 +114,79 @@
                *ap->a_vpp = VTOI(ap->a_vp)->i_devvp;
        if (ap->a_bnp == NULL)
                return (0);
+       
+       
+       if (VTOI(ap->a_vp)->i_din.e2fs_din->e2di_flags & IN_E4EXTENTS)
+               return ext4_bmapext(ap->a_vp, ap->a_bn, ap->a_bnp,
+                   ap->a_runp, NULL);
+       else
+               return ext2fs_bmaparray(ap->a_vp, ap->a_bn, ap->a_bnp, NULL,
+                   NULL, ap->a_runp);
+       
+               
+}
 
-       return (ext2fs_bmaparray(ap->a_vp, ap->a_bn, ap->a_bnp, NULL, NULL,
-               ap->a_runp));
+/*
+ * Convert the logical block number of a file to its physical block number
+ * on the disk within ext4 extents.
+ */
+static int
+ext4_bmapext(struct vnode *vp, int32_t bn, int64_t *bnp, int *runp, int *runb)
+{      
+       struct inode *ip;
+       struct m_ext2fs  *fs;
+       struct ext4_extent *ep;
+       struct ext4_extent_path path = { .ep_bp = NULL };
+       daddr_t lbn;
+       int error = 0;
+
+       ip = VTOI(vp);
+       fs = ip->i_e2fs;
+       lbn = bn;
+
+       /* XXX: Should not initialize on error? */
+       if (runp != NULL)
+               *runp = 0;
+
+       if (runb != NULL)
+               *runb = 0;
+
+       ext4_ext_find_extent(fs, ip, lbn, &path);
+       if (path.ep_is_sparse) {
+               *bnp = -1;
+               if (runp != NULL)
+                       *runp = path.ep_sparse_ext.e_len -
+                           (lbn - path.ep_sparse_ext.e_blk) - 1;
+               if (runb != NULL)
+                       *runb = lbn - path.ep_sparse_ext.e_blk;
+       } else {
+               if (path.ep_ext == NULL) {
+                       error = EIO;
+                       goto out;
+               }
+               ep = path.ep_ext;
+               *bnp = fsbtodb(fs, lbn - ep->e_blk
+                   + (ep->e_start_lo | (daddr_t)ep->e_start_hi << 32));
+
+               if (*bnp == 0)
+                       *bnp = -1;
+
+               if (runp != NULL)
+                       *runp = ep->e_len - (lbn - ep->e_blk) - 1;
+               if (runb != NULL)
+                       *runb = lbn - ep->e_blk;
+       }
+
+out:
+       if (path.ep_bp != NULL) {
+               brelse(path.ep_bp, 0);
+       }
+
+       return error;
 }
 
+
+
 /*
  * Indirect blocks are now on the vnode for the file.  They are given negative
  * logical block numbers.  Indirect blocks are addressed by the negative
diff -r 81c2a9bd9060 -r 2fa4a3be1583 sys/ufs/ext2fs/ext2fs_extents.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/ufs/ext2fs/ext2fs_extents.c   Fri Jun 03 15:35:48 2016 +0000
@@ -0,0 +1,232 @@
+/*     $NetBSD: ext2fs_extents.c,v 1.1 2016/06/03 15:35:48 christos Exp $      */
+
+/*-
+ * Copyright (c) 2010 Zheng Liu <lz%freebsd.org@localhost>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: head/sys/fs/ext2fs/ext2_extents.c 295523 2016-02-11 15:27:14Z pfg $
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: ext2fs_extents.c,v 1.1 2016/06/03 15:35:48 christos Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/resourcevar.h>
+#include <sys/kernel.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/buf.h>
+#include <sys/proc.h>
+#include <sys/mount.h>
+#include <sys/vnode.h>
+#include <sys/signalvar.h>
+#include <sys/kauth.h>
+
+#include <ufs/ufs/inode.h>
+#include <ufs/ufs/ufsmount.h>
+#include <ufs/ufs/ufs_extern.h>
+
+
+#include <ufs/ext2fs/ext2fs.h>
+#include <ufs/ext2fs/ext2fs_extents.h>
+#include <ufs/ext2fs/ext2fs_extern.h>
+
+
+
+static bool
+ext4_ext_binsearch_index(struct inode *ip, struct ext4_extent_path *path,
+               daddr_t lbn, daddr_t *first_lbn, daddr_t *last_lbn)
+{
+       struct ext4_extent_header *ehp = path->ep_header;
+       struct ext4_extent_index *first, *last, *l, *r, *m;
+
+       first = (struct ext4_extent_index *)(char *)(ehp + 1);
+       last = first + ehp->eh_ecount - 1;
+       l = first;
+       r = last;
+       while (l <= r) {
+               m = l + (r - l) / 2;
+               if (lbn < m->ei_blk)
+                       r = m - 1;
+               else
+                       l = m + 1;
+       }
+
+       if (l == first) {
+               path->ep_sparse_ext.e_blk = *first_lbn;
+               path->ep_sparse_ext.e_len = first->ei_blk - *first_lbn;



Home | Main Index | Thread Index | Old Index