|
@@ -141,7 +141,8 @@ xfs_bmbt_lookup_ge(
|
|
*/
|
|
*/
|
|
static inline bool xfs_bmap_needs_btree(struct xfs_inode *ip, int whichfork)
|
|
static inline bool xfs_bmap_needs_btree(struct xfs_inode *ip, int whichfork)
|
|
{
|
|
{
|
|
- return XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS &&
|
|
|
|
|
|
+ return whichfork != XFS_COW_FORK &&
|
|
|
|
+ XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS &&
|
|
XFS_IFORK_NEXTENTS(ip, whichfork) >
|
|
XFS_IFORK_NEXTENTS(ip, whichfork) >
|
|
XFS_IFORK_MAXEXT(ip, whichfork);
|
|
XFS_IFORK_MAXEXT(ip, whichfork);
|
|
}
|
|
}
|
|
@@ -151,7 +152,8 @@ static inline bool xfs_bmap_needs_btree(struct xfs_inode *ip, int whichfork)
|
|
*/
|
|
*/
|
|
static inline bool xfs_bmap_wants_extents(struct xfs_inode *ip, int whichfork)
|
|
static inline bool xfs_bmap_wants_extents(struct xfs_inode *ip, int whichfork)
|
|
{
|
|
{
|
|
- return XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE &&
|
|
|
|
|
|
+ return whichfork != XFS_COW_FORK &&
|
|
|
|
+ XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE &&
|
|
XFS_IFORK_NEXTENTS(ip, whichfork) <=
|
|
XFS_IFORK_NEXTENTS(ip, whichfork) <=
|
|
XFS_IFORK_MAXEXT(ip, whichfork);
|
|
XFS_IFORK_MAXEXT(ip, whichfork);
|
|
}
|
|
}
|
|
@@ -641,6 +643,7 @@ xfs_bmap_btree_to_extents(
|
|
|
|
|
|
mp = ip->i_mount;
|
|
mp = ip->i_mount;
|
|
ifp = XFS_IFORK_PTR(ip, whichfork);
|
|
ifp = XFS_IFORK_PTR(ip, whichfork);
|
|
|
|
+ ASSERT(whichfork != XFS_COW_FORK);
|
|
ASSERT(ifp->if_flags & XFS_IFEXTENTS);
|
|
ASSERT(ifp->if_flags & XFS_IFEXTENTS);
|
|
ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE);
|
|
ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE);
|
|
rblock = ifp->if_broot;
|
|
rblock = ifp->if_broot;
|
|
@@ -707,6 +710,7 @@ xfs_bmap_extents_to_btree(
|
|
xfs_bmbt_ptr_t *pp; /* root block address pointer */
|
|
xfs_bmbt_ptr_t *pp; /* root block address pointer */
|
|
|
|
|
|
mp = ip->i_mount;
|
|
mp = ip->i_mount;
|
|
|
|
+ ASSERT(whichfork != XFS_COW_FORK);
|
|
ifp = XFS_IFORK_PTR(ip, whichfork);
|
|
ifp = XFS_IFORK_PTR(ip, whichfork);
|
|
ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS);
|
|
ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS);
|
|
|
|
|
|
@@ -838,6 +842,7 @@ xfs_bmap_local_to_extents_empty(
|
|
{
|
|
{
|
|
struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
|
|
struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
|
|
|
|
|
|
|
|
+ ASSERT(whichfork != XFS_COW_FORK);
|
|
ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL);
|
|
ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL);
|
|
ASSERT(ifp->if_bytes == 0);
|
|
ASSERT(ifp->if_bytes == 0);
|
|
ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) == 0);
|
|
ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) == 0);
|
|
@@ -1671,7 +1676,8 @@ xfs_bmap_one_block(
|
|
*/
|
|
*/
|
|
STATIC int /* error */
|
|
STATIC int /* error */
|
|
xfs_bmap_add_extent_delay_real(
|
|
xfs_bmap_add_extent_delay_real(
|
|
- struct xfs_bmalloca *bma)
|
|
|
|
|
|
+ struct xfs_bmalloca *bma,
|
|
|
|
+ int whichfork)
|
|
{
|
|
{
|
|
struct xfs_bmbt_irec *new = &bma->got;
|
|
struct xfs_bmbt_irec *new = &bma->got;
|
|
int diff; /* temp value */
|
|
int diff; /* temp value */
|
|
@@ -1689,11 +1695,14 @@ xfs_bmap_add_extent_delay_real(
|
|
xfs_filblks_t temp=0; /* value for da_new calculations */
|
|
xfs_filblks_t temp=0; /* value for da_new calculations */
|
|
xfs_filblks_t temp2=0;/* value for da_new calculations */
|
|
xfs_filblks_t temp2=0;/* value for da_new calculations */
|
|
int tmp_rval; /* partial logging flags */
|
|
int tmp_rval; /* partial logging flags */
|
|
- int whichfork = XFS_DATA_FORK;
|
|
|
|
struct xfs_mount *mp;
|
|
struct xfs_mount *mp;
|
|
|
|
+ xfs_extnum_t *nextents;
|
|
|
|
|
|
mp = bma->ip->i_mount;
|
|
mp = bma->ip->i_mount;
|
|
ifp = XFS_IFORK_PTR(bma->ip, whichfork);
|
|
ifp = XFS_IFORK_PTR(bma->ip, whichfork);
|
|
|
|
+ ASSERT(whichfork != XFS_ATTR_FORK);
|
|
|
|
+ nextents = (whichfork == XFS_COW_FORK ? &bma->ip->i_cnextents :
|
|
|
|
+ &bma->ip->i_d.di_nextents);
|
|
|
|
|
|
ASSERT(bma->idx >= 0);
|
|
ASSERT(bma->idx >= 0);
|
|
ASSERT(bma->idx <= ifp->if_bytes / sizeof(struct xfs_bmbt_rec));
|
|
ASSERT(bma->idx <= ifp->if_bytes / sizeof(struct xfs_bmbt_rec));
|
|
@@ -1707,6 +1716,9 @@ xfs_bmap_add_extent_delay_real(
|
|
#define RIGHT r[1]
|
|
#define RIGHT r[1]
|
|
#define PREV r[2]
|
|
#define PREV r[2]
|
|
|
|
|
|
|
|
+ if (whichfork == XFS_COW_FORK)
|
|
|
|
+ state |= BMAP_COWFORK;
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* Set up a bunch of variables to make the tests simpler.
|
|
* Set up a bunch of variables to make the tests simpler.
|
|
*/
|
|
*/
|
|
@@ -1793,7 +1805,7 @@ xfs_bmap_add_extent_delay_real(
|
|
trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_);
|
|
trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_);
|
|
|
|
|
|
xfs_iext_remove(bma->ip, bma->idx + 1, 2, state);
|
|
xfs_iext_remove(bma->ip, bma->idx + 1, 2, state);
|
|
- bma->ip->i_d.di_nextents--;
|
|
|
|
|
|
+ (*nextents)--;
|
|
if (bma->cur == NULL)
|
|
if (bma->cur == NULL)
|
|
rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
|
|
rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
|
|
else {
|
|
else {
|
|
@@ -1895,7 +1907,7 @@ xfs_bmap_add_extent_delay_real(
|
|
xfs_bmbt_set_startblock(ep, new->br_startblock);
|
|
xfs_bmbt_set_startblock(ep, new->br_startblock);
|
|
trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_);
|
|
trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_);
|
|
|
|
|
|
- bma->ip->i_d.di_nextents++;
|
|
|
|
|
|
+ (*nextents)++;
|
|
if (bma->cur == NULL)
|
|
if (bma->cur == NULL)
|
|
rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
|
|
rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
|
|
else {
|
|
else {
|
|
@@ -1965,7 +1977,7 @@ xfs_bmap_add_extent_delay_real(
|
|
temp = PREV.br_blockcount - new->br_blockcount;
|
|
temp = PREV.br_blockcount - new->br_blockcount;
|
|
xfs_bmbt_set_blockcount(ep, temp);
|
|
xfs_bmbt_set_blockcount(ep, temp);
|
|
xfs_iext_insert(bma->ip, bma->idx, 1, new, state);
|
|
xfs_iext_insert(bma->ip, bma->idx, 1, new, state);
|
|
- bma->ip->i_d.di_nextents++;
|
|
|
|
|
|
+ (*nextents)++;
|
|
if (bma->cur == NULL)
|
|
if (bma->cur == NULL)
|
|
rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
|
|
rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
|
|
else {
|
|
else {
|
|
@@ -2049,7 +2061,7 @@ xfs_bmap_add_extent_delay_real(
|
|
trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_);
|
|
trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_);
|
|
xfs_bmbt_set_blockcount(ep, temp);
|
|
xfs_bmbt_set_blockcount(ep, temp);
|
|
xfs_iext_insert(bma->ip, bma->idx + 1, 1, new, state);
|
|
xfs_iext_insert(bma->ip, bma->idx + 1, 1, new, state);
|
|
- bma->ip->i_d.di_nextents++;
|
|
|
|
|
|
+ (*nextents)++;
|
|
if (bma->cur == NULL)
|
|
if (bma->cur == NULL)
|
|
rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
|
|
rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
|
|
else {
|
|
else {
|
|
@@ -2118,7 +2130,7 @@ xfs_bmap_add_extent_delay_real(
|
|
RIGHT.br_blockcount = temp2;
|
|
RIGHT.br_blockcount = temp2;
|
|
/* insert LEFT (r[0]) and RIGHT (r[1]) at the same time */
|
|
/* insert LEFT (r[0]) and RIGHT (r[1]) at the same time */
|
|
xfs_iext_insert(bma->ip, bma->idx + 1, 2, &LEFT, state);
|
|
xfs_iext_insert(bma->ip, bma->idx + 1, 2, &LEFT, state);
|
|
- bma->ip->i_d.di_nextents++;
|
|
|
|
|
|
+ (*nextents)++;
|
|
if (bma->cur == NULL)
|
|
if (bma->cur == NULL)
|
|
rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
|
|
rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
|
|
else {
|
|
else {
|
|
@@ -2216,7 +2228,8 @@ xfs_bmap_add_extent_delay_real(
|
|
|
|
|
|
xfs_bmap_check_leaf_extents(bma->cur, bma->ip, whichfork);
|
|
xfs_bmap_check_leaf_extents(bma->cur, bma->ip, whichfork);
|
|
done:
|
|
done:
|
|
- bma->logflags |= rval;
|
|
|
|
|
|
+ if (whichfork != XFS_COW_FORK)
|
|
|
|
+ bma->logflags |= rval;
|
|
return error;
|
|
return error;
|
|
#undef LEFT
|
|
#undef LEFT
|
|
#undef RIGHT
|
|
#undef RIGHT
|
|
@@ -3861,7 +3874,8 @@ xfs_bmap_btalloc(
|
|
ASSERT(nullfb || fb_agno == args.agno ||
|
|
ASSERT(nullfb || fb_agno == args.agno ||
|
|
(ap->dfops->dop_low && fb_agno < args.agno));
|
|
(ap->dfops->dop_low && fb_agno < args.agno));
|
|
ap->length = args.len;
|
|
ap->length = args.len;
|
|
- ap->ip->i_d.di_nblocks += args.len;
|
|
|
|
|
|
+ if (!(ap->flags & XFS_BMAPI_COWFORK))
|
|
|
|
+ ap->ip->i_d.di_nblocks += args.len;
|
|
xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE);
|
|
xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE);
|
|
if (ap->wasdel)
|
|
if (ap->wasdel)
|
|
ap->ip->i_delayed_blks -= args.len;
|
|
ap->ip->i_delayed_blks -= args.len;
|
|
@@ -4256,8 +4270,7 @@ xfs_bmapi_allocate(
|
|
struct xfs_bmalloca *bma)
|
|
struct xfs_bmalloca *bma)
|
|
{
|
|
{
|
|
struct xfs_mount *mp = bma->ip->i_mount;
|
|
struct xfs_mount *mp = bma->ip->i_mount;
|
|
- int whichfork = (bma->flags & XFS_BMAPI_ATTRFORK) ?
|
|
|
|
- XFS_ATTR_FORK : XFS_DATA_FORK;
|
|
|
|
|
|
+ int whichfork = xfs_bmapi_whichfork(bma->flags);
|
|
struct xfs_ifork *ifp = XFS_IFORK_PTR(bma->ip, whichfork);
|
|
struct xfs_ifork *ifp = XFS_IFORK_PTR(bma->ip, whichfork);
|
|
int tmp_logflags = 0;
|
|
int tmp_logflags = 0;
|
|
int error;
|
|
int error;
|
|
@@ -4352,7 +4365,7 @@ xfs_bmapi_allocate(
|
|
bma->got.br_state = XFS_EXT_UNWRITTEN;
|
|
bma->got.br_state = XFS_EXT_UNWRITTEN;
|
|
|
|
|
|
if (bma->wasdel)
|
|
if (bma->wasdel)
|
|
- error = xfs_bmap_add_extent_delay_real(bma);
|
|
|
|
|
|
+ error = xfs_bmap_add_extent_delay_real(bma, whichfork);
|
|
else
|
|
else
|
|
error = xfs_bmap_add_extent_hole_real(bma, whichfork);
|
|
error = xfs_bmap_add_extent_hole_real(bma, whichfork);
|
|
|
|
|
|
@@ -4506,8 +4519,7 @@ xfs_bmapi_write(
|
|
orig_mval = mval;
|
|
orig_mval = mval;
|
|
orig_nmap = *nmap;
|
|
orig_nmap = *nmap;
|
|
#endif
|
|
#endif
|
|
- whichfork = (flags & XFS_BMAPI_ATTRFORK) ?
|
|
|
|
- XFS_ATTR_FORK : XFS_DATA_FORK;
|
|
|
|
|
|
+ whichfork = xfs_bmapi_whichfork(flags);
|
|
|
|
|
|
ASSERT(*nmap >= 1);
|
|
ASSERT(*nmap >= 1);
|
|
ASSERT(*nmap <= XFS_BMAP_MAX_NMAP);
|
|
ASSERT(*nmap <= XFS_BMAP_MAX_NMAP);
|
|
@@ -4519,6 +4531,8 @@ xfs_bmapi_write(
|
|
ASSERT(!(flags & XFS_BMAPI_REMAP) || whichfork == XFS_DATA_FORK);
|
|
ASSERT(!(flags & XFS_BMAPI_REMAP) || whichfork == XFS_DATA_FORK);
|
|
ASSERT(!(flags & XFS_BMAPI_PREALLOC) || !(flags & XFS_BMAPI_REMAP));
|
|
ASSERT(!(flags & XFS_BMAPI_PREALLOC) || !(flags & XFS_BMAPI_REMAP));
|
|
ASSERT(!(flags & XFS_BMAPI_CONVERT) || !(flags & XFS_BMAPI_REMAP));
|
|
ASSERT(!(flags & XFS_BMAPI_CONVERT) || !(flags & XFS_BMAPI_REMAP));
|
|
|
|
+ ASSERT(!(flags & XFS_BMAPI_PREALLOC) || whichfork != XFS_COW_FORK);
|
|
|
|
+ ASSERT(!(flags & XFS_BMAPI_CONVERT) || whichfork != XFS_COW_FORK);
|
|
|
|
|
|
/* zeroing is for currently only for data extents, not metadata */
|
|
/* zeroing is for currently only for data extents, not metadata */
|
|
ASSERT((flags & (XFS_BMAPI_METADATA | XFS_BMAPI_ZERO)) !=
|
|
ASSERT((flags & (XFS_BMAPI_METADATA | XFS_BMAPI_ZERO)) !=
|
|
@@ -4584,6 +4598,8 @@ xfs_bmapi_write(
|
|
*/
|
|
*/
|
|
if (flags & XFS_BMAPI_REMAP)
|
|
if (flags & XFS_BMAPI_REMAP)
|
|
ASSERT(inhole);
|
|
ASSERT(inhole);
|
|
|
|
+ if (flags & XFS_BMAPI_COWFORK)
|
|
|
|
+ ASSERT(!inhole);
|
|
|
|
|
|
/*
|
|
/*
|
|
* First, deal with the hole before the allocated space
|
|
* First, deal with the hole before the allocated space
|