Loading fs/xfs/xfs_bmap.c +345 −323 Original line number Diff line number Diff line Loading @@ -2294,25 +2294,15 @@ xfs_bmap_extsize_align( #define XFS_ALLOC_GAP_UNITS 4 /* * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file. * It figures out where to ask the underlying allocator to put the new extent. */ STATIC int xfs_bmap_alloc( xfs_bmap_adjacent( xfs_bmalloca_t *ap) /* bmap alloc argument struct */ { xfs_fsblock_t adjust; /* adjustment to block numbers */ xfs_alloctype_t atype=0; /* type for allocation routines */ int error; /* error return value */ xfs_agnumber_t fb_agno; /* ag number of ap->firstblock */ xfs_mount_t *mp; /* mount point structure */ int nullfb; /* true if ap->firstblock isn't set */ int rt; /* true if inode is realtime */ xfs_extlen_t prod = 0; /* product factor for allocators */ xfs_extlen_t ralen = 0; /* realtime allocation length */ xfs_extlen_t align; /* minimum allocation alignment */ xfs_rtblock_t rtx; #define ISVALID(x,y) \ (rt ? \ Loading @@ -2321,75 +2311,10 @@ xfs_bmap_alloc( XFS_FSB_TO_AGNO(mp, x) < mp->m_sb.sb_agcount && \ XFS_FSB_TO_AGBNO(mp, x) < mp->m_sb.sb_agblocks) /* * Set up variables. */ mp = ap->ip->i_mount; nullfb = ap->firstblock == NULLFSBLOCK; rt = XFS_IS_REALTIME_INODE(ap->ip) && ap->userdata; fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, ap->firstblock); if (rt) { align = ap->ip->i_d.di_extsize ? ap->ip->i_d.di_extsize : mp->m_sb.sb_rextsize; /* Set prod to match the extent size */ prod = align / mp->m_sb.sb_rextsize; error = xfs_bmap_extsize_align(mp, ap->gotp, ap->prevp, align, rt, ap->eof, 0, ap->conv, &ap->off, &ap->alen); if (error) return error; ASSERT(ap->alen); ASSERT(ap->alen % mp->m_sb.sb_rextsize == 0); /* * If the offset & length are not perfectly aligned * then kill prod, it will just get us in trouble. */ if (do_mod(ap->off, align) || ap->alen % align) prod = 1; /* * Set ralen to be the actual requested length in rtextents. */ ralen = ap->alen / mp->m_sb.sb_rextsize; /* * If the old value was close enough to MAXEXTLEN that * we rounded up to it, cut it back so it's valid again. * Note that if it's a really large request (bigger than * MAXEXTLEN), we don't hear about that number, and can't * adjust the starting point to match it. */ if (ralen * mp->m_sb.sb_rextsize >= MAXEXTLEN) ralen = MAXEXTLEN / mp->m_sb.sb_rextsize; /* * If it's an allocation to an empty file at offset 0, * pick an extent that will space things out in the rt area. */ if (ap->eof && ap->off == 0) { error = xfs_rtpick_extent(mp, ap->tp, ralen, &rtx); if (error) return error; ap->rval = rtx * mp->m_sb.sb_rextsize; } else ap->rval = 0; } else { align = (ap->userdata && ap->ip->i_d.di_extsize && (ap->ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE)) ? ap->ip->i_d.di_extsize : 0; if (unlikely(align)) { error = xfs_bmap_extsize_align(mp, ap->gotp, ap->prevp, align, rt, ap->eof, 0, ap->conv, &ap->off, &ap->alen); ASSERT(!error); ASSERT(ap->alen); } if (nullfb) ap->rval = XFS_INO_TO_FSB(mp, ap->ip->i_ino); else ap->rval = ap->firstblock; } /* * If allocating at eof, and there's a previous real block, * try to use it's last block as our starting point. Loading Loading @@ -2514,25 +2439,73 @@ xfs_bmap_alloc( else if (gotbno != NULLFSBLOCK) ap->rval = gotbno; } #undef ISVALID return 0; } STATIC int xfs_bmap_rtalloc( xfs_bmalloca_t *ap) /* bmap alloc argument struct */ { xfs_alloctype_t atype = 0; /* type for allocation routines */ int error; /* error return value */ xfs_mount_t *mp; /* mount point structure */ xfs_extlen_t prod = 0; /* product factor for allocators */ xfs_extlen_t ralen = 0; /* realtime allocation length */ xfs_extlen_t align; /* minimum allocation alignment */ xfs_rtblock_t rtx; /* realtime extent number */ xfs_rtblock_t rtb; mp = ap->ip->i_mount; align = ap->ip->i_d.di_extsize ? ap->ip->i_d.di_extsize : mp->m_sb.sb_rextsize; prod = align / mp->m_sb.sb_rextsize; error = xfs_bmap_extsize_align(mp, ap->gotp, ap->prevp, align, 1, ap->eof, 0, ap->conv, &ap->off, &ap->alen); if (error) return error; ASSERT(ap->alen); ASSERT(ap->alen % mp->m_sb.sb_rextsize == 0); /* * If allowed, use ap->rval; otherwise must use firstblock since * it's in the right allocation group. * If the offset & length are not perfectly aligned * then kill prod, it will just get us in trouble. */ if (nullfb || rt || XFS_FSB_TO_AGNO(mp, ap->rval) == fb_agno) ; else ap->rval = ap->firstblock; if (do_mod(ap->off, align) || ap->alen % align) prod = 1; /* * Realtime allocation, done through xfs_rtallocate_extent. * Set ralen to be the actual requested length in rtextents. */ if (rt) { #ifndef __KERNEL__ ASSERT(0); #else xfs_rtblock_t rtb; ralen = ap->alen / mp->m_sb.sb_rextsize; /* * If the old value was close enough to MAXEXTLEN that * we rounded up to it, cut it back so it's valid again. * Note that if it's a really large request (bigger than * MAXEXTLEN), we don't hear about that number, and can't * adjust the starting point to match it. */ if (ralen * mp->m_sb.sb_rextsize >= MAXEXTLEN) ralen = MAXEXTLEN / mp->m_sb.sb_rextsize; /* * If it's an allocation to an empty file at offset 0, * pick an extent that will space things out in the rt area. */ if (ap->eof && ap->off == 0) { error = xfs_rtpick_extent(mp, ap->tp, ralen, &rtx); if (error) return error; ap->rval = rtx * mp->m_sb.sb_rextsize; } else { ap->rval = 0; } atype = ap->rval == 0 ? XFS_ALLOCTYPE_ANY_AG : XFS_ALLOCTYPE_NEAR_BNO; xfs_bmap_adjacent(ap); /* * Realtime allocation, done through xfs_rtallocate_extent. */ atype = ap->rval == 0 ? XFS_ALLOCTYPE_ANY_AG : XFS_ALLOCTYPE_NEAR_BNO; do_div(ap->rval, mp->m_sb.sb_rextsize); rtb = ap->rval; ap->alen = ralen; Loading @@ -2559,29 +2532,67 @@ xfs_bmap_alloc( */ XFS_TRANS_MOD_DQUOT_BYINO(mp, ap->tp, ap->ip, ap->wasdel ? XFS_TRANS_DQ_DELRTBCOUNT : XFS_TRANS_DQ_RTBCOUNT, (long) ralen); } else XFS_TRANS_DQ_RTBCOUNT, (long) ralen); } else { ap->alen = 0; #endif /* __KERNEL__ */ } /* * Normal allocation, done through xfs_alloc_vextent. */ else { return 0; } STATIC int xfs_bmap_btalloc( xfs_bmalloca_t *ap) /* bmap alloc argument struct */ { xfs_mount_t *mp; /* mount point structure */ xfs_alloctype_t atype = 0; /* type for allocation routines */ xfs_extlen_t align; /* minimum allocation alignment */ xfs_agnumber_t ag; xfs_agnumber_t fb_agno; /* ag number of ap->firstblock */ xfs_agnumber_t startag; xfs_alloc_arg_t args; xfs_extlen_t blen; xfs_extlen_t delta; int isaligned; xfs_extlen_t longest; xfs_extlen_t need; xfs_extlen_t nextminlen = 0; int notinit; xfs_perag_t *pag; xfs_agnumber_t startag; int nullfb; /* true if ap->firstblock isn't set */ int isaligned; int notinit; int tryagain; int error; mp = ap->ip->i_mount; align = (ap->userdata && ap->ip->i_d.di_extsize && (ap->ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE)) ? ap->ip->i_d.di_extsize : 0; if (unlikely(align)) { error = xfs_bmap_extsize_align(mp, ap->gotp, ap->prevp, align, 0, ap->eof, 0, ap->conv, &ap->off, &ap->alen); ASSERT(!error); ASSERT(ap->alen); } nullfb = ap->firstblock == NULLFSBLOCK; fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, ap->firstblock); if (nullfb) ap->rval = XFS_INO_TO_FSB(mp, ap->ip->i_ino); else ap->rval = ap->firstblock; xfs_bmap_adjacent(ap); /* * If allowed, use ap->rval; otherwise must use firstblock since * it's in the right allocation group. */ if (nullfb || XFS_FSB_TO_AGNO(mp, ap->rval) == fb_agno) ; else ap->rval = ap->firstblock; /* * Normal allocation, done through xfs_alloc_vextent. */ tryagain = isaligned = 0; args.tp = ap->tp; args.mp = mp; Loading Loading @@ -2786,9 +2797,20 @@ xfs_bmap_alloc( ap->rval = NULLFSBLOCK; ap->alen = 0; } } return 0; #undef ISVALID } /* * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file. * It figures out where to ask the underlying allocator to put the new extent. */ STATIC int xfs_bmap_alloc( xfs_bmalloca_t *ap) /* bmap alloc argument struct */ { if ((ap->ip->i_d.di_flags & XFS_DIFLAG_REALTIME) && ap->userdata) return xfs_bmap_rtalloc(ap); return xfs_bmap_btalloc(ap); } /* Loading Loading
fs/xfs/xfs_bmap.c +345 −323 Original line number Diff line number Diff line Loading @@ -2294,25 +2294,15 @@ xfs_bmap_extsize_align( #define XFS_ALLOC_GAP_UNITS 4 /* * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file. * It figures out where to ask the underlying allocator to put the new extent. */ STATIC int xfs_bmap_alloc( xfs_bmap_adjacent( xfs_bmalloca_t *ap) /* bmap alloc argument struct */ { xfs_fsblock_t adjust; /* adjustment to block numbers */ xfs_alloctype_t atype=0; /* type for allocation routines */ int error; /* error return value */ xfs_agnumber_t fb_agno; /* ag number of ap->firstblock */ xfs_mount_t *mp; /* mount point structure */ int nullfb; /* true if ap->firstblock isn't set */ int rt; /* true if inode is realtime */ xfs_extlen_t prod = 0; /* product factor for allocators */ xfs_extlen_t ralen = 0; /* realtime allocation length */ xfs_extlen_t align; /* minimum allocation alignment */ xfs_rtblock_t rtx; #define ISVALID(x,y) \ (rt ? \ Loading @@ -2321,75 +2311,10 @@ xfs_bmap_alloc( XFS_FSB_TO_AGNO(mp, x) < mp->m_sb.sb_agcount && \ XFS_FSB_TO_AGBNO(mp, x) < mp->m_sb.sb_agblocks) /* * Set up variables. */ mp = ap->ip->i_mount; nullfb = ap->firstblock == NULLFSBLOCK; rt = XFS_IS_REALTIME_INODE(ap->ip) && ap->userdata; fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, ap->firstblock); if (rt) { align = ap->ip->i_d.di_extsize ? ap->ip->i_d.di_extsize : mp->m_sb.sb_rextsize; /* Set prod to match the extent size */ prod = align / mp->m_sb.sb_rextsize; error = xfs_bmap_extsize_align(mp, ap->gotp, ap->prevp, align, rt, ap->eof, 0, ap->conv, &ap->off, &ap->alen); if (error) return error; ASSERT(ap->alen); ASSERT(ap->alen % mp->m_sb.sb_rextsize == 0); /* * If the offset & length are not perfectly aligned * then kill prod, it will just get us in trouble. */ if (do_mod(ap->off, align) || ap->alen % align) prod = 1; /* * Set ralen to be the actual requested length in rtextents. */ ralen = ap->alen / mp->m_sb.sb_rextsize; /* * If the old value was close enough to MAXEXTLEN that * we rounded up to it, cut it back so it's valid again. * Note that if it's a really large request (bigger than * MAXEXTLEN), we don't hear about that number, and can't * adjust the starting point to match it. */ if (ralen * mp->m_sb.sb_rextsize >= MAXEXTLEN) ralen = MAXEXTLEN / mp->m_sb.sb_rextsize; /* * If it's an allocation to an empty file at offset 0, * pick an extent that will space things out in the rt area. */ if (ap->eof && ap->off == 0) { error = xfs_rtpick_extent(mp, ap->tp, ralen, &rtx); if (error) return error; ap->rval = rtx * mp->m_sb.sb_rextsize; } else ap->rval = 0; } else { align = (ap->userdata && ap->ip->i_d.di_extsize && (ap->ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE)) ? ap->ip->i_d.di_extsize : 0; if (unlikely(align)) { error = xfs_bmap_extsize_align(mp, ap->gotp, ap->prevp, align, rt, ap->eof, 0, ap->conv, &ap->off, &ap->alen); ASSERT(!error); ASSERT(ap->alen); } if (nullfb) ap->rval = XFS_INO_TO_FSB(mp, ap->ip->i_ino); else ap->rval = ap->firstblock; } /* * If allocating at eof, and there's a previous real block, * try to use it's last block as our starting point. Loading Loading @@ -2514,25 +2439,73 @@ xfs_bmap_alloc( else if (gotbno != NULLFSBLOCK) ap->rval = gotbno; } #undef ISVALID return 0; } STATIC int xfs_bmap_rtalloc( xfs_bmalloca_t *ap) /* bmap alloc argument struct */ { xfs_alloctype_t atype = 0; /* type for allocation routines */ int error; /* error return value */ xfs_mount_t *mp; /* mount point structure */ xfs_extlen_t prod = 0; /* product factor for allocators */ xfs_extlen_t ralen = 0; /* realtime allocation length */ xfs_extlen_t align; /* minimum allocation alignment */ xfs_rtblock_t rtx; /* realtime extent number */ xfs_rtblock_t rtb; mp = ap->ip->i_mount; align = ap->ip->i_d.di_extsize ? ap->ip->i_d.di_extsize : mp->m_sb.sb_rextsize; prod = align / mp->m_sb.sb_rextsize; error = xfs_bmap_extsize_align(mp, ap->gotp, ap->prevp, align, 1, ap->eof, 0, ap->conv, &ap->off, &ap->alen); if (error) return error; ASSERT(ap->alen); ASSERT(ap->alen % mp->m_sb.sb_rextsize == 0); /* * If allowed, use ap->rval; otherwise must use firstblock since * it's in the right allocation group. * If the offset & length are not perfectly aligned * then kill prod, it will just get us in trouble. */ if (nullfb || rt || XFS_FSB_TO_AGNO(mp, ap->rval) == fb_agno) ; else ap->rval = ap->firstblock; if (do_mod(ap->off, align) || ap->alen % align) prod = 1; /* * Realtime allocation, done through xfs_rtallocate_extent. * Set ralen to be the actual requested length in rtextents. */ if (rt) { #ifndef __KERNEL__ ASSERT(0); #else xfs_rtblock_t rtb; ralen = ap->alen / mp->m_sb.sb_rextsize; /* * If the old value was close enough to MAXEXTLEN that * we rounded up to it, cut it back so it's valid again. * Note that if it's a really large request (bigger than * MAXEXTLEN), we don't hear about that number, and can't * adjust the starting point to match it. */ if (ralen * mp->m_sb.sb_rextsize >= MAXEXTLEN) ralen = MAXEXTLEN / mp->m_sb.sb_rextsize; /* * If it's an allocation to an empty file at offset 0, * pick an extent that will space things out in the rt area. */ if (ap->eof && ap->off == 0) { error = xfs_rtpick_extent(mp, ap->tp, ralen, &rtx); if (error) return error; ap->rval = rtx * mp->m_sb.sb_rextsize; } else { ap->rval = 0; } atype = ap->rval == 0 ? XFS_ALLOCTYPE_ANY_AG : XFS_ALLOCTYPE_NEAR_BNO; xfs_bmap_adjacent(ap); /* * Realtime allocation, done through xfs_rtallocate_extent. */ atype = ap->rval == 0 ? XFS_ALLOCTYPE_ANY_AG : XFS_ALLOCTYPE_NEAR_BNO; do_div(ap->rval, mp->m_sb.sb_rextsize); rtb = ap->rval; ap->alen = ralen; Loading @@ -2559,29 +2532,67 @@ xfs_bmap_alloc( */ XFS_TRANS_MOD_DQUOT_BYINO(mp, ap->tp, ap->ip, ap->wasdel ? XFS_TRANS_DQ_DELRTBCOUNT : XFS_TRANS_DQ_RTBCOUNT, (long) ralen); } else XFS_TRANS_DQ_RTBCOUNT, (long) ralen); } else { ap->alen = 0; #endif /* __KERNEL__ */ } /* * Normal allocation, done through xfs_alloc_vextent. */ else { return 0; } STATIC int xfs_bmap_btalloc( xfs_bmalloca_t *ap) /* bmap alloc argument struct */ { xfs_mount_t *mp; /* mount point structure */ xfs_alloctype_t atype = 0; /* type for allocation routines */ xfs_extlen_t align; /* minimum allocation alignment */ xfs_agnumber_t ag; xfs_agnumber_t fb_agno; /* ag number of ap->firstblock */ xfs_agnumber_t startag; xfs_alloc_arg_t args; xfs_extlen_t blen; xfs_extlen_t delta; int isaligned; xfs_extlen_t longest; xfs_extlen_t need; xfs_extlen_t nextminlen = 0; int notinit; xfs_perag_t *pag; xfs_agnumber_t startag; int nullfb; /* true if ap->firstblock isn't set */ int isaligned; int notinit; int tryagain; int error; mp = ap->ip->i_mount; align = (ap->userdata && ap->ip->i_d.di_extsize && (ap->ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE)) ? ap->ip->i_d.di_extsize : 0; if (unlikely(align)) { error = xfs_bmap_extsize_align(mp, ap->gotp, ap->prevp, align, 0, ap->eof, 0, ap->conv, &ap->off, &ap->alen); ASSERT(!error); ASSERT(ap->alen); } nullfb = ap->firstblock == NULLFSBLOCK; fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, ap->firstblock); if (nullfb) ap->rval = XFS_INO_TO_FSB(mp, ap->ip->i_ino); else ap->rval = ap->firstblock; xfs_bmap_adjacent(ap); /* * If allowed, use ap->rval; otherwise must use firstblock since * it's in the right allocation group. */ if (nullfb || XFS_FSB_TO_AGNO(mp, ap->rval) == fb_agno) ; else ap->rval = ap->firstblock; /* * Normal allocation, done through xfs_alloc_vextent. */ tryagain = isaligned = 0; args.tp = ap->tp; args.mp = mp; Loading Loading @@ -2786,9 +2797,20 @@ xfs_bmap_alloc( ap->rval = NULLFSBLOCK; ap->alen = 0; } } return 0; #undef ISVALID } /* * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file. * It figures out where to ask the underlying allocator to put the new extent. */ STATIC int xfs_bmap_alloc( xfs_bmalloca_t *ap) /* bmap alloc argument struct */ { if ((ap->ip->i_d.di_flags & XFS_DIFLAG_REALTIME) && ap->userdata) return xfs_bmap_rtalloc(ap); return xfs_bmap_btalloc(ap); } /* Loading