Skip to content

Commit

Permalink
[XFS] Add new getbmap flags.
Browse files Browse the repository at this point in the history
This adds a new output flag, BMV_OF_LAST to indicate if we've hit
the last extent in the inode.  This potentially saves an extra call
from userspace to see when the whole mapping is done.

It also adds BMV_IF_DELALLOC and BMV_OF_DELALLOC to request, and
indicate, delayed-allocation extents.  In this case bmv_block
is set to -2 (-1 was already taken for HOLESTARTBLOCK; unfortunately
these are the reverse of the in-kernel constants.)

These new flags facilitate addition of the new fiemap interface.

Rather than adding sh_delalloc, remove sh_unwritten & just test
the flags directly.

Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Niv Sardi <xaiki@sgi.com>
  • Loading branch information
sandeen authored and Niv Sardi committed Dec 1, 2008
1 parent 8a7141a commit 5af317c
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 15 deletions.
46 changes: 32 additions & 14 deletions fs/xfs/xfs_bmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -5819,6 +5819,9 @@ xfs_getbmapx_fix_eof_hole(
{
__int64_t fixlen;
xfs_mount_t *mp; /* file system mount point */
xfs_ifork_t *ifp; /* inode fork pointer */
xfs_extnum_t lastx; /* last extent pointer */
xfs_fileoff_t fileblock;

if (startblock == HOLESTARTBLOCK) {
mp = ip->i_mount;
Expand All @@ -5832,7 +5835,15 @@ xfs_getbmapx_fix_eof_hole(
out->bmv_length = fixlen;
}
} else {
out->bmv_block = XFS_FSB_TO_DB(ip, startblock);
if (startblock == DELAYSTARTBLOCK)
out->bmv_block = -2;
else
out->bmv_block = XFS_FSB_TO_DB(ip, startblock);
fileblock = XFS_BB_TO_FSB(ip->i_mount, out->bmv_offset);
ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
if (xfs_iext_bno_to_ext(ifp, fileblock, &lastx) &&
(lastx == (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))-1))
out->bmv_oflags |= BMV_OF_LAST;
}

return 1;
Expand Down Expand Up @@ -5867,16 +5878,13 @@ xfs_getbmap(
int whichfork; /* data or attr fork */
int prealloced; /* this is a file with
* preallocated data space */
int sh_unwritten; /* true, if unwritten */
/* extents listed separately */
int iflags; /* interface flags */
int bmapi_flags; /* flags for xfs_bmapi */

mp = ip->i_mount;
iflags = bmv->bmv_iflags;

whichfork = iflags & BMV_IF_ATTRFORK ? XFS_ATTR_FORK : XFS_DATA_FORK;
sh_unwritten = (iflags & BMV_IF_PREALLOC) != 0;

/* If the BMV_IF_NO_DMAPI_READ interface bit specified, do not
* generate a DMAPI read event. Otherwise, if the DM_EVENT_READ
Expand Down Expand Up @@ -5947,8 +5955,9 @@ xfs_getbmap(

xfs_ilock(ip, XFS_IOLOCK_SHARED);

if (whichfork == XFS_DATA_FORK &&
(ip->i_delayed_blks || ip->i_size > ip->i_d.di_size)) {
if (((iflags & BMV_IF_DELALLOC) == 0) &&
(whichfork == XFS_DATA_FORK) &&
(ip->i_delayed_blks || ip->i_size > ip->i_d.di_size)) {
/* xfs_fsize_t last_byte = xfs_file_last_byte(ip); */
error = xfs_flush_pages(ip, (xfs_off_t)0,
-1, 0, FI_REMAPF);
Expand All @@ -5958,7 +5967,8 @@ xfs_getbmap(
}
}

ASSERT(whichfork == XFS_ATTR_FORK || ip->i_delayed_blks == 0);
ASSERT(whichfork == XFS_ATTR_FORK || (iflags & BMV_IF_DELALLOC) ||
ip->i_delayed_blks == 0);

lock = xfs_ilock_map_shared(ip);

Expand All @@ -5970,7 +5980,7 @@ xfs_getbmap(
nex = XFS_IFORK_NEXTENTS(ip, whichfork) * 2 + 1;

bmapi_flags = XFS_BMAPI_AFLAG(whichfork) |
((sh_unwritten) ? 0 : XFS_BMAPI_IGSTATE);
((iflags & BMV_IF_PREALLOC) ? 0 : XFS_BMAPI_IGSTATE);

/*
* Allocate enough space to handle "subnex" maps at a time.
Expand All @@ -5980,9 +5990,12 @@ xfs_getbmap(

bmv->bmv_entries = 0;

if (XFS_IFORK_NEXTENTS(ip, whichfork) == 0) {
error = 0;
goto unlock_and_return;
if ((XFS_IFORK_NEXTENTS(ip, whichfork) == 0)) {
if (((iflags & BMV_IF_DELALLOC) == 0) ||
whichfork == XFS_ATTR_FORK) {
error = 0;
goto unlock_and_return;
}
}

nexleft = nex;
Expand All @@ -5998,15 +6011,20 @@ xfs_getbmap(
ASSERT(nmap <= subnex);

for (i = 0; i < nmap && nexleft && bmv->bmv_length; i++) {
out.bmv_oflags = (map[i].br_state == XFS_EXT_UNWRITTEN) ?
BMV_OF_PREALLOC : 0;
out.bmv_oflags = 0;
if (map[i].br_state == XFS_EXT_UNWRITTEN)
out.bmv_oflags |= BMV_OF_PREALLOC;
else if (map[i].br_startblock == DELAYSTARTBLOCK)
out.bmv_oflags |= BMV_OF_DELALLOC;
out.bmv_offset = XFS_FSB_TO_BB(mp, map[i].br_startoff);
out.bmv_length = XFS_FSB_TO_BB(mp, map[i].br_blockcount);
out.bmv_unused1 = out.bmv_unused2 = 0;
ASSERT(map[i].br_startblock != DELAYSTARTBLOCK);
ASSERT(((iflags & BMV_IF_DELALLOC) != 0) ||
(map[i].br_startblock != DELAYSTARTBLOCK));
if (map[i].br_startblock == HOLESTARTBLOCK &&
whichfork == XFS_ATTR_FORK) {
/* came to the end of attribute fork */
out.bmv_oflags |= BMV_OF_LAST;
goto unlock_and_return;
} else {
int full = 0; /* user array is full */
Expand Down
6 changes: 5 additions & 1 deletion fs/xfs/xfs_fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,14 @@ struct getbmapx {
#define BMV_IF_ATTRFORK 0x1 /* return attr fork rather than data */
#define BMV_IF_NO_DMAPI_READ 0x2 /* Do not generate DMAPI read event */
#define BMV_IF_PREALLOC 0x4 /* rtn status BMV_OF_PREALLOC if req */
#define BMV_IF_VALID (BMV_IF_ATTRFORK|BMV_IF_NO_DMAPI_READ|BMV_IF_PREALLOC)
#define BMV_IF_DELALLOC 0x8 /* rtn status BMV_OF_DELALLOC if req */
#define BMV_IF_VALID \
(BMV_IF_ATTRFORK|BMV_IF_NO_DMAPI_READ|BMV_IF_PREALLOC|BMV_IF_DELALLOC)

/* bmv_oflags values - returned for for each non-header segment */
#define BMV_OF_PREALLOC 0x1 /* segment = unwritten pre-allocation */
#define BMV_OF_DELALLOC 0x2 /* segment = delayed allocation */
#define BMV_OF_LAST 0x4 /* segment is the last in the file */

/*
* Structure for XFS_IOC_FSSETDM.
Expand Down

0 comments on commit 5af317c

Please sign in to comment.