Module Name: src
Committed By: reinoud
Date: Tue May 24 09:55:57 UTC 2016
Modified Files:
src/sys/fs/udf: udf.h udf_readwrite.c udf_strat_bootstrap.c
udf_strat_direct.c udf_strat_rmw.c udf_strat_sequential.c
udf_subr.c udf_subr.h
Log Message:
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.
To generate a diff of this commit:
cvs rdiff -u -r1.51 -r1.52 src/sys/fs/udf/udf.h
cvs rdiff -u -r1.11 -r1.12 src/sys/fs/udf/udf_readwrite.c
cvs rdiff -u -r1.4 -r1.5 src/sys/fs/udf/udf_strat_bootstrap.c
cvs rdiff -u -r1.13 -r1.14 src/sys/fs/udf/udf_strat_direct.c
cvs rdiff -u -r1.27 -r1.28 src/sys/fs/udf/udf_strat_rmw.c
cvs rdiff -u -r1.14 -r1.15 src/sys/fs/udf/udf_strat_sequential.c
cvs rdiff -u -r1.137 -r1.138 src/sys/fs/udf/udf_subr.c
cvs rdiff -u -r1.19 -r1.20 src/sys/fs/udf/udf_subr.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/fs/udf/udf.h
diff -u src/sys/fs/udf/udf.h:1.51 src/sys/fs/udf/udf.h:1.52
--- src/sys/fs/udf/udf.h:1.51 Tue May 10 15:23:39 2016
+++ src/sys/fs/udf/udf.h Tue May 24 09:55:57 2016
@@ -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);
};
Index: src/sys/fs/udf/udf_readwrite.c
diff -u src/sys/fs/udf/udf_readwrite.c:1.11 src/sys/fs/udf/udf_readwrite.c:1.12
--- src/sys/fs/udf/udf_readwrite.c:1.11 Sun Jun 12 03:35:55 2011
+++ src/sys/fs/udf/udf_readwrite.c Tue May 24 09:55:57 2016
@@ -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 */
@@ -696,6 +696,19 @@ udf_discstrat_queuebuf(struct udf_mount
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)
{
struct udf_strategy *strategy = ump->strategy;
Index: src/sys/fs/udf/udf_strat_bootstrap.c
diff -u src/sys/fs/udf/udf_strat_bootstrap.c:1.4 src/sys/fs/udf/udf_strat_bootstrap.c:1.5
--- src/sys/fs/udf/udf_strat_bootstrap.c:1.4 Mon Nov 10 18:46:33 2014
+++ src/sys/fs/udf/udf_strat_bootstrap.c Tue May 24 09:55:57 2016
@@ -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_
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
};
Index: src/sys/fs/udf/udf_strat_direct.c
diff -u src/sys/fs/udf/udf_strat_direct.c:1.13 src/sys/fs/udf/udf_strat_direct.c:1.14
--- src/sys/fs/udf/udf_strat_direct.c:1.13 Tue Oct 6 08:57:34 2015
+++ src/sys/fs/udf/udf_strat_direct.c Tue May 24 09:55:57 2016
@@ -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 */
@@ -393,6 +393,15 @@ udf_queue_buf_direct(struct udf_strat_ar
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)
{
struct udf_mount *ump = args->ump;
@@ -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
};
Index: src/sys/fs/udf/udf_strat_rmw.c
diff -u src/sys/fs/udf/udf_strat_rmw.c:1.27 src/sys/fs/udf/udf_strat_rmw.c:1.28
--- src/sys/fs/udf/udf_strat_rmw.c:1.27 Tue Oct 6 08:57:34 2015
+++ src/sys/fs/udf/udf_strat_rmw.c Tue May 24 09:55:57 2016
@@ -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 *
/* --------------------------------------------------------------------- */
+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
};
Index: src/sys/fs/udf/udf_strat_sequential.c
diff -u src/sys/fs/udf/udf_strat_sequential.c:1.14 src/sys/fs/udf/udf_strat_sequential.c:1.15
--- src/sys/fs/udf/udf_strat_sequential.c:1.14 Tue Oct 6 08:57:34 2015
+++ src/sys/fs/udf/udf_strat_sequential.c Tue May 24 09:55:57 2016
@@ -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 *
/* --------------------------------------------------------------------- */
+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_
/* 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
};
Index: src/sys/fs/udf/udf_subr.c
diff -u src/sys/fs/udf/udf_subr.c:1.137 src/sys/fs/udf/udf_subr.c:1.138
--- src/sys/fs/udf/udf_subr.c:1.137 Tue May 10 15:23:39 2016
+++ src/sys/fs/udf/udf_subr.c Tue May 24 09:55:57 2016
@@ -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 *
}
-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,
/* 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,
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,
/* 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;
Index: src/sys/fs/udf/udf_subr.h
diff -u src/sys/fs/udf/udf_subr.h:1.19 src/sys/fs/udf/udf_subr.h:1.20
--- src/sys/fs/udf/udf_subr.h:1.19 Sun Jul 7 19:49:44 2013
+++ src/sys/fs/udf/udf_subr.h Tue May 24 09:55:57 2016
@@ -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 *
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);