Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/fs/udf Rework VAT searching on recordable media. It is n...
details: https://anonhg.NetBSD.org/src/rev/f3374bf1b0cf
branches: trunk
changeset: 345153:f3374bf1b0cf
user: reinoud <reinoud%NetBSD.org@localhost>
date: Tue May 10 15:23:39 2016 +0000
description:
Rework VAT searching on recordable media. It is now a lot more resilliant to
errors and it allows for VAT searching on crashed writeouts.
While here, make sure the node pointer is always initialised in
udf_get_node().
diffstat:
sys/fs/udf/udf.h | 5 +-
sys/fs/udf/udf_subr.c | 124 ++++++++++++++++++++++++++++++++++---------------
2 files changed, 88 insertions(+), 41 deletions(-)
diffs (210 lines):
diff -r 477d562d24f1 -r f3374bf1b0cf sys/fs/udf/udf.h
--- a/sys/fs/udf/udf.h Tue May 10 15:14:30 2016 +0000
+++ b/sys/fs/udf/udf.h Tue May 10 15:23:39 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: udf.h,v 1.50 2015/08/24 08:31:56 hannken Exp $ */
+/* $NetBSD: udf.h,v 1.51 2016/05/10 15:23:39 reinoud Exp $ */
/*
* Copyright (c) 2006, 2008 Reinoud Zandijk
@@ -417,11 +417,12 @@
#define IN_SYNCED 0x0200 /* node is being used by sync */
#define IN_CALLBACK_ULK 0x0400 /* node will be unlocked by callback */
#define IN_NODE_REBUILD 0x0800 /* node is rebuild */
+#define IN_NO_DELETE 0x1000 /* node is not to be deleted */
#define IN_FLAGBITS \
"\10\1IN_ACCESS\2IN_CHANGE\3IN_UPDATE\4IN_MODIFY\5IN_MODIFIED" \
"\6IN_ACCESSED\7IN_RENAME\10IN_DELETED\11IN_LOCKED\12IN_SYNCED" \
- "\13IN_CALLBACK_ULK\14IN_NODE_REBUILD"
+ "\13IN_CALLBACK_ULK\14IN_NODE_REBUILD\15IN_NO_DELETE"
#endif /* !_FS_UDF_UDF_H_ */
diff -r 477d562d24f1 -r f3374bf1b0cf sys/fs/udf/udf_subr.c
--- a/sys/fs/udf/udf_subr.c Tue May 10 15:14:30 2016 +0000
+++ b/sys/fs/udf/udf_subr.c Tue May 10 15:23:39 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: udf_subr.c,v 1.136 2016/01/27 00:06:49 reinoud Exp $ */
+/* $NetBSD: udf_subr.c,v 1.137 2016/05/10 15:23:39 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.136 2016/01/27 00:06:49 reinoud Exp $");
+__KERNEL_RCSID(0, "$NetBSD: udf_subr.c,v 1.137 2016/05/10 15:23:39 reinoud Exp $");
#endif /* not lint */
@@ -946,7 +946,7 @@
/* VATs are only recorded on sequential media, but initialise */
ump->first_possible_vat_location = track_start + 2;
- ump->last_possible_vat_location = track_end + last_track.packet_size;
+ ump->last_possible_vat_location = track_end;
return ok;
}
@@ -2995,6 +2995,10 @@
ump->logvol_integrity->integrity_type = udf_rw32(UDF_INTEGRITY_CLOSED);
ump->logvol_integrity->time = *mtime;
+ /* if we're updating, free old allocated space */
+ if (ump->vat_table)
+ free(ump->vat_table, M_UDFVOLD);
+
ump->vat_table_len = vat_length;
ump->vat_table_alloc_len = vat_table_alloc_len;
ump->vat_table = vat_table;
@@ -3017,49 +3021,70 @@
static int
udf_search_vat(struct udf_mount *ump, union udf_pmap *mapping)
{
- struct udf_node *vat_node;
+ struct udf_node *vat_node, *accepted_vat_node;
struct long_ad icb_loc;
- uint32_t early_vat_loc, vat_loc;
+ uint32_t early_vat_loc, late_vat_loc, vat_loc;
int error;
/* mapping info not needed */
mapping = mapping;
- vat_loc = ump->last_possible_vat_location;
- early_vat_loc = vat_loc - 256; /* 8 blocks of 32 sectors */
-
- DPRINTF(VOLUMES, ("1) last possible %d, early_vat_loc %d \n",
- vat_loc, early_vat_loc));
- early_vat_loc = MAX(early_vat_loc, ump->first_possible_vat_location);
-
- DPRINTF(VOLUMES, ("2) last possible %d, early_vat_loc %d \n",
- vat_loc, early_vat_loc));
-
- /* start looking from the end of the range */
+ DPRINTF(VOLUMES, ("Searching VAT\n"));
+
+ /*
+ * Start reading forward in blocks from the first possible vat
+ * location. If not found in this block, start again a bit before
+ * until we get a hit.
+ */
+ late_vat_loc = ump->last_possible_vat_location;
+ early_vat_loc = MAX(late_vat_loc - 64, ump->first_possible_vat_location);
+
+ DPRINTF(VOLUMES, ("\tfull range %d to %d\n", early_vat_loc, late_vat_loc));
+ accepted_vat_node = NULL;
do {
- DPRINTF(VOLUMES, ("Checking for VAT at sector %d\n", vat_loc));
- icb_loc.loc.part_num = udf_rw16(UDF_VTOP_RAWPART);
- icb_loc.loc.lb_num = udf_rw32(vat_loc);
-
- error = udf_get_node(ump, &icb_loc, &vat_node);
- if (!error) {
- error = udf_check_for_vat(vat_node);
- DPRINTFIF(VOLUMES, !error,
- ("VAT accepted at %d\n", vat_loc));
- if (!error)
- break;
- }
- if (vat_node) {
- vput(vat_node->vnode);
- vat_node = NULL;
- }
- vat_loc--; /* walk backwards */
- } while (vat_loc >= early_vat_loc);
-
- /* keep our VAT node around */
- if (vat_node) {
- UDF_SET_SYSTEMFILE(vat_node->vnode);
- ump->vat_node = vat_node;
+ vat_loc = early_vat_loc;
+ DPRINTF(VOLUMES, ("\tchecking range %d to %d\n",
+ early_vat_loc, late_vat_loc));
+ do {
+ DPRINTF(VOLUMES, ("\t\tChecking for VAT at sector %d\n",
+ vat_loc));
+ icb_loc.loc.part_num = udf_rw16(UDF_VTOP_RAWPART);
+ icb_loc.loc.lb_num = udf_rw32(vat_loc);
+
+ error = udf_get_node(ump, &icb_loc, &vat_node);
+ if (!error) {
+ error = udf_check_for_vat(vat_node);
+ vat_node->i_flags = 0; /* reset access */
+ }
+ if (!error) {
+ DPRINTFIF(VOLUMES, !error,
+ ("VAT candidate accepted at %d\n",
+ vat_loc));
+ if (accepted_vat_node)
+ vput(accepted_vat_node->vnode);
+ accepted_vat_node = vat_node;
+ accepted_vat_node->i_flags |= IN_NO_DELETE;
+ vat_node = NULL;
+ }
+ if (vat_node)
+ vput(vat_node->vnode);
+ vat_loc++; /* walk forward */
+ } while (vat_loc < late_vat_loc);
+ if (accepted_vat_node)
+ break;
+
+ early_vat_loc = MAX(early_vat_loc - 64, ump->first_possible_vat_location);
+ late_vat_loc = MIN(early_vat_loc + 64, ump->last_possible_vat_location);
+ } while (late_vat_loc > ump->first_possible_vat_location);
+
+ /* keep our last accepted VAT node around */
+ if (accepted_vat_node) {
+ /* revert no delete flag again to avoid potential side effects */
+ accepted_vat_node->i_flags &= ~IN_NO_DELETE;
+
+ UDF_SET_SYSTEMFILE(accepted_vat_node->vnode);
+ ump->vat_node = accepted_vat_node;
+ return 0;
}
return error;
@@ -3674,6 +3699,22 @@
/* determine data and metadata tracks again */
error = udf_search_writing_tracks(ump);
+
+ if (ump->lvclose & UDF_WRITE_VAT) {
+ /*
+ * we writeout the VAT to get a self-sustained session
+ * for fsck
+ */
+ DPRINTF(VOLUMES, ("lvclose & UDF_WRITE_VAT\n"));
+
+ /* 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);
+ }
}
/* mark it open */
@@ -5562,6 +5603,8 @@
int error;
struct vnode *vp;
+ *udf_noderes = NULL;
+
error = vcache_get(ump->vfs_mountp, &node_icb_loc->loc,
sizeof(node_icb_loc->loc), &vp);
if (error)
@@ -5927,6 +5970,9 @@
struct long_ad *loc;
int extnr, lvint, dummy;
+ if (udf_node->i_flags & IN_NO_DELETE)
+ return;
+
/* paranoia check on integrity; should be open!; we could panic */
lvint = udf_rw32(udf_node->ump->logvol_integrity->integrity_type);
if (lvint == UDF_INTEGRITY_CLOSED)
Home |
Main Index |
Thread Index |
Old Index