Loading fs/dax.c +5 −0 Original line number Original line Diff line number Diff line Loading @@ -29,6 +29,11 @@ #include <linux/uio.h> #include <linux/uio.h> #include <linux/vmstat.h> #include <linux/vmstat.h> /* * dax_clear_blocks() is called from within transaction context from XFS, * and hence this means the stack from this point must follow GFP_NOFS * semantics for all operations. */ int dax_clear_blocks(struct inode *inode, sector_t block, long size) int dax_clear_blocks(struct inode *inode, sector_t block, long size) { { struct block_device *bdev = inode->i_sb->s_bdev; struct block_device *bdev = inode->i_sb->s_bdev; Loading fs/xfs/libxfs/xfs_alloc.c +9 −1 Original line number Original line Diff line number Diff line Loading @@ -2509,7 +2509,7 @@ xfs_alloc_vextent( * Try near allocation first, then anywhere-in-ag after * Try near allocation first, then anywhere-in-ag after * the first a.g. fails. * the first a.g. fails. */ */ if ((args->userdata == XFS_ALLOC_INITIAL_USER_DATA) && if ((args->userdata & XFS_ALLOC_INITIAL_USER_DATA) && (mp->m_flags & XFS_MOUNT_32BITINODES)) { (mp->m_flags & XFS_MOUNT_32BITINODES)) { args->fsbno = XFS_AGB_TO_FSB(mp, args->fsbno = XFS_AGB_TO_FSB(mp, ((mp->m_agfrotor / rotorstep) % ((mp->m_agfrotor / rotorstep) % Loading Loading @@ -2640,6 +2640,14 @@ xfs_alloc_vextent( XFS_AG_CHECK_DADDR(mp, XFS_FSB_TO_DADDR(mp, args->fsbno), XFS_AG_CHECK_DADDR(mp, XFS_FSB_TO_DADDR(mp, args->fsbno), args->len); args->len); #endif #endif /* Zero the extent if we were asked to do so */ if (args->userdata & XFS_ALLOC_USERDATA_ZERO) { error = xfs_zero_extent(args->ip, args->fsbno, args->len); if (error) goto error0; } } } xfs_perag_put(args->pag); xfs_perag_put(args->pag); return 0; return 0; Loading fs/xfs/libxfs/xfs_alloc.h +5 −3 Original line number Original line Diff line number Diff line Loading @@ -101,6 +101,7 @@ typedef struct xfs_alloc_arg { struct xfs_mount *mp; /* file system mount point */ struct xfs_mount *mp; /* file system mount point */ struct xfs_buf *agbp; /* buffer for a.g. freelist header */ struct xfs_buf *agbp; /* buffer for a.g. freelist header */ struct xfs_perag *pag; /* per-ag struct for this agno */ struct xfs_perag *pag; /* per-ag struct for this agno */ struct xfs_inode *ip; /* for userdata zeroing method */ xfs_fsblock_t fsbno; /* file system block number */ xfs_fsblock_t fsbno; /* file system block number */ xfs_agnumber_t agno; /* allocation group number */ xfs_agnumber_t agno; /* allocation group number */ xfs_agblock_t agbno; /* allocation group-relative block # */ xfs_agblock_t agbno; /* allocation group-relative block # */ Loading @@ -120,15 +121,16 @@ typedef struct xfs_alloc_arg { char wasdel; /* set if allocation was prev delayed */ char wasdel; /* set if allocation was prev delayed */ char wasfromfl; /* set if allocation is from freelist */ char wasfromfl; /* set if allocation is from freelist */ char isfl; /* set if is freelist blocks - !acctg */ char isfl; /* set if is freelist blocks - !acctg */ char userdata; /* set if this is user data */ char userdata; /* mask defining userdata treatment */ xfs_fsblock_t firstblock; /* io first block allocated */ xfs_fsblock_t firstblock; /* io first block allocated */ } xfs_alloc_arg_t; } xfs_alloc_arg_t; /* /* * Defines for userdata * Defines for userdata */ */ #define XFS_ALLOC_USERDATA 1 /* allocation is for user data*/ #define XFS_ALLOC_USERDATA (1 << 0)/* allocation is for user data*/ #define XFS_ALLOC_INITIAL_USER_DATA 2 /* special case start of file */ #define XFS_ALLOC_INITIAL_USER_DATA (1 << 1)/* special case start of file */ #define XFS_ALLOC_USERDATA_ZERO (1 << 2)/* zero extent on allocation */ xfs_extlen_t xfs_alloc_longest_free_extent(struct xfs_mount *mp, xfs_extlen_t xfs_alloc_longest_free_extent(struct xfs_mount *mp, struct xfs_perag *pag, xfs_extlen_t need); struct xfs_perag *pag, xfs_extlen_t need); Loading fs/xfs/libxfs/xfs_bmap.c +33 −2 Original line number Original line Diff line number Diff line Loading @@ -3802,8 +3802,13 @@ xfs_bmap_btalloc( args.wasdel = ap->wasdel; args.wasdel = ap->wasdel; args.isfl = 0; args.isfl = 0; args.userdata = ap->userdata; args.userdata = ap->userdata; if ((error = xfs_alloc_vextent(&args))) if (ap->userdata & XFS_ALLOC_USERDATA_ZERO) args.ip = ap->ip; error = xfs_alloc_vextent(&args); if (error) return error; return error; if (tryagain && args.fsbno == NULLFSBLOCK) { if (tryagain && args.fsbno == NULLFSBLOCK) { /* /* * Exact allocation failed. Now try with alignment * Exact allocation failed. Now try with alignment Loading Loading @@ -4302,11 +4307,14 @@ xfs_bmapi_allocate( /* /* * Indicate if this is the first user data in the file, or just any * Indicate if this is the first user data in the file, or just any * user data. * user data. And if it is userdata, indicate whether it needs to * be initialised to zero during allocation. */ */ if (!(bma->flags & XFS_BMAPI_METADATA)) { if (!(bma->flags & XFS_BMAPI_METADATA)) { bma->userdata = (bma->offset == 0) ? bma->userdata = (bma->offset == 0) ? XFS_ALLOC_INITIAL_USER_DATA : XFS_ALLOC_USERDATA; XFS_ALLOC_INITIAL_USER_DATA : XFS_ALLOC_USERDATA; if (bma->flags & XFS_BMAPI_ZERO) bma->userdata |= XFS_ALLOC_USERDATA_ZERO; } } bma->minlen = (bma->flags & XFS_BMAPI_CONTIG) ? bma->length : 1; bma->minlen = (bma->flags & XFS_BMAPI_CONTIG) ? bma->length : 1; Loading Loading @@ -4421,6 +4429,17 @@ xfs_bmapi_convert_unwritten( mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN) mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN) ? XFS_EXT_NORM : XFS_EXT_UNWRITTEN; ? XFS_EXT_NORM : XFS_EXT_UNWRITTEN; /* * Before insertion into the bmbt, zero the range being converted * if required. */ if (flags & XFS_BMAPI_ZERO) { error = xfs_zero_extent(bma->ip, mval->br_startblock, mval->br_blockcount); if (error) return error; } error = xfs_bmap_add_extent_unwritten_real(bma->tp, bma->ip, &bma->idx, error = xfs_bmap_add_extent_unwritten_real(bma->tp, bma->ip, &bma->idx, &bma->cur, mval, bma->firstblock, bma->flist, &bma->cur, mval, bma->firstblock, bma->flist, &tmp_logflags); &tmp_logflags); Loading Loading @@ -4514,6 +4533,18 @@ xfs_bmapi_write( ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL); ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL); ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); /* zeroing is for currently only for data extents, not metadata */ ASSERT((flags & (XFS_BMAPI_METADATA | XFS_BMAPI_ZERO)) != (XFS_BMAPI_METADATA | XFS_BMAPI_ZERO)); /* * we can allocate unwritten extents or pre-zero allocated blocks, * but it makes no sense to do both at once. This would result in * zeroing the unwritten extent twice, but it still being an * unwritten extent.... */ ASSERT((flags & (XFS_BMAPI_PREALLOC | XFS_BMAPI_ZERO)) != (XFS_BMAPI_PREALLOC | XFS_BMAPI_ZERO)); if (unlikely(XFS_TEST_ERROR( if (unlikely(XFS_TEST_ERROR( (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE), XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE), Loading fs/xfs/libxfs/xfs_bmap.h +11 −2 Original line number Original line Diff line number Diff line Loading @@ -52,9 +52,9 @@ struct xfs_bmalloca { xfs_extlen_t minleft; /* amount must be left after alloc */ xfs_extlen_t minleft; /* amount must be left after alloc */ bool eof; /* set if allocating past last extent */ bool eof; /* set if allocating past last extent */ bool wasdel; /* replacing a delayed allocation */ bool wasdel; /* replacing a delayed allocation */ bool userdata;/* set if is user data */ bool aeof; /* allocated space at eof */ bool aeof; /* allocated space at eof */ bool conv; /* overwriting unwritten extents */ bool conv; /* overwriting unwritten extents */ char userdata;/* userdata mask */ int flags; int flags; }; }; Loading Loading @@ -109,6 +109,14 @@ typedef struct xfs_bmap_free */ */ #define XFS_BMAPI_CONVERT 0x040 #define XFS_BMAPI_CONVERT 0x040 /* * allocate zeroed extents - this requires all newly allocated user data extents * to be initialised to zero. It will be ignored if XFS_BMAPI_METADATA is set. * Use in conjunction with XFS_BMAPI_CONVERT to convert unwritten extents found * during the allocation range to zeroed written extents. */ #define XFS_BMAPI_ZERO 0x080 #define XFS_BMAPI_FLAGS \ #define XFS_BMAPI_FLAGS \ { XFS_BMAPI_ENTIRE, "ENTIRE" }, \ { XFS_BMAPI_ENTIRE, "ENTIRE" }, \ { XFS_BMAPI_METADATA, "METADATA" }, \ { XFS_BMAPI_METADATA, "METADATA" }, \ Loading @@ -116,7 +124,8 @@ typedef struct xfs_bmap_free { XFS_BMAPI_PREALLOC, "PREALLOC" }, \ { XFS_BMAPI_PREALLOC, "PREALLOC" }, \ { XFS_BMAPI_IGSTATE, "IGSTATE" }, \ { XFS_BMAPI_IGSTATE, "IGSTATE" }, \ { XFS_BMAPI_CONTIG, "CONTIG" }, \ { XFS_BMAPI_CONTIG, "CONTIG" }, \ { XFS_BMAPI_CONVERT, "CONVERT" } { XFS_BMAPI_CONVERT, "CONVERT" }, \ { XFS_BMAPI_ZERO, "ZERO" } static inline int xfs_bmapi_aflag(int w) static inline int xfs_bmapi_aflag(int w) Loading Loading
fs/dax.c +5 −0 Original line number Original line Diff line number Diff line Loading @@ -29,6 +29,11 @@ #include <linux/uio.h> #include <linux/uio.h> #include <linux/vmstat.h> #include <linux/vmstat.h> /* * dax_clear_blocks() is called from within transaction context from XFS, * and hence this means the stack from this point must follow GFP_NOFS * semantics for all operations. */ int dax_clear_blocks(struct inode *inode, sector_t block, long size) int dax_clear_blocks(struct inode *inode, sector_t block, long size) { { struct block_device *bdev = inode->i_sb->s_bdev; struct block_device *bdev = inode->i_sb->s_bdev; Loading
fs/xfs/libxfs/xfs_alloc.c +9 −1 Original line number Original line Diff line number Diff line Loading @@ -2509,7 +2509,7 @@ xfs_alloc_vextent( * Try near allocation first, then anywhere-in-ag after * Try near allocation first, then anywhere-in-ag after * the first a.g. fails. * the first a.g. fails. */ */ if ((args->userdata == XFS_ALLOC_INITIAL_USER_DATA) && if ((args->userdata & XFS_ALLOC_INITIAL_USER_DATA) && (mp->m_flags & XFS_MOUNT_32BITINODES)) { (mp->m_flags & XFS_MOUNT_32BITINODES)) { args->fsbno = XFS_AGB_TO_FSB(mp, args->fsbno = XFS_AGB_TO_FSB(mp, ((mp->m_agfrotor / rotorstep) % ((mp->m_agfrotor / rotorstep) % Loading Loading @@ -2640,6 +2640,14 @@ xfs_alloc_vextent( XFS_AG_CHECK_DADDR(mp, XFS_FSB_TO_DADDR(mp, args->fsbno), XFS_AG_CHECK_DADDR(mp, XFS_FSB_TO_DADDR(mp, args->fsbno), args->len); args->len); #endif #endif /* Zero the extent if we were asked to do so */ if (args->userdata & XFS_ALLOC_USERDATA_ZERO) { error = xfs_zero_extent(args->ip, args->fsbno, args->len); if (error) goto error0; } } } xfs_perag_put(args->pag); xfs_perag_put(args->pag); return 0; return 0; Loading
fs/xfs/libxfs/xfs_alloc.h +5 −3 Original line number Original line Diff line number Diff line Loading @@ -101,6 +101,7 @@ typedef struct xfs_alloc_arg { struct xfs_mount *mp; /* file system mount point */ struct xfs_mount *mp; /* file system mount point */ struct xfs_buf *agbp; /* buffer for a.g. freelist header */ struct xfs_buf *agbp; /* buffer for a.g. freelist header */ struct xfs_perag *pag; /* per-ag struct for this agno */ struct xfs_perag *pag; /* per-ag struct for this agno */ struct xfs_inode *ip; /* for userdata zeroing method */ xfs_fsblock_t fsbno; /* file system block number */ xfs_fsblock_t fsbno; /* file system block number */ xfs_agnumber_t agno; /* allocation group number */ xfs_agnumber_t agno; /* allocation group number */ xfs_agblock_t agbno; /* allocation group-relative block # */ xfs_agblock_t agbno; /* allocation group-relative block # */ Loading @@ -120,15 +121,16 @@ typedef struct xfs_alloc_arg { char wasdel; /* set if allocation was prev delayed */ char wasdel; /* set if allocation was prev delayed */ char wasfromfl; /* set if allocation is from freelist */ char wasfromfl; /* set if allocation is from freelist */ char isfl; /* set if is freelist blocks - !acctg */ char isfl; /* set if is freelist blocks - !acctg */ char userdata; /* set if this is user data */ char userdata; /* mask defining userdata treatment */ xfs_fsblock_t firstblock; /* io first block allocated */ xfs_fsblock_t firstblock; /* io first block allocated */ } xfs_alloc_arg_t; } xfs_alloc_arg_t; /* /* * Defines for userdata * Defines for userdata */ */ #define XFS_ALLOC_USERDATA 1 /* allocation is for user data*/ #define XFS_ALLOC_USERDATA (1 << 0)/* allocation is for user data*/ #define XFS_ALLOC_INITIAL_USER_DATA 2 /* special case start of file */ #define XFS_ALLOC_INITIAL_USER_DATA (1 << 1)/* special case start of file */ #define XFS_ALLOC_USERDATA_ZERO (1 << 2)/* zero extent on allocation */ xfs_extlen_t xfs_alloc_longest_free_extent(struct xfs_mount *mp, xfs_extlen_t xfs_alloc_longest_free_extent(struct xfs_mount *mp, struct xfs_perag *pag, xfs_extlen_t need); struct xfs_perag *pag, xfs_extlen_t need); Loading
fs/xfs/libxfs/xfs_bmap.c +33 −2 Original line number Original line Diff line number Diff line Loading @@ -3802,8 +3802,13 @@ xfs_bmap_btalloc( args.wasdel = ap->wasdel; args.wasdel = ap->wasdel; args.isfl = 0; args.isfl = 0; args.userdata = ap->userdata; args.userdata = ap->userdata; if ((error = xfs_alloc_vextent(&args))) if (ap->userdata & XFS_ALLOC_USERDATA_ZERO) args.ip = ap->ip; error = xfs_alloc_vextent(&args); if (error) return error; return error; if (tryagain && args.fsbno == NULLFSBLOCK) { if (tryagain && args.fsbno == NULLFSBLOCK) { /* /* * Exact allocation failed. Now try with alignment * Exact allocation failed. Now try with alignment Loading Loading @@ -4302,11 +4307,14 @@ xfs_bmapi_allocate( /* /* * Indicate if this is the first user data in the file, or just any * Indicate if this is the first user data in the file, or just any * user data. * user data. And if it is userdata, indicate whether it needs to * be initialised to zero during allocation. */ */ if (!(bma->flags & XFS_BMAPI_METADATA)) { if (!(bma->flags & XFS_BMAPI_METADATA)) { bma->userdata = (bma->offset == 0) ? bma->userdata = (bma->offset == 0) ? XFS_ALLOC_INITIAL_USER_DATA : XFS_ALLOC_USERDATA; XFS_ALLOC_INITIAL_USER_DATA : XFS_ALLOC_USERDATA; if (bma->flags & XFS_BMAPI_ZERO) bma->userdata |= XFS_ALLOC_USERDATA_ZERO; } } bma->minlen = (bma->flags & XFS_BMAPI_CONTIG) ? bma->length : 1; bma->minlen = (bma->flags & XFS_BMAPI_CONTIG) ? bma->length : 1; Loading Loading @@ -4421,6 +4429,17 @@ xfs_bmapi_convert_unwritten( mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN) mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN) ? XFS_EXT_NORM : XFS_EXT_UNWRITTEN; ? XFS_EXT_NORM : XFS_EXT_UNWRITTEN; /* * Before insertion into the bmbt, zero the range being converted * if required. */ if (flags & XFS_BMAPI_ZERO) { error = xfs_zero_extent(bma->ip, mval->br_startblock, mval->br_blockcount); if (error) return error; } error = xfs_bmap_add_extent_unwritten_real(bma->tp, bma->ip, &bma->idx, error = xfs_bmap_add_extent_unwritten_real(bma->tp, bma->ip, &bma->idx, &bma->cur, mval, bma->firstblock, bma->flist, &bma->cur, mval, bma->firstblock, bma->flist, &tmp_logflags); &tmp_logflags); Loading Loading @@ -4514,6 +4533,18 @@ xfs_bmapi_write( ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL); ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL); ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); /* zeroing is for currently only for data extents, not metadata */ ASSERT((flags & (XFS_BMAPI_METADATA | XFS_BMAPI_ZERO)) != (XFS_BMAPI_METADATA | XFS_BMAPI_ZERO)); /* * we can allocate unwritten extents or pre-zero allocated blocks, * but it makes no sense to do both at once. This would result in * zeroing the unwritten extent twice, but it still being an * unwritten extent.... */ ASSERT((flags & (XFS_BMAPI_PREALLOC | XFS_BMAPI_ZERO)) != (XFS_BMAPI_PREALLOC | XFS_BMAPI_ZERO)); if (unlikely(XFS_TEST_ERROR( if (unlikely(XFS_TEST_ERROR( (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE), XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE), Loading
fs/xfs/libxfs/xfs_bmap.h +11 −2 Original line number Original line Diff line number Diff line Loading @@ -52,9 +52,9 @@ struct xfs_bmalloca { xfs_extlen_t minleft; /* amount must be left after alloc */ xfs_extlen_t minleft; /* amount must be left after alloc */ bool eof; /* set if allocating past last extent */ bool eof; /* set if allocating past last extent */ bool wasdel; /* replacing a delayed allocation */ bool wasdel; /* replacing a delayed allocation */ bool userdata;/* set if is user data */ bool aeof; /* allocated space at eof */ bool aeof; /* allocated space at eof */ bool conv; /* overwriting unwritten extents */ bool conv; /* overwriting unwritten extents */ char userdata;/* userdata mask */ int flags; int flags; }; }; Loading Loading @@ -109,6 +109,14 @@ typedef struct xfs_bmap_free */ */ #define XFS_BMAPI_CONVERT 0x040 #define XFS_BMAPI_CONVERT 0x040 /* * allocate zeroed extents - this requires all newly allocated user data extents * to be initialised to zero. It will be ignored if XFS_BMAPI_METADATA is set. * Use in conjunction with XFS_BMAPI_CONVERT to convert unwritten extents found * during the allocation range to zeroed written extents. */ #define XFS_BMAPI_ZERO 0x080 #define XFS_BMAPI_FLAGS \ #define XFS_BMAPI_FLAGS \ { XFS_BMAPI_ENTIRE, "ENTIRE" }, \ { XFS_BMAPI_ENTIRE, "ENTIRE" }, \ { XFS_BMAPI_METADATA, "METADATA" }, \ { XFS_BMAPI_METADATA, "METADATA" }, \ Loading @@ -116,7 +124,8 @@ typedef struct xfs_bmap_free { XFS_BMAPI_PREALLOC, "PREALLOC" }, \ { XFS_BMAPI_PREALLOC, "PREALLOC" }, \ { XFS_BMAPI_IGSTATE, "IGSTATE" }, \ { XFS_BMAPI_IGSTATE, "IGSTATE" }, \ { XFS_BMAPI_CONTIG, "CONTIG" }, \ { XFS_BMAPI_CONTIG, "CONTIG" }, \ { XFS_BMAPI_CONVERT, "CONVERT" } { XFS_BMAPI_CONVERT, "CONVERT" }, \ { XFS_BMAPI_ZERO, "ZERO" } static inline int xfs_bmapi_aflag(int w) static inline int xfs_bmapi_aflag(int w) Loading