1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-01-21 15:45:02 +00:00

Make geom_mirror more friendly to SSDs. To properly support TRIM,

we need to pass BIO_DELETE requests down to providers that support
it. Also, we need to announce our support for BIO_DELETE to upper
consumer. This requires:

- In g_mirror_start() return true for "GEOM::candelete" request.
- In g_mirror_init_disk() probe below provider for "GEOM::candelete"
  attribute, and mark disk with a flag if it does support BIO_DELETE.
- In g_mirror_register_request() distribute BIO_DELETE requests only
  to those disks, that do support it.

Note that we announce "GEOM::candelete" as true unconditionally of
whether we have TRIM-capable media down below or not. This is made
intentionally, because upper consumer (usually UFS) requests the
attribite only once at mount time. And if user ever migrates his
mirror from HDDs to SSDs, then he/she would get TRIM working without
remounting filesystem.

Reviewed by:	pjd
This commit is contained in:
Gleb Smirnoff 2012-07-01 15:43:52 +00:00
parent b0ae63ca25
commit d89862ac87
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=237930
2 changed files with 15 additions and 3 deletions

View File

@ -440,7 +440,7 @@ g_mirror_init_disk(struct g_mirror_softc *sc, struct g_provider *pp,
struct g_mirror_metadata *md, int *errorp)
{
struct g_mirror_disk *disk;
int error;
int i, error;
disk = malloc(sizeof(*disk), M_MIRROR, M_NOWAIT | M_ZERO);
if (disk == NULL) {
@ -455,6 +455,11 @@ g_mirror_init_disk(struct g_mirror_softc *sc, struct g_provider *pp,
disk->d_state = G_MIRROR_DISK_STATE_NONE;
disk->d_priority = md->md_priority;
disk->d_flags = md->md_dflags;
error = g_getattr("GEOM::candelete", disk->d_consumer, &i);
if (error != 0)
goto fail;
if (i)
disk->d_flags |= G_MIRROR_DISK_FLAG_CANDELETE;
if (md->md_provider[0] != '\0')
disk->d_flags |= G_MIRROR_DISK_FLAG_HARDCODED;
disk->d_sync.ds_consumer = NULL;
@ -1085,7 +1090,9 @@ g_mirror_start(struct bio *bp)
g_mirror_flush(sc, bp);
return;
case BIO_GETATTR:
if (strcmp("GEOM::kerneldump", bp->bio_attribute) == 0) {
if (g_handleattr_int(bp, "GEOM::candelete", 1))
return;
else if (strcmp("GEOM::kerneldump", bp->bio_attribute) == 0) {
g_mirror_kernel_dump(bp);
return;
}
@ -1632,6 +1639,9 @@ g_mirror_register_request(struct bio *bp)
default:
continue;
}
if (bp->bio_cmd == BIO_DELETE &&
(disk->d_flags & G_MIRROR_DISK_FLAG_CANDELETE) == 0)
continue;
cbp = g_clone_bio(bp);
if (cbp == NULL) {
for (cbp = bioq_first(&queue); cbp != NULL;

View File

@ -59,10 +59,12 @@
#define G_MIRROR_DISK_FLAG_INACTIVE 0x0000000000000008ULL
#define G_MIRROR_DISK_FLAG_HARDCODED 0x0000000000000010ULL
#define G_MIRROR_DISK_FLAG_BROKEN 0x0000000000000020ULL
#define G_MIRROR_DISK_FLAG_CANDELETE 0x0000000000000040ULL
#define G_MIRROR_DISK_FLAG_MASK (G_MIRROR_DISK_FLAG_DIRTY | \
G_MIRROR_DISK_FLAG_SYNCHRONIZING | \
G_MIRROR_DISK_FLAG_FORCE_SYNC | \
G_MIRROR_DISK_FLAG_INACTIVE)
G_MIRROR_DISK_FLAG_INACTIVE | \
G_MIRROR_DISK_FLAG_CANDELETE)
#define G_MIRROR_DEVICE_FLAG_NOAUTOSYNC 0x0000000000000001ULL
#define G_MIRROR_DEVICE_FLAG_NOFAILSYNC 0x0000000000000002ULL