diff options
author | phk <phk@FreeBSD.org> | 2007-12-16 19:38:26 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 2007-12-16 19:38:26 +0000 |
commit | f0debf860a7293c754e26563a772bdac6d9aa62f (patch) | |
tree | 6394140da6538b14b5e371f5c85a2200a6649b8c | |
parent | 707b3f65a72523c9cb0af31e0f399bf465387a49 (diff) | |
download | FreeBSD-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.
-rw-r--r-- | sys/geom/geom_dev.c | 20 |
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); |