summaryrefslogtreecommitdiffstats
path: root/sys/geom/geom_dev.c
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2007-12-16 19:38:26 +0000
committerphk <phk@FreeBSD.org>2007-12-16 19:38:26 +0000
commitf0debf860a7293c754e26563a772bdac6d9aa62f (patch)
tree6394140da6538b14b5e371f5c85a2200a6649b8c /sys/geom/geom_dev.c
parent707b3f65a72523c9cb0af31e0f399bf465387a49 (diff)
downloadFreeBSD-src-f0debf860a7293c754e26563a772bdac6d9aa62f.zip
FreeBSD-src-f0debf860a7293c754e26563a772bdac6d9aa62f.tar.gz
Chop DIOCGDELETE from userland up in 1024 sector chunks to give geom_disk
or any other bio chopping geom a reasonable size of work. Check for delivered signals between chunks, because the request size and service time is unbounded.
Diffstat (limited to 'sys/geom/geom_dev.c')
-rw-r--r--sys/geom/geom_dev.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/sys/geom/geom_dev.c b/sys/geom/geom_dev.c
index 2c62b49..c379d06 100644
--- a/sys/geom/geom_dev.c
+++ b/sys/geom/geom_dev.c
@@ -245,7 +245,7 @@ g_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread
struct g_geom *gp;
struct g_consumer *cp;
struct g_kerneldump kd;
- off_t offset, length;
+ off_t offset, length, chunk;
int i, error;
u_int u;
@@ -308,7 +308,23 @@ g_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread
error = EINVAL;
break;
}
- error = g_delete_data(cp, offset, length);
+ while (length > 0) {
+ chunk = length;
+ if (chunk > 1024 * cp->provider->sectorsize)
+ chunk = 1024 * cp->provider->sectorsize;
+ error = g_delete_data(cp, offset, chunk);
+ length -= chunk;
+ offset += chunk;
+ if (error)
+ break;
+ /*
+ * Since the request size is unbounded, the service
+ * time is likewise. We make this ioctl interruptible
+ * by checking for signals for each bio.
+ */
+ if (SIGPENDING(td))
+ break;
+ }
break;
case DIOCGIDENT:
error = g_io_getattr("GEOM::ident", cp, &i, data);
OpenPOWER on IntegriCloud