Page MenuHomeFreeBSD

D39026.id118752.diff
No OneTemporary

D39026.id118752.diff

diff --git a/usr.sbin/makefs/ffs.c b/usr.sbin/makefs/ffs.c
--- a/usr.sbin/makefs/ffs.c
+++ b/usr.sbin/makefs/ffs.c
@@ -94,6 +94,8 @@
#include <sys/statvfs.h>
#endif
+#include <sys/mman.h>
+
#include <ufs/ufs/dinode.h>
#include <ufs/ufs/dir.h>
#include <ufs/ffs/fs.h>
@@ -568,6 +570,11 @@
fs = ffs_mkfs(image, fsopts, tstamp);
fsopts->superblock = (void *)fs;
+ fsopts->mmap = mmap(0, fsopts->size, PROT_READ | PROT_WRITE, MAP_SHARED, fsopts->fd, 0);
+ if (fsopts->mmap == MAP_FAILED) {
+ warn("mmap failed");
+ fsopts->mmap = 0;
+ }
if (debug & DEBUG_FS_CREATE_IMAGE) {
time_t t;
diff --git a/usr.sbin/makefs/ffs/buf.h b/usr.sbin/makefs/ffs/buf.h
--- a/usr.sbin/makefs/ffs/buf.h
+++ b/usr.sbin/makefs/ffs/buf.h
@@ -56,6 +56,8 @@
struct m_buf {
char * b_data;
+ long b_flags;
+#define B_ALLOC 0x001 /* b_data is allocated */
long b_bufsize;
long b_bcount;
daddr_t b_blkno;
diff --git a/usr.sbin/makefs/ffs/buf.c b/usr.sbin/makefs/ffs/buf.c
--- a/usr.sbin/makefs/ffs/buf.c
+++ b/usr.sbin/makefs/ffs/buf.c
@@ -75,6 +75,26 @@
printf("%s: blkno %lld offset %lld bcount %ld\n", __func__,
(long long)(*bpp)->b_blkno, (long long) offset,
(*bpp)->b_bcount);
+ if (fs->mmap) {
+ if (offset + (*bpp)->b_bcount > fs->size)
+ err(1, "%s: read %ld (%lld) past the end", __func__,
+ (*bpp)->b_bcount, (long long)offset);
+ if (!fs->zero_copy) {
+ assert((*bpp)->b_flags & B_ALLOC);
+ memcpy((*bpp)->b_data, fs->mmap + offset, (*bpp)->b_bcount);
+ if (debug & DEBUG_BUF_BREAD)
+ printf("%s: read %ld (%lld) mmap copy\n", __func__,
+ (*bpp)->b_bcount, (long long)offset);
+ } else {
+ /* getblk already set bp->b_data to point in mmap'd buffer */
+ assert(((*bpp)->b_flags & B_ALLOC) == 0);
+ if (debug & DEBUG_BUF_BREAD)
+ printf("%s: read %ld (%lld) zero copy\n", __func__,
+ (*bpp)->b_bcount, (long long)offset);
+ }
+ return (0);
+ }
+ /* Fallback for mmap failing or not supported by fs */
if (lseek((*bpp)->b_fs->fd, offset, SEEK_SET) == -1)
err(1, "%s: lseek %lld (%lld)", __func__,
(long long)(*bpp)->b_blkno, (long long)offset);
@@ -118,7 +138,8 @@
}
TAILQ_REMOVE(&buftail, bp, b_tailq);
- free(bp->b_data);
+ if (bp->b_fs->mmap == 0)
+ free(bp->b_data);
free(bp);
}
@@ -135,6 +156,26 @@
printf("bwrite: blkno %lld offset %lld bcount %ld\n",
(long long)bp->b_blkno, (long long) offset,
bp->b_bcount);
+ if (fs->mmap) {
+ if (offset + bp->b_bcount > fs->size)
+ err(1, "%s: write %ld (%lld) past the end", __func__,
+ bp->b_bcount, (long long)offset);
+ if (!fs->zero_copy) {
+ assert(bp->b_flags & B_ALLOC);
+ memcpy(fs->mmap + offset, bp->b_data, bp->b_bcount);
+ if (debug & DEBUG_BUF_BWRITE)
+ printf("bwrite: write %ld (offset %lld) mmap copy\n",
+ bp->b_bcount, (long long)offset);
+ } else {
+ /* mmap means it's already updated */
+ assert((bp->b_flags & B_ALLOC) == 0);
+ if (debug & DEBUG_BUF_BWRITE)
+ printf("bwrite: write %ld (offset %lld) zero copy\n",
+ bp->b_bcount, (long long)offset);
+ }
+ return (0);
+ }
+ /* Fallback */
if (lseek(bp->b_fs->fd, offset, SEEK_SET) == -1)
return (errno);
rv = write(bp->b_fs->fd, bp->b_data, bp->b_bcount);
@@ -206,9 +247,16 @@
}
bp->b_bcount = size;
if (bp->b_data == NULL || bp->b_bcount > bp->b_bufsize) {
- n = erealloc(bp->b_data, size);
- memset(n, 0, size);
- bp->b_data = n;
+ if (vp->fs->mmap != 0 && vp->fs->zero_copy) {
+ assert((bp->b_flags & B_ALLOC) == 0);
+ bp->b_data = vp->fs->mmap +
+ (off_t)bp->b_blkno * bp->b_fs->sectorsize + bp->b_fs->offset;
+ } else {
+ n = erealloc(bp->b_data, size);
+ memset(n, 0, size);
+ bp->b_data = n;
+ bp->b_flags |= B_ALLOC;
+ }
bp->b_bufsize = size;
}
diff --git a/usr.sbin/makefs/makefs.h b/usr.sbin/makefs/makefs.h
--- a/usr.sbin/makefs/makefs.h
+++ b/usr.sbin/makefs/makefs.h
@@ -148,6 +148,7 @@
int fd; /* file descriptor of image */
void *superblock; /* superblock */
int onlyspec; /* only add entries in specfile */
+ char *mmap; /* Address, if any, for mmap'd array */
/* global options */
@@ -162,6 +163,7 @@
int needswap; /* non-zero if byte swapping needed */
int sectorsize; /* sector size */
int sparse; /* sparse image, don't fill it with zeros */
+ int zero_copy; /* Do zero copy if possible */
void *fs_specific; /* File system specific additions. */
option_t *fs_options; /* File system specific options */
diff --git a/usr.sbin/makefs/msdos.c b/usr.sbin/makefs/msdos.c
--- a/usr.sbin/makefs/msdos.c
+++ b/usr.sbin/makefs/msdos.c
@@ -55,6 +55,7 @@
#include <dirent.h>
#include <util.h>
+#include <sys/mman.h>
#include <mkfs_msdos.h>
#include <fs/msdosfs/bpb.h>
#include "msdos/direntry.h"
@@ -183,6 +184,13 @@
fsopts->fd = open(image, O_RDWR);
vp.fs = fsopts;
+ fsopts->mmap = mmap(0, fsopts->size, PROT_READ | PROT_WRITE, MAP_SHARED, fsopts->fd, 0);
+ if (fsopts->mmap == MAP_FAILED) {
+ warn("mmap failed");
+ fsopts->mmap = 0;
+ } else {
+ fsopts->zero_copy = 1;
+ }
if ((pmp = m_msdosfs_mount(&vp)) == NULL)
err(1, "msdosfs_mount");

File Metadata

Mime Type
text/plain
Expires
Wed, Dec 31, 10:02 AM (9 h, 24 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27408272
Default Alt Text
D39026.id118752.diff (5 KB)

Event Timeline