summaryrefslogtreecommitdiffstats
path: root/sys/geom
diff options
context:
space:
mode:
authorken <ken@FreeBSD.org>2015-12-04 03:38:35 +0000
committerken <ken@FreeBSD.org>2015-12-04 03:38:35 +0000
commit134df9b39d33d06bb7a0f331372a746260cddc20 (patch)
tree4adcc64f90b7b92c3c7a01182b037a6e61576602 /sys/geom
parent38174a7667de4ae9a0a33ede1f08554c5c47db42 (diff)
downloadFreeBSD-src-134df9b39d33d06bb7a0f331372a746260cddc20.zip
FreeBSD-src-134df9b39d33d06bb7a0f331372a746260cddc20.tar.gz
Fix g_disk_vlist_limit() to work properly with deletes.
Add a new bp argument to g_disk_maxsegs(), and add a new function, g_disk_maxsize() tha will properly determine the maximum I/O size for a delete or non-delete bio. Submitted by: will MFC after: 1 week Sponsored by: Spectra Logic
Diffstat (limited to 'sys/geom')
-rw-r--r--sys/geom/geom_disk.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/sys/geom/geom_disk.c b/sys/geom/geom_disk.c
index 4ba624c..7d31897 100644
--- a/sys/geom/geom_disk.c
+++ b/sys/geom/geom_disk.c
@@ -253,10 +253,18 @@ g_disk_ioctl(struct g_provider *pp, u_long cmd, void * data, int fflag, struct t
return (error);
}
+static off_t
+g_disk_maxsize(struct disk *dp, struct bio *bp)
+{
+ if (bp->bio_cmd == BIO_DELETE)
+ return (dp->d_delmaxsize);
+ return (dp->d_maxsize);
+}
+
static int
-g_disk_maxsegs(struct disk *dp)
+g_disk_maxsegs(struct disk *dp, struct bio *bp)
{
- return ((dp->d_maxsize / PAGE_SIZE) + 1);
+ return ((g_disk_maxsize(dp, bp) / PAGE_SIZE) + 1);
}
static void
@@ -334,7 +342,7 @@ g_disk_vlist_limit(struct disk *dp, struct bio *bp, bus_dma_segment_t **pendseg)
end = (bus_dma_segment_t *)bp->bio_data + bp->bio_ma_n;
residual = bp->bio_length;
offset = bp->bio_ma_offset;
- pages = g_disk_maxsegs(dp);
+ pages = g_disk_maxsegs(dp, bp);
while (residual != 0 && pages != 0) {
KASSERT((seg != end),
("vlist limit runs off the end"));
@@ -350,10 +358,7 @@ static bool
g_disk_limit(struct disk *dp, struct bio *bp)
{
bool limited = false;
- off_t d_maxsize;
-
- d_maxsize = (bp->bio_cmd == BIO_DELETE) ?
- dp->d_delmaxsize : dp->d_maxsize;
+ off_t maxsz = g_disk_maxsize(dp, bp);
/*
* XXX: If we have a stripesize we should really use it here.
@@ -361,8 +366,8 @@ g_disk_limit(struct disk *dp, struct bio *bp)
* as deletes can be very sensitive to size given how they
* are processed.
*/
- if (bp->bio_length > d_maxsize) {
- bp->bio_length = d_maxsize;
+ if (bp->bio_length > maxsz) {
+ bp->bio_length = maxsz;
limited = true;
}
OpenPOWER on IntegriCloud