Skip to content

Commit

Permalink
[PATCH] JFS: Don't allocate extents that overlap existing extents
Browse files Browse the repository at this point in the history
Modify xtSearch so that it returns the next allocated block when the
requested block is unmapped.  This can be used to make sure we don't
create a new extent that overlaps the next one.

Signed-off-by: Dave Kleikamp <shaggy@austin.ibm.com>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
  • Loading branch information
Dave Kleikamp authored and Linus Torvalds committed May 3, 2005
1 parent 1c62782 commit 6628465
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 25 deletions.
6 changes: 3 additions & 3 deletions fs/jfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ jfs_get_blocks(struct inode *ip, sector_t lblock, unsigned long max_blocks,
xad_t xad;
s64 xaddr;
int xflag;
s32 xlen;
s32 xlen = max_blocks;

/*
* Take appropriate lock on inode
Expand All @@ -190,7 +190,7 @@ jfs_get_blocks(struct inode *ip, sector_t lblock, unsigned long max_blocks,

if (((lblock64 << ip->i_sb->s_blocksize_bits) < ip->i_size) &&
(!xtLookup(ip, lblock64, max_blocks, &xflag, &xaddr, &xlen, 0)) &&
xlen) {
xaddr) {
if (xflag & XAD_NOTRECORDED) {
if (!create)
/*
Expand Down Expand Up @@ -229,7 +229,7 @@ jfs_get_blocks(struct inode *ip, sector_t lblock, unsigned long max_blocks,
#ifdef _JFS_4K
if ((rc = extHint(ip, lblock64 << ip->i_sb->s_blocksize_bits, &xad)))
goto unlock;
rc = extAlloc(ip, max_blocks, lblock64, &xad, FALSE);
rc = extAlloc(ip, xlen, lblock64, &xad, FALSE);
if (rc)
goto unlock;

Expand Down
4 changes: 2 additions & 2 deletions fs/jfs/jfs_dtree.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ static struct metapage *read_index_page(struct inode *inode, s64 blkno)
s32 xlen;

rc = xtLookup(inode, blkno, 1, &xflag, &xaddr, &xlen, 1);
if (rc || (xlen == 0))
if (rc || (xaddr == 0))
return NULL;

return read_metapage(inode, xaddr, PSIZE, 1);
Expand All @@ -231,7 +231,7 @@ static struct metapage *get_index_page(struct inode *inode, s64 blkno)
s32 xlen;

rc = xtLookup(inode, blkno, 1, &xflag, &xaddr, &xlen, 1);
if (rc || (xlen == 0))
if (rc || (xaddr == 0))
return NULL;

return get_metapage(inode, xaddr, PSIZE, 1);
Expand Down
61 changes: 41 additions & 20 deletions fs/jfs/jfs_xtree.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@ static struct {
/*
* forward references
*/
static int xtSearch(struct inode *ip,
s64 xoff, int *cmpp, struct btstack * btstack, int flag);
static int xtSearch(struct inode *ip, s64 xoff, s64 *next, int *cmpp,
struct btstack * btstack, int flag);

static int xtSplitUp(tid_t tid,
struct inode *ip,
Expand Down Expand Up @@ -159,11 +159,12 @@ int xtLookup(struct inode *ip, s64 lstart,
xtpage_t *p;
int index;
xad_t *xad;
s64 size, xoff, xend;
s64 next, size, xoff, xend;
int xlen;
s64 xaddr;

*plen = 0;
*paddr = 0;
*plen = llen;

if (!no_check) {
/* is lookup offset beyond eof ? */
Expand All @@ -180,7 +181,7 @@ int xtLookup(struct inode *ip, s64 lstart,
* search for the xad entry covering the logical extent
*/
//search:
if ((rc = xtSearch(ip, lstart, &cmp, &btstack, 0))) {
if ((rc = xtSearch(ip, lstart, &next, &cmp, &btstack, 0))) {
jfs_err("xtLookup: xtSearch returned %d", rc);
return rc;
}
Expand All @@ -198,8 +199,11 @@ int xtLookup(struct inode *ip, s64 lstart,
* lstart is a page start address,
* i.e., lstart cannot start in a hole;
*/
if (cmp)
if (cmp) {
if (next)
*plen = min(next - lstart, llen);
goto out;
}

/*
* lxd covered by xad
Expand Down Expand Up @@ -284,7 +288,7 @@ int xtLookupList(struct inode *ip, struct lxdlist * lxdlist,
if (lstart >= size)
return 0;

if ((rc = xtSearch(ip, lstart, &cmp, &btstack, 0)))
if ((rc = xtSearch(ip, lstart, NULL, &cmp, &btstack, 0)))
return rc;

/*
Expand Down Expand Up @@ -488,6 +492,7 @@ int xtLookupList(struct inode *ip, struct lxdlist * lxdlist,
* parameters:
* ip - file object;
* xoff - extent offset;
* nextp - address of next extent (if any) for search miss
* cmpp - comparison result:
* btstack - traverse stack;
* flag - search process flag (XT_INSERT);
Expand All @@ -497,7 +502,7 @@ int xtLookupList(struct inode *ip, struct lxdlist * lxdlist,
* *cmpp is set to result of comparison with the entry returned.
* the page containing the entry is pinned at exit.
*/
static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */
static int xtSearch(struct inode *ip, s64 xoff, s64 *nextp,
int *cmpp, struct btstack * btstack, int flag)
{
struct jfs_inode_info *jfs_ip = JFS_IP(ip);
Expand All @@ -511,6 +516,7 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */
struct btframe *btsp;
int nsplit = 0; /* number of pages to split */
s64 t64;
s64 next = 0;

INCREMENT(xtStat.search);

Expand Down Expand Up @@ -579,6 +585,7 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */
* previous and this entry
*/
*cmpp = 1;
next = t64;
goto out;
}

Expand Down Expand Up @@ -623,6 +630,9 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */
/* update sequential access heuristics */
jfs_ip->btindex = index;

if (nextp)
*nextp = next;

INCREMENT(xtStat.fastSearch);
return 0;
}
Expand Down Expand Up @@ -675,10 +685,11 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */

return 0;
}

/* search hit - internal page:
* descend/search its child page
*/
if (index < p->header.nextindex - 1)
next = offsetXAD(&p->xad[index + 1]);
goto next;
}

Expand All @@ -694,6 +705,8 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */
* base is the smallest index with key (Kj) greater than
* search key (K) and may be zero or maxentry index.
*/
if (base < p->header.nextindex)
next = offsetXAD(&p->xad[base]);
/*
* search miss - leaf page:
*
Expand Down Expand Up @@ -727,6 +740,9 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */
jfs_ip->btorder = BT_RANDOM;
jfs_ip->btindex = base;

if (nextp)
*nextp = next;

return 0;
}

Expand Down Expand Up @@ -793,6 +809,7 @@ int xtInsert(tid_t tid, /* transaction id */
struct xtsplit split; /* split information */
xad_t *xad;
int cmp;
s64 next;
struct tlock *tlck;
struct xtlock *xtlck;

Expand All @@ -806,15 +823,15 @@ int xtInsert(tid_t tid, /* transaction id */
* n.b. xtSearch() may return index of maxentry of
* the full page.
*/
if ((rc = xtSearch(ip, xoff, &cmp, &btstack, XT_INSERT)))
if ((rc = xtSearch(ip, xoff, &next, &cmp, &btstack, XT_INSERT)))
return rc;

/* retrieve search result */
XT_GETSEARCH(ip, btstack.top, bn, mp, p, index);

/* This test must follow XT_GETSEARCH since mp must be valid if
* we branch to out: */
if (cmp == 0) {
if ((cmp == 0) || (next && (xlen > next - xoff))) {
rc = -EEXIST;
goto out;
}
Expand Down Expand Up @@ -1626,7 +1643,7 @@ int xtExtend(tid_t tid, /* transaction id */
jfs_info("xtExtend: nxoff:0x%lx nxlen:0x%x", (ulong) xoff, xlen);

/* there must exist extent to be extended */
if ((rc = xtSearch(ip, xoff - 1, &cmp, &btstack, XT_INSERT)))
if ((rc = xtSearch(ip, xoff - 1, NULL, &cmp, &btstack, XT_INSERT)))
return rc;

/* retrieve search result */
Expand Down Expand Up @@ -1794,7 +1811,7 @@ printf("xtTailgate: nxoff:0x%lx nxlen:0x%x nxaddr:0x%lx\n",
*/

/* there must exist extent to be tailgated */
if ((rc = xtSearch(ip, xoff, &cmp, &btstack, XT_INSERT)))
if ((rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, XT_INSERT)))
return rc;

/* retrieve search result */
Expand Down Expand Up @@ -1977,7 +1994,7 @@ int xtUpdate(tid_t tid, struct inode *ip, xad_t * nxad)
nxlen = lengthXAD(nxad);
nxaddr = addressXAD(nxad);

if ((rc = xtSearch(ip, nxoff, &cmp, &btstack, XT_INSERT)))
if ((rc = xtSearch(ip, nxoff, NULL, &cmp, &btstack, XT_INSERT)))
return rc;

/* retrieve search result */
Expand Down Expand Up @@ -2291,7 +2308,7 @@ int xtUpdate(tid_t tid, struct inode *ip, xad_t * nxad)
if (nextindex == le16_to_cpu(p->header.maxentry)) {
XT_PUTPAGE(mp);

if ((rc = xtSearch(ip, nxoff, &cmp, &btstack, XT_INSERT)))
if ((rc = xtSearch(ip, nxoff, NULL, &cmp, &btstack, XT_INSERT)))
return rc;

/* retrieve search result */
Expand Down Expand Up @@ -2438,6 +2455,7 @@ int xtAppend(tid_t tid, /* transaction id */
int nsplit, nblocks, xlen;
struct pxdlist pxdlist;
pxd_t *pxd;
s64 next;

xaddr = *xaddrp;
xlen = *xlenp;
Expand All @@ -2452,7 +2470,7 @@ int xtAppend(tid_t tid, /* transaction id */
* n.b. xtSearch() may return index of maxentry of
* the full page.
*/
if ((rc = xtSearch(ip, xoff, &cmp, &btstack, XT_INSERT)))
if ((rc = xtSearch(ip, xoff, &next, &cmp, &btstack, XT_INSERT)))
return rc;

/* retrieve search result */
Expand All @@ -2462,6 +2480,9 @@ int xtAppend(tid_t tid, /* transaction id */
rc = -EEXIST;
goto out;
}

if (next)
xlen = min(xlen, (int)(next - xoff));
//insert:
/*
* insert entry for new extent
Expand Down Expand Up @@ -2600,7 +2621,7 @@ int xtDelete(tid_t tid, struct inode *ip, s64 xoff, s32 xlen, int flag)
/*
* find the matching entry; xtSearch() pins the page
*/
if ((rc = xtSearch(ip, xoff, &cmp, &btstack, 0)))
if ((rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, 0)))
return rc;

XT_GETSEARCH(ip, btstack.top, bn, mp, p, index);
Expand Down Expand Up @@ -2852,7 +2873,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */
*/
if (xtype == DATAEXT) {
/* search in leaf entry */
rc = xtSearch(ip, xoff, &cmp, &btstack, 0);
rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, 0);
if (rc)
return rc;

Expand Down Expand Up @@ -2958,7 +2979,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */
}

/* get back parent page */
if ((rc = xtSearch(ip, xoff, &cmp, &btstack, 0)))
if ((rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, 0)))
return rc;

XT_GETSEARCH(ip, btstack.top, bn, pmp, pp, index);
Expand Down Expand Up @@ -3991,7 +4012,7 @@ s64 xtTruncate_pmap(tid_t tid, struct inode *ip, s64 committed_size)

if (committed_size) {
xoff = (committed_size >> JFS_SBI(ip->i_sb)->l2bsize) - 1;
rc = xtSearch(ip, xoff, &cmp, &btstack, 0);
rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, 0);
if (rc)
return rc;

Expand Down

0 comments on commit 6628465

Please sign in to comment.