Skip to content

Commit 0dfc7af

Browse files
akihikodakistefanhaRH
authored andcommitted
block/file-posix: Optimize for macOS
This commit introduces "punch hole" operation and optimizes transfer block size for macOS. Thanks to Konstantin Nazarov for detailed analysis of a flaw in an old version of this change: https://gist.github.com/akihikodaki/87df4149e7ca87f18dc56807ec5a1bc5#gistcomment-3654667 Signed-off-by: Akihiko Odaki <[email protected]> Message-id: [email protected] Signed-off-by: Stefan Hajnoczi <[email protected]>
1 parent 023ca42 commit 0dfc7af

File tree

1 file changed

+25
-2
lines changed

1 file changed

+25
-2
lines changed

block/file-posix.c

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#if defined(HAVE_HOST_BLOCK_DEVICE)
4747
#include <paths.h>
4848
#include <sys/param.h>
49+
#include <sys/mount.h>
4950
#include <IOKit/IOKitLib.h>
5051
#include <IOKit/IOBSD.h>
5152
#include <IOKit/storage/IOMediaBSDClient.h>
@@ -1254,6 +1255,15 @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
12541255
return;
12551256
}
12561257

1258+
#if defined(__APPLE__) && (__MACH__)
1259+
struct statfs buf;
1260+
1261+
if (!fstatfs(s->fd, &buf)) {
1262+
bs->bl.opt_transfer = buf.f_iosize;
1263+
bs->bl.pdiscard_alignment = buf.f_bsize;
1264+
}
1265+
#endif
1266+
12571267
if (bs->sg || S_ISBLK(st.st_mode)) {
12581268
int ret = hdev_get_max_hw_transfer(s->fd, &st);
12591269

@@ -1591,6 +1601,7 @@ static int handle_aiocb_rw(void *opaque)
15911601
}
15921602
}
15931603

1604+
#if defined(CONFIG_FALLOCATE) || defined(BLKZEROOUT) || defined(BLKDISCARD)
15941605
static int translate_err(int err)
15951606
{
15961607
if (err == -ENODEV || err == -ENOSYS || err == -EOPNOTSUPP ||
@@ -1599,6 +1610,7 @@ static int translate_err(int err)
15991610
}
16001611
return err;
16011612
}
1613+
#endif
16021614

16031615
#ifdef CONFIG_FALLOCATE
16041616
static int do_fallocate(int fd, int mode, off_t offset, off_t len)
@@ -1811,16 +1823,27 @@ static int handle_aiocb_discard(void *opaque)
18111823
}
18121824
} while (errno == EINTR);
18131825

1814-
ret = -errno;
1826+
ret = translate_err(-errno);
18151827
#endif
18161828
} else {
18171829
#ifdef CONFIG_FALLOCATE_PUNCH_HOLE
18181830
ret = do_fallocate(s->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
18191831
aiocb->aio_offset, aiocb->aio_nbytes);
1832+
ret = translate_err(-errno);
1833+
#elif defined(__APPLE__) && (__MACH__)
1834+
fpunchhole_t fpunchhole;
1835+
fpunchhole.fp_flags = 0;
1836+
fpunchhole.reserved = 0;
1837+
fpunchhole.fp_offset = aiocb->aio_offset;
1838+
fpunchhole.fp_length = aiocb->aio_nbytes;
1839+
if (fcntl(s->fd, F_PUNCHHOLE, &fpunchhole) == -1) {
1840+
ret = errno == ENODEV ? -ENOTSUP : -errno;
1841+
} else {
1842+
ret = 0;
1843+
}
18201844
#endif
18211845
}
18221846

1823-
ret = translate_err(ret);
18241847
if (ret == -ENOTSUP) {
18251848
s->has_discard = false;
18261849
}

0 commit comments

Comments
 (0)