Page MenuHomeFreeBSD

D53424.diff
No OneTemporary

D53424.diff

diff --git a/sys/ufs/ufs/ufs_bmap.c b/sys/ufs/ufs/ufs_bmap.c
--- a/sys/ufs/ufs/ufs_bmap.c
+++ b/sys/ufs/ufs/ufs_bmap.c
@@ -48,6 +48,7 @@
#include <vm/vm.h>
#include <vm/vm_object.h>
+#include <vm/vm_page.h>
#include <vm/vnode_pager.h>
#include <ufs/ufs/extattr.h>
@@ -59,6 +60,11 @@
static ufs_lbn_t lbn_count(struct ufsmount *, int);
static int readindir(struct vnode *, ufs_lbn_t, ufs2_daddr_t, struct buf **);
+static int ufs_bmap_use_unmapped = 1;
+
+SYSCTL_INT(_vfs_ufs, OID_AUTO, bmap_use_unmapped, CTLFLAG_RWTUN,
+ &ufs_bmap_use_unmapped, 0, "UFS bmap uses unmapped bufs");
+
/*
* Bmap converts the logical block number of a file to its physical block
* number on the disk. The conversion is done by using the logical block
@@ -102,12 +108,16 @@
struct buf *bp;
struct mount *mp;
struct ufsmount *ump;
- int error;
+ struct inode *ip;
+ int error, gbflags;
mp = vp->v_mount;
ump = VFSTOUFS(mp);
+ ip = VTOI(vp);
- bp = getblk(vp, lbn, mp->mnt_stat.f_iosize, 0, 0, 0);
+ gbflags = !I_IS_UFS1(ip) && PMAP_HAS_DMAP && ufs_bmap_use_unmapped ?
+ GB_UNMAPPED : 0;
+ bp = getblk(vp, lbn, mp->mnt_stat.f_iosize, 0, 0, gbflags);
if ((bp->b_flags & B_CACHE) == 0) {
KASSERT(daddr != 0,
("readindir: indirect block not in cache"));
@@ -168,6 +178,11 @@
ufs_lbn_t metalbn;
int error, num, maxrun = 0;
int *nump;
+ ufs1_daddr_t *daddr1p;
+ ufs2_daddr_t pgbn, daddrppg, prevdaddr, *daddr2p;
+ int32_t daddrsz, boff, pgidx, pgoff;
+ void *pgaddr;
+ bool isseq;
ap = NULL;
ip = VTOI(vp);
@@ -261,17 +276,68 @@
if (error != 0)
return (error);
- if (I_IS_UFS1(ip))
- daddr = ((ufs1_daddr_t *)bp->b_data)[ap->in_off];
- else
- daddr = ((ufs2_daddr_t *)bp->b_data)[ap->in_off];
+ daddrsz = I_IS_UFS1(ip) ? sizeof(ufs1_daddr_t) : sizeof(ufs2_daddr_t);
+ if (!buf_mapped(bp)) {
+ boff = ap->in_off * daddrsz;
+ pgidx = boff / PAGE_SIZE;
+ pgoff = (boff & PAGE_MASK) / daddrsz;
+ pgaddr = (void *)PHYS_TO_DMAP(VM_PAGE_TO_PHYS(bp->b_pages[pgidx]));
+ if (I_IS_UFS1(ip))
+ daddr = ((ufs1_daddr_t *)pgaddr)[pgoff];
+ else
+ daddr = ((ufs2_daddr_t *)pgaddr)[pgoff];
+ } else {
+ if (I_IS_UFS1(ip))
+ daddr = ((ufs1_daddr_t *)bp->b_data)[ap->in_off];
+ else
+ daddr = ((ufs2_daddr_t *)bp->b_data)[ap->in_off];
+ }
+
if ((error = UFS_CHECK_BLKNO(mp, ip->i_number, daddr,
mp->mnt_stat.f_iosize)) != 0) {
bqrelse(bp);
return (error);
}
+ if (num > 1 || daddr == 0 || runp == NULL)
+ continue;
+
+ daddrppg = PAGE_SIZE / daddrsz;
if (I_IS_UFS1(ip)) {
- if (num == 1 && daddr && runp) {
+ if (!buf_mapped(bp)) {
+ prevdaddr = daddr;
+ isseq = true;
+ for (bn = ap->in_off + 1;
+ bn < MNINDIR(ump) && *runp < maxrun && isseq; ) {
+ boff = bn * daddrsz;
+ pgidx = boff / PAGE_SIZE;
+ pgoff = (boff & PAGE_MASK) / daddrsz;
+ KASSERT(pgidx >= 0 && pgidx < bp->b_npages,
+ ("pgidx %d vs b_npages %d", pgidx, bp->b_npages));
+ pgaddr = (void *)PHYS_TO_DMAP(VM_PAGE_TO_PHYS(bp->b_pages[pgidx]));
+ daddr1p = (ufs1_daddr_t *)pgaddr;
+ for (pgbn = pgoff;
+ pgbn < daddrppg && *runp < maxrun &&
+ (isseq = is_sequential(ump, prevdaddr, daddr1p[pgbn]));
+ prevdaddr = daddr1p[pgbn], ++pgbn, ++bn, ++*runp);
+ }
+ prevdaddr = daddr;
+ bn = ap->in_off;
+ if (runb && bn) {
+ isseq = true;
+ for (--bn; bn >= 0 && *runb < maxrun && isseq; ) {
+ boff = bn * daddrsz;
+ pgidx = boff / PAGE_SIZE;
+ pgoff = (boff & PAGE_MASK) / daddrsz;
+ KASSERT(pgidx >= 0 && pgidx < bp->b_npages,
+ ("pgidx %d vs b_npages %d", pgidx, bp->b_npages));
+ pgaddr = (void *)PHYS_TO_DMAP(VM_PAGE_TO_PHYS(bp->b_pages[pgidx]));
+ daddr1p = (ufs1_daddr_t *)pgaddr;
+ for (pgbn = pgoff; pgbn >= 0 && *runb < maxrun &&
+ (isseq = is_sequential(ump, daddr1p[pgbn], prevdaddr));
+ prevdaddr = daddr1p[pgbn], --pgbn, --bn, ++*runb);
+ }
+ }
+ } else {
for (bn = ap->in_off + 1;
bn < MNINDIR(ump) && *runp < maxrun &&
is_sequential(ump,
@@ -289,7 +355,43 @@
}
continue;
}
- if (num == 1 && daddr && runp) {
+
+ if (!buf_mapped(bp)) {
+ prevdaddr = daddr;
+ isseq = true;
+ for (bn = ap->in_off + 1;
+ bn < MNINDIR(ump) && *runp < maxrun && isseq; ) {
+ boff = bn * daddrsz;
+ pgidx = boff / PAGE_SIZE;
+ pgoff = (boff & PAGE_MASK) / daddrsz;
+ KASSERT(pgidx >= 0 && pgidx < bp->b_npages,
+ ("pgidx %d vs b_npages %d", pgidx, bp->b_npages));
+ pgaddr = (void *)PHYS_TO_DMAP(VM_PAGE_TO_PHYS(bp->b_pages[pgidx]));
+ daddr2p = (ufs2_daddr_t *)pgaddr;
+ for (pgbn = pgoff;
+ pgbn < daddrppg && *runp < maxrun &&
+ (isseq = is_sequential(ump, prevdaddr, daddr2p[pgbn]));
+ prevdaddr = daddr2p[pgbn], ++pgbn, ++bn, ++*runp);
+ }
+ prevdaddr = daddr;
+ bn = ap->in_off;
+ if (runb && bn) {
+ isseq = true;
+ for (--bn; bn >= 0 && *runb < maxrun && isseq; ) {
+ boff = bn * daddrsz;
+ pgidx = boff / PAGE_SIZE;
+ pgoff = (boff & PAGE_MASK) / daddrsz;
+ KASSERT(pgidx >= 0 && pgidx < bp->b_npages,
+ ("pgidx %d vs b_npages %d", pgidx, bp->b_npages));
+ pgaddr = (void *)PHYS_TO_DMAP(VM_PAGE_TO_PHYS(
+ bp->b_pages[pgidx]));
+ daddr2p = (ufs2_daddr_t *)pgaddr;
+ for (pgbn = pgoff; pgbn >= 0 && *runb < maxrun &&
+ (isseq = is_sequential(ump, daddr2p[pgbn], prevdaddr));
+ prevdaddr = daddr2p[pgbn], --pgbn, --bn, ++*runb);
+ }
+ }
+ } else {
for (bn = ap->in_off + 1;
bn < MNINDIR(ump) && *runp < maxrun &&
is_sequential(ump,

File Metadata

Mime Type
text/plain
Expires
Thu, Jan 29, 12:32 PM (2 h, 21 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28081956
Default Alt Text
D53424.diff (5 KB)

Event Timeline