Implement three new ioctls that can be used with GEOM provider:

DIOCGFLUSH - Flush write cache (sends BIO_FLUSH).

	DIOCGDELETE - Delete data (mark as unused) (sends BIO_DELETE).

	DIOCGIDENT - Get provider's uniqe and fixed identifier (asks for
		GEOM::ident attribute).

First two are self-explanatory, but the last one might not be. Here are
properties of provider's ident:

- ident value is preserved between reboots,
- provider can be detached/attached and ident is preserved,
- provider's name can change - ident can't,
- ident value should not be based on on-disk metadata; in other words
  copying whole data from one disk to another should not yield the same
  ident for the other disk,
- there could be more than one provider with the same ident, but only if
  they point at exactly the same physical storage, this is the case for
  multipathing for example,
- GEOM classes that consumes single providers and provide single providers,
  like geli, gbde, should just attach class name to the ident of the
  underlying provider,
- ident is an ASCII string (is printable),
- ident is optional and applications can't relay on its presence.

The main purpose for this is that application and remember provider's ident
and once it tries to open provider by its name again, it may compare idents
to be sure this is the right provider. If it is not (idents don't match),
then it can open provider by its ident.

OK'ed by:	phk
This commit is contained in:
Pawel Jakub Dawidek 2007-05-05 17:02:19 +00:00
parent 2b17fb9514
commit 0589353ac7
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=169284
2 changed files with 52 additions and 0 deletions

View file

@ -245,6 +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;
int i, error;
u_int u;
@ -294,6 +295,25 @@ g_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread
if (!error)
dev->si_flags |= SI_DUMPDEV;
break;
case DIOCGFLUSH:
error = g_io_flush(cp);
break;
case DIOCGDELETE:
offset = ((off_t *)data)[0];
length = ((off_t *)data)[1];
if ((offset % cp->provider->sectorsize) != 0 ||
(length % cp->provider->sectorsize) != 0 ||
length <= 0 || length > MAXPHYS) {
printf("%s: offset=%jd length=%jd\n", __func__, offset,
length);
error = EINVAL;
break;
}
error = g_delete_data(cp, offset, length);
break;
case DIOCGIDENT:
error = g_io_getattr("GEOM::ident", cp, &i, data);
break;
default:
if (cp->provider->geom->ioctl != NULL) {

View file

@ -66,4 +66,36 @@ void disk_err(struct bio *bp, const char *what, int blkdone, int nl);
* which may apply to the device.
*/
#define DIOCGFLUSH _IO('d', 135) /* Flush write cache */
/*-
* Flush write cache of the device.
*/
#define DIOCGDELETE _IOW('d', 136, off_t[2]) /* Delete data */
/*-
* Mark data on the device as unused.
*/
#define DISK_IDENT_SIZE 256
#define DIOCGIDENT _IOR('d', 137, char[DISK_IDENT_SIZE])
/*-
* Get the ident of the given provider. Ident is (most of the time)
* a uniqe and fixed provider's identifier. Ident's properties are as
* follow:
* - ident value is preserved between reboots,
* - provider can be detached/attached and ident is preserved,
* - provider's name can change - ident can't,
* - ident value should not be based on on-disk metadata; in other
* words copying whole data from one disk to another should not
* yield the same ident for the other disk,
* - there could be more than one provider with the same ident, but
* only if they point at exactly the same physical storage, this is
* the case for multipathing for example,
* - GEOM classes that consumes single providers and provide single
* providers, like geli, gbde, should just attach class name to the
* ident of the underlying provider,
* - ident is an ASCII string (is printable),
* - ident is optional and applications can't relay on its presence.
*/
#endif /* _SYS_DISK_H_ */