Commit 6628465e authored by Dave Kleikamp's avatar Dave Kleikamp Committed by Linus Torvalds

[PATCH] JFS: Don't allocate extents that overlap existing extents

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: default avatarDave Kleikamp <shaggy@austin.ibm.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 1c627829
...@@ -178,7 +178,7 @@ jfs_get_blocks(struct inode *ip, sector_t lblock, unsigned long max_blocks, ...@@ -178,7 +178,7 @@ jfs_get_blocks(struct inode *ip, sector_t lblock, unsigned long max_blocks,
xad_t xad; xad_t xad;
s64 xaddr; s64 xaddr;
int xflag; int xflag;
s32 xlen; s32 xlen = max_blocks;
/* /*
* Take appropriate lock on inode * Take appropriate lock on inode
...@@ -190,7 +190,7 @@ jfs_get_blocks(struct inode *ip, sector_t lblock, unsigned long max_blocks, ...@@ -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) && if (((lblock64 << ip->i_sb->s_blocksize_bits) < ip->i_size) &&
(!xtLookup(ip, lblock64, max_blocks, &xflag, &xaddr, &xlen, 0)) && (!xtLookup(ip, lblock64, max_blocks, &xflag, &xaddr, &xlen, 0)) &&
xlen) { xaddr) {
if (xflag & XAD_NOTRECORDED) { if (xflag & XAD_NOTRECORDED) {
if (!create) if (!create)
/* /*
...@@ -229,7 +229,7 @@ jfs_get_blocks(struct inode *ip, sector_t lblock, unsigned long max_blocks, ...@@ -229,7 +229,7 @@ jfs_get_blocks(struct inode *ip, sector_t lblock, unsigned long max_blocks,
#ifdef _JFS_4K #ifdef _JFS_4K
if ((rc = extHint(ip, lblock64 << ip->i_sb->s_blocksize_bits, &xad))) if ((rc = extHint(ip, lblock64 << ip->i_sb->s_blocksize_bits, &xad)))
goto unlock; goto unlock;
rc = extAlloc(ip, max_blocks, lblock64, &xad, FALSE); rc = extAlloc(ip, xlen, lblock64, &xad, FALSE);
if (rc) if (rc)
goto unlock; goto unlock;
......
...@@ -212,7 +212,7 @@ static struct metapage *read_index_page(struct inode *inode, s64 blkno) ...@@ -212,7 +212,7 @@ static struct metapage *read_index_page(struct inode *inode, s64 blkno)
s32 xlen; s32 xlen;
rc = xtLookup(inode, blkno, 1, &xflag, &xaddr, &xlen, 1); rc = xtLookup(inode, blkno, 1, &xflag, &xaddr, &xlen, 1);
if (rc || (xlen == 0)) if (rc || (xaddr == 0))
return NULL; return NULL;
return read_metapage(inode, xaddr, PSIZE, 1); return read_metapage(inode, xaddr, PSIZE, 1);
...@@ -231,7 +231,7 @@ static struct metapage *get_index_page(struct inode *inode, s64 blkno) ...@@ -231,7 +231,7 @@ static struct metapage *get_index_page(struct inode *inode, s64 blkno)
s32 xlen; s32 xlen;
rc = xtLookup(inode, blkno, 1, &xflag, &xaddr, &xlen, 1); rc = xtLookup(inode, blkno, 1, &xflag, &xaddr, &xlen, 1);
if (rc || (xlen == 0)) if (rc || (xaddr == 0))
return NULL; return NULL;
return get_metapage(inode, xaddr, PSIZE, 1); return get_metapage(inode, xaddr, PSIZE, 1);
......
...@@ -111,8 +111,8 @@ static struct { ...@@ -111,8 +111,8 @@ static struct {
/* /*
* forward references * forward references
*/ */
static int xtSearch(struct inode *ip, static int xtSearch(struct inode *ip, s64 xoff, s64 *next, int *cmpp,
s64 xoff, int *cmpp, struct btstack * btstack, int flag); struct btstack * btstack, int flag);
static int xtSplitUp(tid_t tid, static int xtSplitUp(tid_t tid,
struct inode *ip, struct inode *ip,
...@@ -159,11 +159,12 @@ int xtLookup(struct inode *ip, s64 lstart, ...@@ -159,11 +159,12 @@ int xtLookup(struct inode *ip, s64 lstart,
xtpage_t *p; xtpage_t *p;
int index; int index;
xad_t *xad; xad_t *xad;
s64 size, xoff, xend; s64 next, size, xoff, xend;
int xlen; int xlen;
s64 xaddr; s64 xaddr;
*plen = 0; *paddr = 0;
*plen = llen;
if (!no_check) { if (!no_check) {
/* is lookup offset beyond eof ? */ /* is lookup offset beyond eof ? */
...@@ -180,7 +181,7 @@ int xtLookup(struct inode *ip, s64 lstart, ...@@ -180,7 +181,7 @@ int xtLookup(struct inode *ip, s64 lstart,
* search for the xad entry covering the logical extent * search for the xad entry covering the logical extent
*/ */
//search: //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); jfs_err("xtLookup: xtSearch returned %d", rc);
return rc; return rc;
} }
...@@ -198,8 +199,11 @@ int xtLookup(struct inode *ip, s64 lstart, ...@@ -198,8 +199,11 @@ int xtLookup(struct inode *ip, s64 lstart,
* lstart is a page start address, * lstart is a page start address,
* i.e., lstart cannot start in a hole; * i.e., lstart cannot start in a hole;
*/ */
if (cmp) if (cmp) {
if (next)
*plen = min(next - lstart, llen);
goto out; goto out;
}
/* /*
* lxd covered by xad * lxd covered by xad
...@@ -284,7 +288,7 @@ int xtLookupList(struct inode *ip, struct lxdlist * lxdlist, ...@@ -284,7 +288,7 @@ int xtLookupList(struct inode *ip, struct lxdlist * lxdlist,
if (lstart >= size) if (lstart >= size)
return 0; return 0;
if ((rc = xtSearch(ip, lstart, &cmp, &btstack, 0))) if ((rc = xtSearch(ip, lstart, NULL, &cmp, &btstack, 0)))
return rc; return rc;
/* /*
...@@ -488,6 +492,7 @@ int xtLookupList(struct inode *ip, struct lxdlist * lxdlist, ...@@ -488,6 +492,7 @@ int xtLookupList(struct inode *ip, struct lxdlist * lxdlist,
* parameters: * parameters:
* ip - file object; * ip - file object;
* xoff - extent offset; * xoff - extent offset;
* nextp - address of next extent (if any) for search miss
* cmpp - comparison result: * cmpp - comparison result:
* btstack - traverse stack; * btstack - traverse stack;
* flag - search process flag (XT_INSERT); * flag - search process flag (XT_INSERT);
...@@ -497,7 +502,7 @@ int xtLookupList(struct inode *ip, struct lxdlist * lxdlist, ...@@ -497,7 +502,7 @@ int xtLookupList(struct inode *ip, struct lxdlist * lxdlist,
* *cmpp is set to result of comparison with the entry returned. * *cmpp is set to result of comparison with the entry returned.
* the page containing the entry is pinned at exit. * 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) int *cmpp, struct btstack * btstack, int flag)
{ {
struct jfs_inode_info *jfs_ip = JFS_IP(ip); struct jfs_inode_info *jfs_ip = JFS_IP(ip);
...@@ -511,6 +516,7 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */ ...@@ -511,6 +516,7 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */
struct btframe *btsp; struct btframe *btsp;
int nsplit = 0; /* number of pages to split */ int nsplit = 0; /* number of pages to split */
s64 t64; s64 t64;
s64 next = 0;
INCREMENT(xtStat.search); INCREMENT(xtStat.search);
...@@ -579,6 +585,7 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */ ...@@ -579,6 +585,7 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */
* previous and this entry * previous and this entry
*/ */
*cmpp = 1; *cmpp = 1;
next = t64;
goto out; goto out;
} }
...@@ -623,6 +630,9 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */ ...@@ -623,6 +630,9 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */
/* update sequential access heuristics */ /* update sequential access heuristics */
jfs_ip->btindex = index; jfs_ip->btindex = index;
if (nextp)
*nextp = next;
INCREMENT(xtStat.fastSearch); INCREMENT(xtStat.fastSearch);
return 0; return 0;
} }
...@@ -675,10 +685,11 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */ ...@@ -675,10 +685,11 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */
return 0; return 0;
} }
/* search hit - internal page: /* search hit - internal page:
* descend/search its child page * descend/search its child page
*/ */
if (index < p->header.nextindex - 1)
next = offsetXAD(&p->xad[index + 1]);
goto next; goto next;
} }
...@@ -694,6 +705,8 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */ ...@@ -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 * base is the smallest index with key (Kj) greater than
* search key (K) and may be zero or maxentry index. * search key (K) and may be zero or maxentry index.
*/ */
if (base < p->header.nextindex)
next = offsetXAD(&p->xad[base]);
/* /*
* search miss - leaf page: * search miss - leaf page:
* *
...@@ -727,6 +740,9 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */ ...@@ -727,6 +740,9 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */
jfs_ip->btorder = BT_RANDOM; jfs_ip->btorder = BT_RANDOM;
jfs_ip->btindex = base; jfs_ip->btindex = base;
if (nextp)
*nextp = next;
return 0; return 0;
} }
...@@ -793,6 +809,7 @@ int xtInsert(tid_t tid, /* transaction id */ ...@@ -793,6 +809,7 @@ int xtInsert(tid_t tid, /* transaction id */
struct xtsplit split; /* split information */ struct xtsplit split; /* split information */
xad_t *xad; xad_t *xad;
int cmp; int cmp;
s64 next;
struct tlock *tlck; struct tlock *tlck;
struct xtlock *xtlck; struct xtlock *xtlck;
...@@ -806,7 +823,7 @@ int xtInsert(tid_t tid, /* transaction id */ ...@@ -806,7 +823,7 @@ int xtInsert(tid_t tid, /* transaction id */
* n.b. xtSearch() may return index of maxentry of * n.b. xtSearch() may return index of maxentry of
* the full page. * the full page.
*/ */
if ((rc = xtSearch(ip, xoff, &cmp, &btstack, XT_INSERT))) if ((rc = xtSearch(ip, xoff, &next, &cmp, &btstack, XT_INSERT)))
return rc; return rc;
/* retrieve search result */ /* retrieve search result */
...@@ -814,7 +831,7 @@ int xtInsert(tid_t tid, /* transaction id */ ...@@ -814,7 +831,7 @@ int xtInsert(tid_t tid, /* transaction id */
/* This test must follow XT_GETSEARCH since mp must be valid if /* This test must follow XT_GETSEARCH since mp must be valid if
* we branch to out: */ * we branch to out: */
if (cmp == 0) { if ((cmp == 0) || (next && (xlen > next - xoff))) {
rc = -EEXIST; rc = -EEXIST;
goto out; goto out;
} }
...@@ -1626,7 +1643,7 @@ int xtExtend(tid_t tid, /* transaction id */ ...@@ -1626,7 +1643,7 @@ int xtExtend(tid_t tid, /* transaction id */
jfs_info("xtExtend: nxoff:0x%lx nxlen:0x%x", (ulong) xoff, xlen); jfs_info("xtExtend: nxoff:0x%lx nxlen:0x%x", (ulong) xoff, xlen);
/* there must exist extent to be extended */ /* 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; return rc;
/* retrieve search result */ /* retrieve search result */
...@@ -1794,7 +1811,7 @@ printf("xtTailgate: nxoff:0x%lx nxlen:0x%x nxaddr:0x%lx\n", ...@@ -1794,7 +1811,7 @@ printf("xtTailgate: nxoff:0x%lx nxlen:0x%x nxaddr:0x%lx\n",
*/ */
/* there must exist extent to be tailgated */ /* 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; return rc;
/* retrieve search result */ /* retrieve search result */
...@@ -1977,7 +1994,7 @@ int xtUpdate(tid_t tid, struct inode *ip, xad_t * nxad) ...@@ -1977,7 +1994,7 @@ int xtUpdate(tid_t tid, struct inode *ip, xad_t * nxad)
nxlen = lengthXAD(nxad); nxlen = lengthXAD(nxad);
nxaddr = addressXAD(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; return rc;
/* retrieve search result */ /* retrieve search result */
...@@ -2291,7 +2308,7 @@ int xtUpdate(tid_t tid, struct inode *ip, xad_t * nxad) ...@@ -2291,7 +2308,7 @@ int xtUpdate(tid_t tid, struct inode *ip, xad_t * nxad)
if (nextindex == le16_to_cpu(p->header.maxentry)) { if (nextindex == le16_to_cpu(p->header.maxentry)) {
XT_PUTPAGE(mp); XT_PUTPAGE(mp);
if ((rc = xtSearch(ip, nxoff, &cmp, &btstack, XT_INSERT))) if ((rc = xtSearch(ip, nxoff, NULL, &cmp, &btstack, XT_INSERT)))
return rc; return rc;
/* retrieve search result */ /* retrieve search result */
...@@ -2438,6 +2455,7 @@ int xtAppend(tid_t tid, /* transaction id */ ...@@ -2438,6 +2455,7 @@ int xtAppend(tid_t tid, /* transaction id */
int nsplit, nblocks, xlen; int nsplit, nblocks, xlen;
struct pxdlist pxdlist; struct pxdlist pxdlist;
pxd_t *pxd; pxd_t *pxd;
s64 next;
xaddr = *xaddrp; xaddr = *xaddrp;
xlen = *xlenp; xlen = *xlenp;
...@@ -2452,7 +2470,7 @@ int xtAppend(tid_t tid, /* transaction id */ ...@@ -2452,7 +2470,7 @@ int xtAppend(tid_t tid, /* transaction id */
* n.b. xtSearch() may return index of maxentry of * n.b. xtSearch() may return index of maxentry of
* the full page. * the full page.
*/ */
if ((rc = xtSearch(ip, xoff, &cmp, &btstack, XT_INSERT))) if ((rc = xtSearch(ip, xoff, &next, &cmp, &btstack, XT_INSERT)))
return rc; return rc;
/* retrieve search result */ /* retrieve search result */
...@@ -2462,6 +2480,9 @@ int xtAppend(tid_t tid, /* transaction id */ ...@@ -2462,6 +2480,9 @@ int xtAppend(tid_t tid, /* transaction id */
rc = -EEXIST; rc = -EEXIST;
goto out; goto out;
} }
if (next)
xlen = min(xlen, (int)(next - xoff));
//insert: //insert:
/* /*
* insert entry for new extent * insert entry for new extent
...@@ -2600,7 +2621,7 @@ int xtDelete(tid_t tid, struct inode *ip, s64 xoff, s32 xlen, int flag) ...@@ -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 * 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; return rc;
XT_GETSEARCH(ip, btstack.top, bn, mp, p, index); XT_GETSEARCH(ip, btstack.top, bn, mp, p, index);
...@@ -2852,7 +2873,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */ ...@@ -2852,7 +2873,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */
*/ */
if (xtype == DATAEXT) { if (xtype == DATAEXT) {
/* search in leaf entry */ /* search in leaf entry */
rc = xtSearch(ip, xoff, &cmp, &btstack, 0); rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, 0);
if (rc) if (rc)
return rc; return rc;
...@@ -2958,7 +2979,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */ ...@@ -2958,7 +2979,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */
} }
/* get back parent page */ /* get back parent page */
if ((rc = xtSearch(ip, xoff, &cmp, &btstack, 0))) if ((rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, 0)))
return rc; return rc;
XT_GETSEARCH(ip, btstack.top, bn, pmp, pp, index); XT_GETSEARCH(ip, btstack.top, bn, pmp, pp, index);
...@@ -3991,7 +4012,7 @@ s64 xtTruncate_pmap(tid_t tid, struct inode *ip, s64 committed_size) ...@@ -3991,7 +4012,7 @@ s64 xtTruncate_pmap(tid_t tid, struct inode *ip, s64 committed_size)
if (committed_size) { if (committed_size) {
xoff = (committed_size >> JFS_SBI(ip->i_sb)->l2bsize) - 1; 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) if (rc)
return rc; return rc;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment