Updates delete_method sysctl changes to always maintain disk d_flags

DISKFLAG_CANDELETE. While this change makes this layer consistent
other layers such as UFS and ZFS BIO_DELETE support may not notice
any change made manually via these device sysctls until the device
is reopened via a mount.

Also corrected var order in dadeletemethodsysctl

PR:		kern/169801
Reviewed by:	pjd (mentor)
Approved by:	mav
MFC after:	2 weeks
This commit is contained in:
smh 2013-01-10 11:57:46 +00:00
parent 7d5ba844df
commit 648c153a8f

View File

@ -863,6 +863,8 @@ static void daasync(void *callback_arg, u_int32_t code,
static void dasysctlinit(void *context, int pending); static void dasysctlinit(void *context, int pending);
static int dacmdsizesysctl(SYSCTL_HANDLER_ARGS); static int dacmdsizesysctl(SYSCTL_HANDLER_ARGS);
static int dadeletemethodsysctl(SYSCTL_HANDLER_ARGS); static int dadeletemethodsysctl(SYSCTL_HANDLER_ARGS);
static int dadeletemethodset(struct da_softc *softc,
da_delete_methods delete_method);
static periph_ctor_t daregister; static periph_ctor_t daregister;
static periph_dtor_t dacleanup; static periph_dtor_t dacleanup;
static periph_start_t dastart; static periph_start_t dastart;
@ -1489,7 +1491,7 @@ dasysctlinit(void *context, int pending)
*/ */
SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree), SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
OID_AUTO, "delete_method", CTLTYPE_STRING | CTLFLAG_RW, OID_AUTO, "delete_method", CTLTYPE_STRING | CTLFLAG_RW,
&softc->delete_method, 0, dadeletemethodsysctl, "A", softc, 0, dadeletemethodsysctl, "A",
"BIO_DELETE execution method"); "BIO_DELETE execution method");
SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree), SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
OID_AUTO, "minimum_cmd_size", CTLTYPE_INT | CTLFLAG_RW, OID_AUTO, "minimum_cmd_size", CTLTYPE_INT | CTLFLAG_RW,
@ -1565,15 +1567,34 @@ dacmdsizesysctl(SYSCTL_HANDLER_ARGS)
return (0); return (0);
} }
static int
dadeletemethodset(struct da_softc *softc, da_delete_methods delete_method)
{
if (delete_method < 0 || delete_method > DA_DELETE_MAX)
return (EINVAL);
softc->delete_method = delete_method;
if (softc->delete_method > DA_DELETE_DISABLE)
softc->disk->d_flags |= DISKFLAG_CANDELETE;
else
softc->disk->d_flags &= ~DISKFLAG_CANDELETE;
return (0);
}
static int static int
dadeletemethodsysctl(SYSCTL_HANDLER_ARGS) dadeletemethodsysctl(SYSCTL_HANDLER_ARGS)
{ {
char buf[16]; char buf[16];
int error;
const char *p; const char *p;
int i, value; struct da_softc *softc;
int i, error, value;
value = *(int *)arg1; softc = (struct da_softc *)arg1;
value = softc->delete_method;
if (value < 0 || value > DA_DELETE_MAX) if (value < 0 || value > DA_DELETE_MAX)
p = "UNKNOWN"; p = "UNKNOWN";
else else
@ -1585,8 +1606,7 @@ dadeletemethodsysctl(SYSCTL_HANDLER_ARGS)
for (i = 0; i <= DA_DELETE_MAX; i++) { for (i = 0; i <= DA_DELETE_MAX; i++) {
if (strcmp(buf, da_delete_method_names[i]) != 0) if (strcmp(buf, da_delete_method_names[i]) != 0)
continue; continue;
*(int *)arg1 = i; return dadeletemethodset(softc, i);
return (0);
} }
return (EINVAL); return (EINVAL);
} }
@ -2082,24 +2102,24 @@ cmd6workaround(union ccb *ccb)
if (softc->delete_method == DA_DELETE_UNMAP) { if (softc->delete_method == DA_DELETE_UNMAP) {
xpt_print(ccb->ccb_h.path, "UNMAP is not supported, " xpt_print(ccb->ccb_h.path, "UNMAP is not supported, "
"switching to WRITE SAME(16) with UNMAP.\n"); "switching to WRITE SAME(16) with UNMAP.\n");
softc->delete_method = DA_DELETE_WS16; dadeletemethodset(softc, DA_DELETE_WS16);
} else if (softc->delete_method == DA_DELETE_WS16) { } else if (softc->delete_method == DA_DELETE_WS16) {
xpt_print(ccb->ccb_h.path, xpt_print(ccb->ccb_h.path,
"WRITE SAME(16) with UNMAP is not supported, " "WRITE SAME(16) with UNMAP is not supported, "
"disabling BIO_DELETE.\n"); "disabling BIO_DELETE.\n");
softc->delete_method = DA_DELETE_DISABLE; dadeletemethodset(softc, DA_DELETE_DISABLE);
} else if (softc->delete_method == DA_DELETE_WS10) { } else if (softc->delete_method == DA_DELETE_WS10) {
xpt_print(ccb->ccb_h.path, xpt_print(ccb->ccb_h.path,
"WRITE SAME(10) with UNMAP is not supported, " "WRITE SAME(10) with UNMAP is not supported, "
"disabling BIO_DELETE.\n"); "disabling BIO_DELETE.\n");
softc->delete_method = DA_DELETE_DISABLE; dadeletemethodset(softc, DA_DELETE_DISABLE);
} else if (softc->delete_method == DA_DELETE_ZERO) { } else if (softc->delete_method == DA_DELETE_ZERO) {
xpt_print(ccb->ccb_h.path, xpt_print(ccb->ccb_h.path,
"WRITE SAME(10) is not supported, " "WRITE SAME(10) is not supported, "
"disabling BIO_DELETE.\n"); "disabling BIO_DELETE.\n");
softc->delete_method = DA_DELETE_DISABLE; dadeletemethodset(softc, DA_DELETE_DISABLE);
} else } else
softc->delete_method = DA_DELETE_DISABLE; dadeletemethodset(softc, DA_DELETE_DISABLE);
while ((bp = bioq_takefirst(&softc->delete_run_queue)) while ((bp = bioq_takefirst(&softc->delete_run_queue))
!= NULL) != NULL)
bioq_disksort(&softc->delete_queue, bp); bioq_disksort(&softc->delete_queue, bp);
@ -2345,7 +2365,7 @@ dadone(struct cam_periph *periph, union ccb *done_ccb)
rcaplong, sizeof(*rcaplong)); rcaplong, sizeof(*rcaplong));
if ((lalba & SRC16_LBPME_A) if ((lalba & SRC16_LBPME_A)
&& softc->delete_method == DA_DELETE_NONE) && softc->delete_method == DA_DELETE_NONE)
softc->delete_method = DA_DELETE_UNMAP; dadeletemethodset(softc, DA_DELETE_UNMAP);
dp = &softc->params; dp = &softc->params;
snprintf(announce_buf, sizeof(announce_buf), snprintf(announce_buf, sizeof(announce_buf),
"%juMB (%ju %u byte sectors: %dH %dS/T " "%juMB (%ju %u byte sectors: %dH %dS/T "