Cleanup VAT writout. To prevent issues with the sequential writing strategy
trying to write on blocks that are lost due to the synchronisation, don't just bluntly do synchronize device caches, but split out on strategies.
This commit is contained in:
parent
6e3cf83f8e
commit
42866dd28d
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: udf.h,v 1.51 2016/05/10 15:23:39 reinoud Exp $ */
|
||||
/* $NetBSD: udf.h,v 1.52 2016/05/24 09:55:57 reinoud Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006, 2008 Reinoud Zandijk
|
||||
@ -76,7 +76,7 @@ extern int udf_verbose;
|
||||
#define UDF_DEBUG_RESERVE 0x1000000
|
||||
|
||||
/* initial value of udf_verbose */
|
||||
#define UDF_DEBUGGING 0
|
||||
#define UDF_DEBUGGING (0)
|
||||
|
||||
#ifdef UDF_DEBUG
|
||||
#define DPRINTF(name, arg) { \
|
||||
@ -252,6 +252,7 @@ struct udf_strategy {
|
||||
int (*read_logvol_dscr) (struct udf_strat_args *args);
|
||||
int (*write_logvol_dscr) (struct udf_strat_args *args);
|
||||
void (*queuebuf) (struct udf_strat_args *args);
|
||||
void (*sync_caches) (struct udf_strat_args *args);
|
||||
void (*discstrat_init) (struct udf_strat_args *args);
|
||||
void (*discstrat_finish) (struct udf_strat_args *args);
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: udf_readwrite.c,v 1.11 2011/06/12 03:35:55 rmind Exp $ */
|
||||
/* $NetBSD: udf_readwrite.c,v 1.12 2016/05/24 09:55:57 reinoud Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007, 2008 Reinoud Zandijk
|
||||
@ -28,7 +28,7 @@
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__KERNEL_RCSID(0, "$NetBSD: udf_readwrite.c,v 1.11 2011/06/12 03:35:55 rmind Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: udf_readwrite.c,v 1.12 2016/05/24 09:55:57 reinoud Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
|
||||
@ -695,6 +695,19 @@ udf_discstrat_queuebuf(struct udf_mount *ump, struct buf *nestbuf)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
udf_synchronise_caches(struct udf_mount *ump)
|
||||
{
|
||||
struct udf_strategy *strategy = ump->strategy;
|
||||
struct udf_strat_args args;
|
||||
|
||||
KASSERT(strategy);
|
||||
args.ump = ump;
|
||||
|
||||
(strategy->sync_caches)(&args);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
udf_discstrat_init(struct udf_mount *ump)
|
||||
{
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: udf_strat_bootstrap.c,v 1.4 2014/11/10 18:46:33 maxv Exp $ */
|
||||
/* $NetBSD: udf_strat_bootstrap.c,v 1.5 2016/05/24 09:55:57 reinoud Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006, 2008 Reinoud Zandijk
|
||||
@ -28,7 +28,7 @@
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__KERNEL_RCSID(0, "$NetBSD: udf_strat_bootstrap.c,v 1.4 2014/11/10 18:46:33 maxv Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: udf_strat_bootstrap.c,v 1.5 2016/05/24 09:55:57 reinoud Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
|
||||
@ -115,6 +115,14 @@ udf_queuebuf_bootstrap(struct udf_strat_args *args)
|
||||
VOP_STRATEGY(ump->devvp, buf);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
udf_sync_caches_bootstrap(struct udf_strat_args *args)
|
||||
{
|
||||
/* empty */
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
udf_discstrat_init_bootstrap(struct udf_strat_args *args)
|
||||
{
|
||||
@ -137,6 +145,7 @@ struct udf_strategy udf_strat_bootstrap =
|
||||
udf_read_logvol_dscr_bootstrap,
|
||||
udf_write_logvol_dscr_bootstrap,
|
||||
udf_queuebuf_bootstrap,
|
||||
udf_sync_caches_bootstrap,
|
||||
udf_discstrat_init_bootstrap,
|
||||
udf_discstrat_finish_bootstrap
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: udf_strat_direct.c,v 1.13 2015/10/06 08:57:34 hannken Exp $ */
|
||||
/* $NetBSD: udf_strat_direct.c,v 1.14 2016/05/24 09:55:57 reinoud Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006, 2008 Reinoud Zandijk
|
||||
@ -28,7 +28,7 @@
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__KERNEL_RCSID(0, "$NetBSD: udf_strat_direct.c,v 1.13 2015/10/06 08:57:34 hannken Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: udf_strat_direct.c,v 1.14 2016/05/24 09:55:57 reinoud Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
|
||||
@ -392,6 +392,15 @@ udf_queue_buf_direct(struct udf_strat_args *args)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
udf_sync_caches_direct(struct udf_strat_args *args)
|
||||
{
|
||||
struct udf_mount *ump = args->ump;
|
||||
|
||||
udf_mmc_synchronise_caches(ump);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
udf_discstrat_init_direct(struct udf_strat_args *args)
|
||||
{
|
||||
@ -441,6 +450,7 @@ struct udf_strategy udf_strat_direct =
|
||||
udf_read_nodedscr_direct,
|
||||
udf_write_nodedscr_direct,
|
||||
udf_queue_buf_direct,
|
||||
udf_sync_caches_direct,
|
||||
udf_discstrat_init_direct,
|
||||
udf_discstrat_finish_direct
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: udf_strat_rmw.c,v 1.27 2015/10/06 08:57:34 hannken Exp $ */
|
||||
/* $NetBSD: udf_strat_rmw.c,v 1.28 2016/05/24 09:55:57 reinoud Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006, 2008 Reinoud Zandijk
|
||||
@ -28,7 +28,7 @@
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__KERNEL_RCSID(0, "$NetBSD: udf_strat_rmw.c,v 1.27 2015/10/06 08:57:34 hannken Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: udf_strat_rmw.c,v 1.28 2016/05/24 09:55:57 reinoud Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
|
||||
@ -1005,6 +1005,16 @@ udf_queuebuf_rmw(struct udf_strat_args *args)
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
udf_sync_caches_rmw(struct udf_strat_args *args)
|
||||
{
|
||||
struct udf_mount *ump = args->ump;
|
||||
|
||||
udf_mmc_synchronise_caches(ump);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
udf_shedule_read_callback(struct buf *buf)
|
||||
{
|
||||
@ -1495,6 +1505,7 @@ struct udf_strategy udf_strat_rmw =
|
||||
udf_read_nodedscr_rmw,
|
||||
udf_write_nodedscr_rmw,
|
||||
udf_queuebuf_rmw,
|
||||
udf_sync_caches_rmw,
|
||||
udf_discstrat_init_rmw,
|
||||
udf_discstrat_finish_rmw
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: udf_strat_sequential.c,v 1.14 2015/10/06 08:57:34 hannken Exp $ */
|
||||
/* $NetBSD: udf_strat_sequential.c,v 1.15 2016/05/24 09:55:57 reinoud Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006, 2008 Reinoud Zandijk
|
||||
@ -28,7 +28,7 @@
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__KERNEL_RCSID(0, "$NetBSD: udf_strat_sequential.c,v 1.14 2015/10/06 08:57:34 hannken Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: udf_strat_sequential.c,v 1.15 2016/05/24 09:55:57 reinoud Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
|
||||
@ -86,6 +86,7 @@ struct strat_private {
|
||||
kmutex_t discstrat_mutex; /* disc strategy */
|
||||
|
||||
int run_thread; /* thread control */
|
||||
int sync_req; /* thread control */
|
||||
int cur_queue;
|
||||
|
||||
struct disk_strategy old_strategy_setting;
|
||||
@ -287,6 +288,30 @@ udf_queuebuf_seq(struct udf_strat_args *args)
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
udf_sync_caches_seq(struct udf_strat_args *args)
|
||||
{
|
||||
struct udf_mount *ump = args->ump;
|
||||
struct strat_private *priv = PRIV(ump);
|
||||
|
||||
/* we might be called during unmount inadvertedly, be on safe side */
|
||||
if (!priv)
|
||||
return;
|
||||
|
||||
/* signal our thread that there might be something to do */
|
||||
priv->sync_req = 1;
|
||||
cv_signal(&priv->discstrat_cv);
|
||||
|
||||
mutex_enter(&priv->discstrat_mutex);
|
||||
while (priv->sync_req) {
|
||||
cv_timedwait(&priv->discstrat_cv,
|
||||
&priv->discstrat_mutex, hz/8);
|
||||
}
|
||||
mutex_exit(&priv->discstrat_mutex);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
/* TODO convert to lb_size */
|
||||
static void
|
||||
udf_VAT_mapping_update(struct udf_mount *ump, struct buf *buf, uint32_t lb_map)
|
||||
@ -539,7 +564,7 @@ udf_discstrat_thread(void *arg)
|
||||
|
||||
empty = 1;
|
||||
mutex_enter(&priv->discstrat_mutex);
|
||||
while (priv->run_thread || !empty) {
|
||||
while (priv->run_thread || !empty || priv->sync_req) {
|
||||
/* process the current selected queue */
|
||||
udf_doshedule(ump);
|
||||
empty = (bufq_peek(priv->queues[UDF_SHED_READING]) == NULL);
|
||||
@ -547,9 +572,16 @@ udf_discstrat_thread(void *arg)
|
||||
empty &= (bufq_peek(priv->queues[UDF_SHED_SEQWRITING]) == NULL);
|
||||
|
||||
/* wait for more if needed */
|
||||
if (empty)
|
||||
if (empty) {
|
||||
if (priv->sync_req) {
|
||||
/* on sync, we need to simulate a read->write transition */
|
||||
udf_mmc_synchronise_caches(ump);
|
||||
priv->cur_queue = UDF_SHED_READING;
|
||||
priv->sync_req = 0;
|
||||
}
|
||||
cv_timedwait(&priv->discstrat_cv,
|
||||
&priv->discstrat_mutex, hz/8);
|
||||
}
|
||||
}
|
||||
mutex_exit(&priv->discstrat_mutex);
|
||||
|
||||
@ -621,6 +653,7 @@ udf_discstrat_init_seq(struct udf_strat_args *args)
|
||||
|
||||
/* create our disk strategy thread */
|
||||
priv->run_thread = 1;
|
||||
priv->sync_req = 0;
|
||||
if (kthread_create(PRI_NONE, 0 /* KTHREAD_MPSAFE*/, NULL /* cpu_info*/,
|
||||
udf_discstrat_thread, ump, &priv->queue_lwp,
|
||||
"%s", "udf_rw")) {
|
||||
@ -673,6 +706,7 @@ struct udf_strategy udf_strat_sequential =
|
||||
udf_read_logvol_dscr_seq,
|
||||
udf_write_logvol_dscr_seq,
|
||||
udf_queuebuf_seq,
|
||||
udf_sync_caches_seq,
|
||||
udf_discstrat_init_seq,
|
||||
udf_discstrat_finish_seq
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: udf_subr.c,v 1.137 2016/05/10 15:23:39 reinoud Exp $ */
|
||||
/* $NetBSD: udf_subr.c,v 1.138 2016/05/24 09:55:57 reinoud Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006, 2008 Reinoud Zandijk
|
||||
@ -29,7 +29,7 @@
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__KERNEL_RCSID(0, "$NetBSD: udf_subr.c,v 1.137 2016/05/10 15:23:39 reinoud Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: udf_subr.c,v 1.138 2016/05/24 09:55:57 reinoud Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
|
||||
@ -319,27 +319,25 @@ udf_setup_writeparams(struct udf_mount *ump)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
udf_synchronise_caches(struct udf_mount *ump)
|
||||
void
|
||||
udf_mmc_synchronise_caches(struct udf_mount *ump)
|
||||
{
|
||||
struct mmc_op mmc_op;
|
||||
|
||||
DPRINTF(CALL, ("udf_synchronise_caches()\n"));
|
||||
DPRINTF(CALL, ("udf_mcc_synchronise_caches()\n"));
|
||||
|
||||
if (ump->vfs_mountp->mnt_flag & MNT_RDONLY)
|
||||
return 0;
|
||||
return;
|
||||
|
||||
/* discs are done now */
|
||||
if (ump->discinfo.mmc_class == MMC_CLASS_DISC)
|
||||
return 0;
|
||||
return;
|
||||
|
||||
memset(&mmc_op, 0, sizeof(struct mmc_op));
|
||||
mmc_op.operation = MMC_OP_SYNCHRONISECACHE;
|
||||
|
||||
/* ignore return code */
|
||||
(void) VOP_IOCTL(ump->devvp, MMCOP, &mmc_op, FKIOCTL, NOCRED);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
@ -2833,7 +2831,6 @@ udf_writeout_vat(struct udf_mount *ump)
|
||||
if (error)
|
||||
printf("udf_writeout_vat: error writing VAT node!\n");
|
||||
out:
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -3710,10 +3707,9 @@ udf_open_logvol(struct udf_mount *ump)
|
||||
/* write out the VAT data and all its descriptors */
|
||||
DPRINTF(VOLUMES, ("writeout vat_node\n"));
|
||||
udf_writeout_vat(ump);
|
||||
vflushbuf(ump->vat_node->vnode, 1 /* sync */);
|
||||
|
||||
(void) VOP_FSYNC(ump->vat_node->vnode,
|
||||
FSCRED, FSYNC_WAIT, 0, 0);
|
||||
/* force everything to be synchronized on the device */
|
||||
(void) udf_synchronise_caches(ump);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3763,15 +3759,6 @@ udf_close_logvol(struct udf_mount *ump, int mntflags)
|
||||
/* write out the VAT data and all its descriptors */
|
||||
DPRINTF(VOLUMES, ("writeout vat_node\n"));
|
||||
udf_writeout_vat(ump);
|
||||
(void) vflushbuf(ump->vat_node->vnode, FSYNC_WAIT);
|
||||
|
||||
(void) VOP_FSYNC(ump->vat_node->vnode,
|
||||
FSCRED, FSYNC_WAIT, 0, 0);
|
||||
|
||||
if (ump->lvclose & UDF_CLOSE_SESSION) {
|
||||
DPRINTF(VOLUMES, ("udf_close_logvol: closing session "
|
||||
"as requested\n"));
|
||||
}
|
||||
|
||||
/* at least two DVD packets and 3 CD-R packets */
|
||||
nvats = 32;
|
||||
@ -3806,6 +3793,9 @@ udf_close_logvol(struct udf_mount *ump, int mntflags)
|
||||
if (!error)
|
||||
nok++;
|
||||
}
|
||||
/* force everything to be synchronized on the device */
|
||||
(void) udf_synchronise_caches(ump);
|
||||
|
||||
if (nok < 14) {
|
||||
/* arbitrary; but at least one or two CD frames */
|
||||
printf("writeout of at least 14 VATs failed\n");
|
||||
@ -3817,6 +3807,8 @@ udf_close_logvol(struct udf_mount *ump, int mntflags)
|
||||
|
||||
/* finish closing of session */
|
||||
if (ump->lvclose & UDF_CLOSE_SESSION) {
|
||||
DPRINTF(VOLUMES, ("udf_close_logvol: closing session "
|
||||
"as requested\n"));
|
||||
error = udf_validate_session_start(ump);
|
||||
if (error)
|
||||
return error;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: udf_subr.h,v 1.19 2013/07/07 19:49:44 reinoud Exp $ */
|
||||
/* $NetBSD: udf_subr.h,v 1.20 2016/05/24 09:55:57 reinoud Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006, 2008 Reinoud Zandijk
|
||||
@ -40,7 +40,8 @@ int udf_search_tracks(struct udf_mount *ump, struct udf_args *args,
|
||||
int *first_tracknr, int *last_tracknr);
|
||||
int udf_search_writing_tracks(struct udf_mount *ump);
|
||||
int udf_setup_writeparams(struct udf_mount *ump);
|
||||
int udf_synchronise_caches(struct udf_mount *ump);
|
||||
void udf_mmc_synchronise_caches(struct udf_mount *ump);
|
||||
void udf_synchronise_caches(struct udf_mount *ump);
|
||||
|
||||
/* tags operations */
|
||||
int udf_fidsize(struct fileid_desc *fid);
|
||||
|
Loading…
Reference in New Issue
Block a user