]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - fs/xfs/libxfs/xfs_inode_fork.c
Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost
[mirror_ubuntu-artful-kernel.git] / fs / xfs / libxfs / xfs_inode_fork.c
index 5dd56d3dbb3aeb41e7e46b921ca9052dd9066c41..222e103356c6d838742703315a5f558551faf51e 100644 (file)
@@ -775,6 +775,13 @@ xfs_idestroy_fork(
        }
 }
 
+/* Count number of incore extents based on if_bytes */
+xfs_extnum_t
+xfs_iext_count(struct xfs_ifork *ifp)
+{
+       return ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
+}
+
 /*
  * Convert in-core extents to on-disk form
  *
@@ -803,7 +810,7 @@ xfs_iextents_copy(
        ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED));
        ASSERT(ifp->if_bytes > 0);
 
-       nrecs = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
+       nrecs = xfs_iext_count(ifp);
        XFS_BMAP_TRACE_EXLIST(ip, nrecs, whichfork);
        ASSERT(nrecs > 0);
 
@@ -941,7 +948,7 @@ xfs_iext_get_ext(
        xfs_extnum_t    idx)            /* index of target extent */
 {
        ASSERT(idx >= 0);
-       ASSERT(idx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t));
+       ASSERT(idx < xfs_iext_count(ifp));
 
        if ((ifp->if_flags & XFS_IFEXTIREC) && (idx == 0)) {
                return ifp->if_u1.if_ext_irec->er_extbuf;
@@ -1017,7 +1024,7 @@ xfs_iext_add(
        int             new_size;       /* size of extents after adding */
        xfs_extnum_t    nextents;       /* number of extents in file */
 
-       nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
+       nextents = xfs_iext_count(ifp);
        ASSERT((idx >= 0) && (idx <= nextents));
        byte_diff = ext_diff * sizeof(xfs_bmbt_rec_t);
        new_size = ifp->if_bytes + byte_diff;
@@ -1241,7 +1248,7 @@ xfs_iext_remove(
        trace_xfs_iext_remove(ip, idx, state, _RET_IP_);
 
        ASSERT(ext_diff > 0);
-       nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
+       nextents = xfs_iext_count(ifp);
        new_size = (nextents - ext_diff) * sizeof(xfs_bmbt_rec_t);
 
        if (new_size == 0) {
@@ -1270,7 +1277,7 @@ xfs_iext_remove_inline(
 
        ASSERT(!(ifp->if_flags & XFS_IFEXTIREC));
        ASSERT(idx < XFS_INLINE_EXTS);
-       nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
+       nextents = xfs_iext_count(ifp);
        ASSERT(((nextents - ext_diff) > 0) &&
                (nextents - ext_diff) < XFS_INLINE_EXTS);
 
@@ -1309,7 +1316,7 @@ xfs_iext_remove_direct(
        ASSERT(!(ifp->if_flags & XFS_IFEXTIREC));
        new_size = ifp->if_bytes -
                (ext_diff * sizeof(xfs_bmbt_rec_t));
-       nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
+       nextents = xfs_iext_count(ifp);
 
        if (new_size == 0) {
                xfs_iext_destroy(ifp);
@@ -1546,7 +1553,7 @@ xfs_iext_indirect_to_direct(
        int             size;           /* size of file extents */
 
        ASSERT(ifp->if_flags & XFS_IFEXTIREC);
-       nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
+       nextents = xfs_iext_count(ifp);
        ASSERT(nextents <= XFS_LINEAR_EXTS);
        size = nextents * sizeof(xfs_bmbt_rec_t);
 
@@ -1620,7 +1627,7 @@ xfs_iext_bno_to_ext(
        xfs_extnum_t    nextents;       /* number of file extents */
        xfs_fileoff_t   startoff = 0;   /* start offset of extent */
 
-       nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
+       nextents = xfs_iext_count(ifp);
        if (nextents == 0) {
                *idxp = 0;
                return NULL;
@@ -1733,8 +1740,8 @@ xfs_iext_idx_to_irec(
 
        ASSERT(ifp->if_flags & XFS_IFEXTIREC);
        ASSERT(page_idx >= 0);
-       ASSERT(page_idx <= ifp->if_bytes / sizeof(xfs_bmbt_rec_t));
-       ASSERT(page_idx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t) || realloc);
+       ASSERT(page_idx <= xfs_iext_count(ifp));
+       ASSERT(page_idx < xfs_iext_count(ifp) || realloc);
 
        nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
        erp_idx = 0;
@@ -1782,7 +1789,7 @@ xfs_iext_irec_init(
        xfs_extnum_t    nextents;       /* number of extents in file */
 
        ASSERT(!(ifp->if_flags & XFS_IFEXTIREC));
-       nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
+       nextents = xfs_iext_count(ifp);
        ASSERT(nextents <= XFS_LINEAR_EXTS);
 
        erp = kmem_alloc(sizeof(xfs_ext_irec_t), KM_NOFS);
@@ -1906,7 +1913,7 @@ xfs_iext_irec_compact(
 
        ASSERT(ifp->if_flags & XFS_IFEXTIREC);
        nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
-       nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
+       nextents = xfs_iext_count(ifp);
 
        if (nextents == 0) {
                xfs_iext_destroy(ifp);
@@ -1996,3 +2003,49 @@ xfs_ifork_init_cow(
        ip->i_cformat = XFS_DINODE_FMT_EXTENTS;
        ip->i_cnextents = 0;
 }
+
+/*
+ * Lookup the extent covering bno.
+ *
+ * If there is an extent covering bno return the extent index, and store the
+ * expanded extent structure in *gotp, and the extent index in *idx.
+ * If there is no extent covering bno, but there is an extent after it (e.g.
+ * it lies in a hole) return that extent in *gotp and its index in *idx
+ * instead.
+ * If bno is beyond the last extent return false, and return the index after
+ * the last valid index in *idxp.
+ */
+bool
+xfs_iext_lookup_extent(
+       struct xfs_inode        *ip,
+       struct xfs_ifork        *ifp,
+       xfs_fileoff_t           bno,
+       xfs_extnum_t            *idxp,
+       struct xfs_bmbt_irec    *gotp)
+{
+       struct xfs_bmbt_rec_host *ep;
+
+       XFS_STATS_INC(ip->i_mount, xs_look_exlist);
+
+       ep = xfs_iext_bno_to_ext(ifp, bno, idxp);
+       if (!ep)
+               return false;
+       xfs_bmbt_get_all(ep, gotp);
+       return true;
+}
+
+/*
+ * Return true if there is an extent at index idx, and return the expanded
+ * extent structure at idx in that case.  Else return false.
+ */
+bool
+xfs_iext_get_extent(
+       struct xfs_ifork        *ifp,
+       xfs_extnum_t            idx,
+       struct xfs_bmbt_irec    *gotp)
+{
+       if (idx < 0 || idx >= xfs_iext_count(ifp))
+               return false;
+       xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx), gotp);
+       return true;
+}