Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/fs/udf Enhance logical volume integrity descriptor handl...
details: https://anonhg.NetBSD.org/src/rev/4235182b8c69
branches: trunk
changeset: 834047:4235182b8c69
user: reinoud <reinoud%NetBSD.org@localhost>
date: Wed Jul 25 11:09:22 2018 +0000
description:
Enhance logical volume integrity descriptor handling and provide
bug-compatibility for Linux mkudffs 1.3 images.
diffstat:
sys/fs/udf/udf_subr.c | 61 ++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 48 insertions(+), 13 deletions(-)
diffs (133 lines):
diff -r 2e6dc36d4f41 -r 4235182b8c69 sys/fs/udf/udf_subr.c
--- a/sys/fs/udf/udf_subr.c Wed Jul 25 07:55:44 2018 +0000
+++ b/sys/fs/udf/udf_subr.c Wed Jul 25 11:09:22 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: udf_subr.c,v 1.141 2018/06/06 01:49:09 maya Exp $ */
+/* $NetBSD: udf_subr.c,v 1.142 2018/07/25 11:09:22 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.141 2018/06/06 01:49:09 maya Exp $");
+__KERNEL_RCSID(0, "$NetBSD: udf_subr.c,v 1.142 2018/07/25 11:09:22 reinoud Exp $");
#endif /* not lint */
@@ -1233,7 +1233,7 @@
/* are we linking to a new piece? */
if (dscr && lvint->next_extent.len) {
- len = udf_rw32(lvint->next_extent.len);
+ len = udf_rw32(lvint->next_extent.len);
lbnum = udf_rw32(lvint->next_extent.loc);
if (trace_len >= UDF_LVDINT_SEGMENTS-1) {
@@ -1279,7 +1279,7 @@
uint32_t out_ext, out_wpos, out_len;
uint32_t lb_num;
uint32_t len, start;
- int ext, minext, extlen, cnt, cpy_len, dscr_type;
+ int ext, sumext, extlen, cnt, cpy_len, dscr_type;
int losing;
int error;
@@ -1287,18 +1287,29 @@
/* search smallest extent */
trace = &ump->lvint_trace[0];
- minext = trace->end - trace->start;
+ sumext = trace->end - trace->start;
for (ext = 1; ext < UDF_LVDINT_SEGMENTS; ext++) {
trace = &ump->lvint_trace[ext];
extlen = trace->end - trace->start;
if (extlen == 0)
break;
- minext = MIN(minext, extlen);
- }
- losing = MIN(minext, UDF_LVINT_LOSSAGE);
- /* no sense wiping all */
- if (losing == minext)
- losing--;
+ sumext += extlen;
+ }
+
+ /* just one element? its not legal but be bug compatible */
+ if (sumext == 1) {
+ /* overwrite the only entry */
+ DPRINTF(VOLUMES, ("\tLinux bugcompat overwriting sole entry\n"));
+ trace = &ump->lvint_trace[0];
+ trace->wpos = 0;
+ return 0;
+ }
+
+ losing = MIN(sumext, UDF_LVINT_LOSSAGE);
+
+ /* no sense wiping too much */
+ if (sumext == UDF_LVINT_LOSSAGE)
+ losing = UDF_LVINT_LOSSAGE/2;
DPRINTF(VOLUMES, ("\tlosing %d entries\n", losing));
@@ -1435,7 +1446,6 @@
DPRINTF(VOLUMES, ("writing out logvol integrity descriptor\n"));
-again:
/* get free space in last chunk */
trace = ump->lvint_trace;
while (trace->wpos > (trace->end - trace->start)) {
@@ -1463,11 +1473,20 @@
if (space < 1) {
if (lvflag & UDF_APPENDONLY_LVINT)
return EROFS;
+
/* loose history by re-writing extents */
error = udf_loose_lvint_history(ump);
if (error)
return error;
- goto again;
+
+ trace = ump->lvint_trace;
+ while (trace->wpos > (trace->end - trace->start))
+ trace++;
+ space = (trace->end - trace->start) - trace->wpos;
+ DPRINTF(VOLUMES, ("new try: write start = %d, end = %d, "
+ "pos = %d, wpos = %d, "
+ "space = %d\n", trace->start, trace->end,
+ trace->pos, trace->wpos, space));
}
/* update our integrity descriptor to identify us and timestamp it */
@@ -1671,6 +1690,14 @@
DPRINTF(VOLUMES, ("Write unalloc. space bitmap %d\n",
lb_num + ptov));
dscr = (union dscrptr *) ump->part_unalloc_dscr[phys_part];
+
+ /* force a sane minimum for descriptors CRC length */
+ /* see UDF 2.3.1.2 and 2.3.8.1 */
+ KASSERT(udf_rw16(dscr->sbd.tag.id) == TAGID_SPACE_BITMAP);
+ if (udf_rw16(dscr->sbd.tag.desc_crc_len) == 0)
+ dscr->sbd.tag.desc_crc_len = udf_rw16(8);
+
+ /* write out space bitmap */
error = udf_write_phys_dscr_sync(ump, NULL, UDF_C_DSCR,
(union dscrptr *) dscr,
ptov + lb_num, lb_num);
@@ -1697,6 +1724,14 @@
DPRINTF(VOLUMES, ("Write freed space bitmap %d\n",
lb_num + ptov));
dscr = (union dscrptr *) ump->part_freed_dscr[phys_part];
+
+ /* force a sane minimum for descriptors CRC length */
+ /* see UDF 2.3.1.2 and 2.3.8.1 */
+ KASSERT(udf_rw16(dscr->sbd.tag.id) == TAGID_SPACE_BITMAP);
+ if (udf_rw16(dscr->sbd.tag.desc_crc_len) == 0)
+ dscr->sbd.tag.desc_crc_len = udf_rw16(8);
+
+ /* write out space bitmap */
error = udf_write_phys_dscr_sync(ump, NULL, UDF_C_DSCR,
(union dscrptr *) dscr,
ptov + lb_num, lb_num);
Home |
Main Index |
Thread Index |
Old Index