Support for allocation extents descriptor writing to allow for arbitrary
heavily fragmented files. Also fixing some (rare) allocation bugs and function name streamlining. Tested on harddisc, CD-RW and CD-R i.e. all three basic backend classes.
This commit is contained in:
parent
a25c030645
commit
4d5c88faa5
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: udf.h,v 1.16 2008/07/03 19:29:42 reinoud Exp $ */
|
||||
/* $NetBSD: udf.h,v 1.17 2008/07/07 18:45:26 reinoud Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006, 2008 Reinoud Zandijk
|
||||
@ -64,12 +64,13 @@ extern int udf_verbose;
|
||||
#define UDF_DEBUG_EXTATTR 0x002000
|
||||
#define UDF_DEBUG_ALLOC 0x004000
|
||||
#define UDF_DEBUG_ADWLK 0x008000
|
||||
#define UDF_DEBUG_NOTIMPL 0x010000
|
||||
#define UDF_DEBUG_SHEDULE 0x020000
|
||||
#define UDF_DEBUG_ECCLINE 0x040000
|
||||
#define UDF_DEBUG_SYNC 0x080000
|
||||
#define UDF_DEBUG_PARANOIA 0x100000
|
||||
#define UDF_DEBUG_NODEDUMP 0x200000
|
||||
#define UDF_DEBUG_PARANOIDADWLK 0x010000
|
||||
#define UDF_DEBUG_NOTIMPL 0x020000
|
||||
#define UDF_DEBUG_SHEDULE 0x040000
|
||||
#define UDF_DEBUG_ECCLINE 0x080000
|
||||
#define UDF_DEBUG_SYNC 0x100000
|
||||
#define UDF_DEBUG_PARANOIA 0x200000
|
||||
#define UDF_DEBUG_NODEDUMP 0x400000
|
||||
|
||||
/* initial value of udf_verbose */
|
||||
#define UDF_DEBUGGING 0
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: udf_allocation.c,v 1.10 2008/07/03 18:03:01 reinoud Exp $ */
|
||||
/* $NetBSD: udf_allocation.c,v 1.11 2008/07/07 18:45:26 reinoud Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006, 2008 Reinoud Zandijk
|
||||
@ -28,7 +28,7 @@
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__KERNEL_RCSID(0, "$NetBSD: udf_allocation.c,v 1.10 2008/07/03 18:03:01 reinoud Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: udf_allocation.c,v 1.11 2008/07/07 18:45:26 reinoud Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
|
||||
@ -86,7 +86,7 @@ static void udf_record_allocation_in_node(struct udf_mount *ump,
|
||||
*/
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
//#ifdef DEBUG
|
||||
|
||||
#if 1
|
||||
#if 1
|
||||
static void
|
||||
@ -94,14 +94,13 @@ udf_node_dump(struct udf_node *udf_node) {
|
||||
struct file_entry *fe;
|
||||
struct extfile_entry *efe;
|
||||
struct icb_tag *icbtag;
|
||||
struct short_ad *short_ad;
|
||||
struct long_ad *long_ad;
|
||||
struct long_ad s_ad;
|
||||
uint64_t inflen;
|
||||
uint32_t icbflags, addr_type, max_l_ad;
|
||||
uint32_t icbflags, addr_type;
|
||||
uint32_t len, lb_num;
|
||||
uint8_t *data_pos;
|
||||
uint32_t flags;
|
||||
int part_num;
|
||||
int adlen, ad_off, dscr_size, l_ea, l_ad, lb_size, flags;
|
||||
int lb_size, eof, slot;
|
||||
|
||||
if ((udf_verbose & UDF_DEBUG_NODEDUMP) == 0)
|
||||
return;
|
||||
@ -113,57 +112,35 @@ udf_node_dump(struct udf_node *udf_node) {
|
||||
if (fe) {
|
||||
icbtag = &fe->icbtag;
|
||||
inflen = udf_rw64(fe->inf_len);
|
||||
dscr_size = sizeof(struct file_entry) -1;
|
||||
l_ea = udf_rw32(fe->l_ea);
|
||||
l_ad = udf_rw32(fe->l_ad);
|
||||
data_pos = (uint8_t *) fe + dscr_size + l_ea;
|
||||
} else {
|
||||
icbtag = &efe->icbtag;
|
||||
inflen = udf_rw64(efe->inf_len);
|
||||
dscr_size = sizeof(struct extfile_entry) -1;
|
||||
l_ea = udf_rw32(efe->l_ea);
|
||||
l_ad = udf_rw32(efe->l_ad);
|
||||
data_pos = (uint8_t *) efe + dscr_size + l_ea;
|
||||
}
|
||||
max_l_ad = lb_size - dscr_size - l_ea;
|
||||
|
||||
icbflags = udf_rw16(icbtag->flags);
|
||||
addr_type = icbflags & UDF_ICB_TAG_FLAGS_ALLOC_MASK;
|
||||
|
||||
printf("udf_node_dump:\n");
|
||||
printf("\tudf_node %p\n", udf_node);
|
||||
printf("udf_node_dump %p :\n", udf_node);
|
||||
|
||||
if (addr_type == UDF_ICB_INTERN_ALLOC) {
|
||||
printf("\t\tIntern alloc, len = %"PRIu64"\n", inflen);
|
||||
printf("\tIntern alloc, len = %"PRIu64"\n", inflen);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("\t\tInflen = %"PRIu64"\n", inflen);
|
||||
printf("\t\tl_ad = %d\n", l_ad);
|
||||
|
||||
if (addr_type == UDF_ICB_SHORT_ALLOC) {
|
||||
adlen = sizeof(struct short_ad);
|
||||
} else {
|
||||
adlen = sizeof(struct long_ad);
|
||||
}
|
||||
|
||||
printf("\tInflen = %"PRIu64"\n", inflen);
|
||||
printf("\t\t");
|
||||
for (ad_off = 0; ad_off < l_ad; ad_off += adlen) {
|
||||
if (addr_type == UDF_ICB_SHORT_ALLOC) {
|
||||
short_ad = (struct short_ad *) (data_pos + ad_off);
|
||||
len = udf_rw32(short_ad->len);
|
||||
lb_num = udf_rw32(short_ad->lb_num);
|
||||
part_num = -1;
|
||||
flags = UDF_EXT_FLAGS(len);
|
||||
len = UDF_EXT_LEN(len);
|
||||
} else {
|
||||
long_ad = (struct long_ad *) (data_pos + ad_off);
|
||||
len = udf_rw32(long_ad->len);
|
||||
lb_num = udf_rw32(long_ad->loc.lb_num);
|
||||
part_num = udf_rw16(long_ad->loc.part_num);
|
||||
flags = UDF_EXT_FLAGS(len);
|
||||
len = UDF_EXT_LEN(len);
|
||||
}
|
||||
|
||||
slot = 0;
|
||||
for (;;) {
|
||||
udf_get_adslot(udf_node, slot, &s_ad, &eof);
|
||||
if (eof)
|
||||
break;
|
||||
part_num = udf_rw16(s_ad.loc.part_num);
|
||||
lb_num = udf_rw32(s_ad.loc.lb_num);
|
||||
len = udf_rw32(s_ad.len);
|
||||
flags = UDF_EXT_FLAGS(len);
|
||||
len = UDF_EXT_LEN(len);
|
||||
|
||||
printf("[");
|
||||
if (part_num >= 0)
|
||||
printf("part %d, ", part_num);
|
||||
@ -171,10 +148,14 @@ udf_node_dump(struct udf_node *udf_node) {
|
||||
if (flags)
|
||||
printf(", flags %d", flags>>30);
|
||||
printf("] ");
|
||||
if (ad_off + adlen == l_ad)
|
||||
printf("\n\t\tl_ad END\n\t\t");
|
||||
|
||||
if (flags == UDF_EXT_REDIRECT) {
|
||||
printf("\n\textent END\n\tallocation extent\n\t\t");
|
||||
}
|
||||
|
||||
slot++;
|
||||
}
|
||||
printf("\n");
|
||||
printf("\n\tl_ad END\n\n");
|
||||
}
|
||||
#else
|
||||
#define udf_node_dump(a)
|
||||
@ -258,14 +239,13 @@ udf_node_sanity_check(struct udf_node *udf_node,
|
||||
struct file_entry *fe;
|
||||
struct extfile_entry *efe;
|
||||
struct icb_tag *icbtag;
|
||||
struct short_ad *short_ad;
|
||||
struct long_ad *long_ad;
|
||||
struct long_ad s_ad;
|
||||
uint64_t inflen, logblksrec;
|
||||
uint32_t icbflags, addr_type, max_l_ad;
|
||||
uint32_t len, lb_num;
|
||||
uint8_t *data_pos;
|
||||
uint32_t icbflags, addr_type;
|
||||
uint32_t len, lb_num, l_ea, l_ad, max_l_ad;
|
||||
uint16_t part_num;
|
||||
int adlen, ad_off, dscr_size, l_ea, l_ad, lb_size, flags, whole_lb;
|
||||
int dscr_size, lb_size, flags, whole_lb;
|
||||
int slot, eof;
|
||||
|
||||
// KASSERT(mutex_owned(&udf_node->ump->allocate_mutex));
|
||||
|
||||
@ -279,21 +259,19 @@ udf_node_sanity_check(struct udf_node *udf_node,
|
||||
if (fe) {
|
||||
icbtag = &fe->icbtag;
|
||||
inflen = udf_rw64(fe->inf_len);
|
||||
logblksrec = udf_rw64(fe->logblks_rec);
|
||||
dscr_size = sizeof(struct file_entry) -1;
|
||||
l_ea = udf_rw32(fe->l_ea);
|
||||
logblksrec = udf_rw64(fe->logblks_rec);
|
||||
l_ad = udf_rw32(fe->l_ad);
|
||||
data_pos = (uint8_t *) fe + dscr_size + l_ea;
|
||||
l_ea = udf_rw32(fe->l_ea);
|
||||
} else {
|
||||
icbtag = &efe->icbtag;
|
||||
inflen = udf_rw64(efe->inf_len);
|
||||
logblksrec = udf_rw64(efe->logblks_rec);
|
||||
dscr_size = sizeof(struct extfile_entry) -1;
|
||||
l_ea = udf_rw32(efe->l_ea);
|
||||
logblksrec = udf_rw64(efe->logblks_rec);
|
||||
l_ad = udf_rw32(efe->l_ad);
|
||||
data_pos = (uint8_t *) efe + dscr_size + l_ea;
|
||||
l_ea = udf_rw32(efe->l_ea);
|
||||
}
|
||||
max_l_ad = lb_size - dscr_size - l_ea;
|
||||
max_l_ad = lb_size - dscr_size - l_ea;
|
||||
icbflags = udf_rw16(icbtag->flags);
|
||||
addr_type = icbflags & UDF_ICB_TAG_FLAGS_ALLOC_MASK;
|
||||
|
||||
@ -308,31 +286,21 @@ udf_node_sanity_check(struct udf_node *udf_node,
|
||||
return;
|
||||
}
|
||||
|
||||
if (addr_type == UDF_ICB_SHORT_ALLOC) {
|
||||
adlen = sizeof(struct short_ad);
|
||||
} else {
|
||||
adlen = sizeof(struct long_ad);
|
||||
}
|
||||
|
||||
/* start counting */
|
||||
whole_lb = 1;
|
||||
for (ad_off = 0; ad_off < l_ad; ad_off += adlen) {
|
||||
slot = 0;
|
||||
for (;;) {
|
||||
udf_get_adslot(udf_node, slot, &s_ad, &eof);
|
||||
if (eof)
|
||||
break;
|
||||
KASSERT(whole_lb == 1);
|
||||
if (addr_type == UDF_ICB_SHORT_ALLOC) {
|
||||
short_ad = (struct short_ad *) (data_pos + ad_off);
|
||||
len = udf_rw32(short_ad->len);
|
||||
lb_num = udf_rw32(short_ad->lb_num);
|
||||
part_num = udf_rw16(udf_node->loc.loc.part_num);
|
||||
flags = UDF_EXT_FLAGS(len);
|
||||
len = UDF_EXT_LEN(len);
|
||||
} else {
|
||||
long_ad = (struct long_ad *) (data_pos + ad_off);
|
||||
len = udf_rw32(long_ad->len);
|
||||
lb_num = udf_rw32(long_ad->loc.lb_num);
|
||||
part_num = udf_rw16(long_ad->loc.part_num);
|
||||
flags = UDF_EXT_FLAGS(len);
|
||||
len = UDF_EXT_LEN(len);
|
||||
}
|
||||
|
||||
part_num = udf_rw16(s_ad.loc.part_num);
|
||||
lb_num = udf_rw32(s_ad.loc.lb_num);
|
||||
len = udf_rw32(s_ad.len);
|
||||
flags = UDF_EXT_FLAGS(len);
|
||||
len = UDF_EXT_LEN(len);
|
||||
|
||||
if (flags != UDF_EXT_REDIRECT) {
|
||||
*cnt_inflen += len;
|
||||
if (flags == UDF_EXT_ALLOCATED) {
|
||||
@ -348,6 +316,8 @@ udf_node_sanity_check(struct udf_node *udf_node,
|
||||
|
||||
/* check whole lb */
|
||||
whole_lb = ((len % lb_size) == 0);
|
||||
|
||||
slot++;
|
||||
}
|
||||
/* rest should be zero (ad_off > l_ad < max_l_ad - adlen) */
|
||||
|
||||
@ -1280,6 +1250,7 @@ udf_wipe_adslots(struct udf_node *udf_node)
|
||||
for (extnr = 0; extnr < udf_node->num_extensions; extnr++) {
|
||||
ext = udf_node->ext[extnr];
|
||||
dscr_size = sizeof(struct alloc_ext_entry) -1;
|
||||
data_pos = (uint8_t *) ext->data;
|
||||
max_l_ad = lb_size - dscr_size;
|
||||
memset(data_pos, 0, max_l_ad);
|
||||
ext->l_ad = udf_rw32(0);
|
||||
@ -1287,6 +1258,7 @@ udf_wipe_adslots(struct udf_node *udf_node)
|
||||
crclen = dscr_size - UDF_DESC_TAG_LENGTH;
|
||||
ext->tag.desc_crc_len = udf_rw32(crclen);
|
||||
}
|
||||
udf_node->i_flags |= IN_NODE_REBUILD;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
@ -1299,9 +1271,9 @@ udf_get_adslot(struct udf_node *udf_node, int slot, struct long_ad *icb,
|
||||
struct alloc_ext_entry *ext;
|
||||
struct icb_tag *icbtag;
|
||||
struct short_ad *short_ad;
|
||||
struct long_ad *long_ad;
|
||||
struct long_ad *long_ad, l_icb;
|
||||
uint32_t offset;
|
||||
uint32_t lb_size, dscr_size, l_ea, l_ad, max_l_ad;
|
||||
uint32_t lb_size, dscr_size, l_ea, l_ad, flags;
|
||||
uint8_t *data_pos;
|
||||
int icbflags, addr_type, adlen, extnr;
|
||||
|
||||
@ -1323,7 +1295,6 @@ udf_get_adslot(struct udf_node *udf_node, int slot, struct long_ad *icb,
|
||||
l_ad = udf_rw32(efe->l_ad);
|
||||
data_pos = (uint8_t *) efe + dscr_size + l_ea;
|
||||
}
|
||||
max_l_ad = lb_size - dscr_size - l_ea;
|
||||
|
||||
icbflags = udf_rw16(icbtag->flags);
|
||||
addr_type = icbflags & UDF_ICB_TAG_FLAGS_ALLOC_MASK;
|
||||
@ -1345,22 +1316,42 @@ udf_get_adslot(struct udf_node *udf_node, int slot, struct long_ad *icb,
|
||||
/* if offset too big, we go to the allocation extensions */
|
||||
offset = slot * adlen;
|
||||
extnr = -1;
|
||||
while (offset >= max_l_ad) {
|
||||
extnr++;
|
||||
offset -= max_l_ad;
|
||||
ext = udf_node->ext[extnr];
|
||||
dscr_size = sizeof(struct alloc_ext_entry) -1;
|
||||
l_ad = udf_rw32(ext->l_ad);
|
||||
max_l_ad = lb_size - dscr_size;
|
||||
data_pos = (uint8_t *) ext + dscr_size;
|
||||
if (extnr > udf_node->num_extensions) {
|
||||
while (offset >= l_ad) {
|
||||
/* check if our last entry is a redirect */
|
||||
if (addr_type == UDF_ICB_SHORT_ALLOC) {
|
||||
short_ad = (struct short_ad *) (data_pos + l_ad-adlen);
|
||||
l_icb.len = short_ad->len;
|
||||
l_icb.loc.part_num = udf_node->loc.loc.part_num;
|
||||
l_icb.loc.lb_num = short_ad->lb_num;
|
||||
} else {
|
||||
KASSERT(addr_type == UDF_ICB_LONG_ALLOC);
|
||||
long_ad = (struct long_ad *) (data_pos + l_ad-adlen);
|
||||
l_icb = *long_ad;
|
||||
}
|
||||
flags = UDF_EXT_FLAGS(udf_rw32(l_icb.len));
|
||||
if (flags != UDF_EXT_REDIRECT) {
|
||||
l_ad = 0; /* force EOF */
|
||||
break;
|
||||
}
|
||||
|
||||
/* advance to next extent */
|
||||
extnr++;
|
||||
if (extnr >= udf_node->num_extensions) {
|
||||
l_ad = 0; /* force EOF */
|
||||
break;
|
||||
}
|
||||
offset = offset - l_ad;
|
||||
ext = udf_node->ext[extnr];
|
||||
dscr_size = sizeof(struct alloc_ext_entry) -1;
|
||||
l_ad = udf_rw32(ext->l_ad);
|
||||
data_pos = (uint8_t *) ext + dscr_size;
|
||||
}
|
||||
|
||||
/* XXX l_ad == 0 should be enough to check */
|
||||
*eof = (offset >= l_ad) || (l_ad == 0);
|
||||
if (*eof) {
|
||||
DPRINTF(PARANOIDADWLK, ("returning EOF, extnr %d, offset %d, "
|
||||
"l_ad %d\n", extnr, offset, l_ad));
|
||||
memset(icb, 0, sizeof(struct long_ad));
|
||||
return;
|
||||
}
|
||||
@ -1375,27 +1366,35 @@ udf_get_adslot(struct udf_node *udf_node, int slot, struct long_ad *icb,
|
||||
long_ad = (struct long_ad *) (data_pos + offset);
|
||||
*icb = *long_ad;
|
||||
}
|
||||
DPRINTF(PARANOIDADWLK, ("returning element : v %d, lb %d, len %d, "
|
||||
"flags %d\n", icb->loc.part_num, icb->loc.lb_num,
|
||||
UDF_EXT_LEN(icb->len), UDF_EXT_FLAGS(icb->len)));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
int
|
||||
udf_append_adslot(struct udf_node *udf_node, int slot, struct long_ad *icb) {
|
||||
udf_append_adslot(struct udf_node *udf_node, int *slot, struct long_ad *icb) {
|
||||
struct udf_mount *ump = udf_node->ump;
|
||||
union dscrptr *dscr;
|
||||
struct file_entry *fe;
|
||||
struct extfile_entry *efe;
|
||||
struct alloc_ext_entry *ext;
|
||||
struct icb_tag *icbtag;
|
||||
struct short_ad *short_ad;
|
||||
struct long_ad *long_ad, o_icb;
|
||||
struct long_ad *long_ad, o_icb, l_icb;
|
||||
uint64_t logblks_rec, *logblks_rec_p;
|
||||
uint32_t offset, rest, len;
|
||||
uint64_t lmapping, pmapping;
|
||||
uint32_t offset, rest, len, lb_num;
|
||||
uint32_t lb_size, dscr_size, l_ea, l_ad, *l_ad_p, max_l_ad, crclen;
|
||||
uint32_t flags;
|
||||
uint16_t vpart_num;
|
||||
uint8_t *data_pos;
|
||||
int icbflags, addr_type, adlen, extnr;
|
||||
int error;
|
||||
|
||||
/* determine what descriptor we are in */
|
||||
lb_size = udf_rw32(udf_node->ump->logical_vol->lb_size);
|
||||
lb_size = udf_rw32(ump->logical_vol->lb_size);
|
||||
|
||||
fe = udf_node->fe;
|
||||
efe = udf_node->efe;
|
||||
@ -1436,7 +1435,8 @@ udf_append_adslot(struct udf_node *udf_node, int slot, struct long_ad *icb) {
|
||||
|
||||
/* clean up given long_ad */
|
||||
#ifdef DIAGNOSTIC
|
||||
if (UDF_EXT_FLAGS(udf_rw32(icb->len)) == UDF_EXT_FREE) {
|
||||
flags = UDF_EXT_FLAGS(udf_rw32(icb->len));
|
||||
if (flags == UDF_EXT_FREE) {
|
||||
if ((udf_rw16(icb->loc.part_num) != 0) ||
|
||||
(udf_rw32(icb->loc.lb_num) != 0))
|
||||
printf("UDF: warning, cleaning long_ad marked free\n");
|
||||
@ -1446,29 +1446,49 @@ udf_append_adslot(struct udf_node *udf_node, int slot, struct long_ad *icb) {
|
||||
#endif
|
||||
|
||||
/* if offset too big, we go to the allocation extensions */
|
||||
offset = slot * adlen;
|
||||
extnr = 0;
|
||||
while (offset > max_l_ad) {
|
||||
offset -= max_l_ad;
|
||||
l_ad = udf_rw32(*l_ad_p);
|
||||
offset = (*slot) * adlen;
|
||||
extnr = -1;
|
||||
while (offset >= l_ad) {
|
||||
/* check if our last entry is a redirect */
|
||||
if (addr_type == UDF_ICB_SHORT_ALLOC) {
|
||||
short_ad = (struct short_ad *) (data_pos + l_ad-adlen);
|
||||
l_icb.len = short_ad->len;
|
||||
l_icb.loc.part_num = udf_node->loc.loc.part_num;
|
||||
l_icb.loc.lb_num = short_ad->lb_num;
|
||||
} else {
|
||||
KASSERT(addr_type == UDF_ICB_LONG_ALLOC);
|
||||
long_ad = (struct long_ad *) (data_pos + l_ad-adlen);
|
||||
l_icb = *long_ad;
|
||||
}
|
||||
flags = UDF_EXT_FLAGS(udf_rw32(l_icb.len));
|
||||
if (flags != UDF_EXT_REDIRECT) {
|
||||
/* only one past the last one is adressable */
|
||||
break;
|
||||
}
|
||||
|
||||
/* advance to next extent */
|
||||
extnr++;
|
||||
KASSERT(extnr < udf_node->num_extensions);
|
||||
offset = offset - l_ad;
|
||||
|
||||
ext = udf_node->ext[extnr];
|
||||
dscr = (union dscrptr *) ext;
|
||||
dscr_size = sizeof(struct alloc_ext_entry) -1;
|
||||
|
||||
KASSERT(ext != NULL);
|
||||
l_ad_p = &ext->l_ad;
|
||||
max_l_ad = lb_size - dscr_size;
|
||||
data_pos = (uint8_t *) dscr + dscr_size;
|
||||
|
||||
extnr++;
|
||||
l_ad_p = &ext->l_ad;
|
||||
l_ad = udf_rw32(*l_ad_p);
|
||||
data_pos = (uint8_t *) ext + dscr_size;
|
||||
}
|
||||
DPRINTF(PARANOIDADWLK, ("append, ext %d, offset %d, l_ad %d\n",
|
||||
extnr, offset, udf_rw32(*l_ad_p)));
|
||||
KASSERT(l_ad == udf_rw32(*l_ad_p));
|
||||
|
||||
/* offset is offset within the current (E)FE/AED */
|
||||
l_ad = udf_rw32(*l_ad_p);
|
||||
crclen = udf_rw32(dscr->tag.desc_crc_len);
|
||||
logblks_rec = udf_rw64(*logblks_rec_p);
|
||||
|
||||
if (extnr > udf_node->num_extensions)
|
||||
return EFBIG; /* too fragmented */
|
||||
|
||||
/* overwriting old piece? */
|
||||
if (offset < l_ad) {
|
||||
/* overwrite entry; compensate for the old element */
|
||||
@ -1492,15 +1512,83 @@ udf_append_adslot(struct udf_node *udf_node, int slot, struct long_ad *icb) {
|
||||
}
|
||||
}
|
||||
|
||||
/* calculate rest space in this descriptor */
|
||||
rest = max_l_ad - offset;
|
||||
/* check if we're not appending a redirection */
|
||||
flags = UDF_EXT_FLAGS(udf_rw32(icb->len));
|
||||
KASSERT(flags != UDF_EXT_REDIRECT);
|
||||
|
||||
/* round down available space */
|
||||
rest = adlen * ((max_l_ad - offset) / adlen);
|
||||
if (rest <= adlen) {
|
||||
/* create redirect and link new allocation extension */
|
||||
printf("udf_append_to_adslot: can't create allocation extention yet\n");
|
||||
return EFBIG;
|
||||
/* have to append aed, see if we already have a spare one */
|
||||
extnr++;
|
||||
ext = udf_node->ext[extnr];
|
||||
l_icb = udf_node->ext_loc[extnr];
|
||||
if (ext == NULL) {
|
||||
DPRINTF(ALLOC,("adding allocation extent %d\n", extnr));
|
||||
error = udf_pre_allocate_space(ump, UDF_C_NODE, 1,
|
||||
&vpart_num, &lmapping, &pmapping);
|
||||
lb_num = lmapping;
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
/* initialise pointer to location */
|
||||
memset(&l_icb, 0, sizeof(struct long_ad));
|
||||
l_icb.len = udf_rw32(lb_size | UDF_EXT_REDIRECT);
|
||||
l_icb.loc.lb_num = udf_rw32(lb_num);
|
||||
l_icb.loc.part_num = udf_rw16(vpart_num);
|
||||
|
||||
/* create new aed descriptor */
|
||||
udf_create_logvol_dscr(ump, udf_node, &l_icb,
|
||||
(union dscrptr **) &ext);
|
||||
|
||||
udf_inittag(ump, &ext->tag, TAGID_ALLOCEXTENT, lb_num);
|
||||
dscr_size = sizeof(struct alloc_ext_entry) -1;
|
||||
max_l_ad = lb_size - dscr_size;
|
||||
memset(ext->data, 0, max_l_ad);
|
||||
ext->l_ad = udf_rw32(0);
|
||||
ext->tag.desc_crc_len =
|
||||
udf_rw32(dscr_size - UDF_DESC_TAG_LENGTH);
|
||||
|
||||
/* declare aed */
|
||||
udf_node->num_extensions++;
|
||||
udf_node->ext_loc[extnr] = l_icb;
|
||||
udf_node->ext[extnr] = ext;
|
||||
}
|
||||
/* add redirect and adjust l_ad and crclen for old descr */
|
||||
if (addr_type == UDF_ICB_SHORT_ALLOC) {
|
||||
short_ad = (struct short_ad *) (data_pos + offset);
|
||||
short_ad->len = l_icb.len;
|
||||
short_ad->lb_num = l_icb.loc.lb_num;
|
||||
} else if (addr_type == UDF_ICB_LONG_ALLOC) {
|
||||
long_ad = (struct long_ad *) (data_pos + offset);
|
||||
*long_ad = l_icb;
|
||||
}
|
||||
l_ad += adlen;
|
||||
crclen += adlen;
|
||||
dscr->tag.desc_crc_len = udf_rw32(crclen);
|
||||
*l_ad_p = udf_rw32(l_ad);
|
||||
|
||||
/* advance to the new extension */
|
||||
KASSERT(ext != NULL);
|
||||
dscr = (union dscrptr *) ext;
|
||||
dscr_size = sizeof(struct alloc_ext_entry) -1;
|
||||
max_l_ad = lb_size - dscr_size;
|
||||
data_pos = (uint8_t *) dscr + dscr_size;
|
||||
|
||||
l_ad_p = &ext->l_ad;
|
||||
l_ad = udf_rw32(*l_ad_p);
|
||||
crclen = udf_rw32(dscr->tag.desc_crc_len);
|
||||
offset = 0;
|
||||
|
||||
/* adjust callees slot count for link insert */
|
||||
*slot += 1;
|
||||
}
|
||||
|
||||
/* write out the element */
|
||||
DPRINTF(PARANOIDADWLK, ("adding element : %p : v %d, lb %d, "
|
||||
"len %d, flags %d\n", data_pos + offset,
|
||||
icb->loc.part_num, icb->loc.lb_num,
|
||||
UDF_EXT_LEN(icb->len), UDF_EXT_FLAGS(icb->len)));
|
||||
if (addr_type == UDF_ICB_SHORT_ALLOC) {
|
||||
short_ad = (struct short_ad *) (data_pos + offset);
|
||||
short_ad->len = icb->len;
|
||||
@ -1511,7 +1599,8 @@ udf_append_adslot(struct udf_node *udf_node, int slot, struct long_ad *icb) {
|
||||
}
|
||||
|
||||
/* adjust logblks recorded count */
|
||||
if (UDF_EXT_FLAGS(icb->len) == UDF_EXT_ALLOCATED)
|
||||
flags = UDF_EXT_FLAGS(udf_rw32(icb->len));
|
||||
if (flags == UDF_EXT_ALLOCATED)
|
||||
logblks_rec += (UDF_EXT_LEN(icb->len) + lb_size -1) / lb_size;
|
||||
*logblks_rec_p = udf_rw64(logblks_rec);
|
||||
|
||||
@ -1526,6 +1615,65 @@ udf_append_adslot(struct udf_node *udf_node, int slot, struct long_ad *icb) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
udf_count_alloc_exts(struct udf_node *udf_node)
|
||||
{
|
||||
struct long_ad s_ad;
|
||||
uint32_t lb_num, len, flags;
|
||||
uint16_t vpart_num;
|
||||
int slot, eof;
|
||||
int num_extents, extnr;
|
||||
int lb_size;
|
||||
|
||||
if (udf_node->num_extensions == 0)
|
||||
return;
|
||||
|
||||
lb_size = udf_rw32(udf_node->ump->logical_vol->lb_size);
|
||||
/* count number of allocation extents in use */
|
||||
num_extents = 0;
|
||||
slot = 0;
|
||||
for (;;) {
|
||||
udf_get_adslot(udf_node, slot, &s_ad, &eof);
|
||||
if (eof)
|
||||
break;
|
||||
len = udf_rw32(s_ad.len);
|
||||
flags = UDF_EXT_FLAGS(len);
|
||||
|
||||
if (flags == UDF_EXT_REDIRECT)
|
||||
num_extents++;
|
||||
|
||||
slot++;
|
||||
}
|
||||
|
||||
DPRINTF(ALLOC, ("udf_count_alloc_ext counted %d live extents\n",
|
||||
num_extents));
|
||||
|
||||
/* XXX choice: we could delay freeing them on node writeout */
|
||||
/* free excess entries */
|
||||
extnr = num_extents;
|
||||
for (;extnr < udf_node->num_extensions; extnr++) {
|
||||
DPRINTF(ALLOC, ("freeing alloc ext %d\n", extnr));
|
||||
/* free dscriptor */
|
||||
s_ad = udf_node->ext_loc[extnr];
|
||||
udf_free_logvol_dscr(udf_node->ump, &s_ad,
|
||||
udf_node->ext[extnr]);
|
||||
udf_node->ext[extnr] = NULL;
|
||||
|
||||
/* free disc space */
|
||||
lb_num = udf_rw32(s_ad.loc.lb_num);
|
||||
vpart_num = udf_rw16(s_ad.loc.part_num);
|
||||
udf_free_allocated_space(udf_node->ump, lb_num, vpart_num, 1);
|
||||
|
||||
memset(&udf_node->ext_loc[extnr], 0, sizeof(struct long_ad));
|
||||
}
|
||||
|
||||
/* set our new number of allocation extents */
|
||||
udf_node->num_extensions = num_extents;
|
||||
}
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
@ -1855,7 +2003,7 @@ udf_record_allocation_in_node(struct udf_mount *ump, struct buf *buf,
|
||||
UDF_EXT_LEN(udf_rw32(c_ad.len)),
|
||||
UDF_EXT_FLAGS(udf_rw32(c_ad.len)) >> 30));
|
||||
|
||||
error = udf_append_adslot(udf_node, slot, &c_ad);
|
||||
error = udf_append_adslot(udf_node, &slot, &c_ad);
|
||||
if (error) {
|
||||
buf->b_error = error;
|
||||
goto out;
|
||||
@ -1874,7 +2022,7 @@ udf_record_allocation_in_node(struct udf_mount *ump, struct buf *buf,
|
||||
UDF_EXT_LEN(udf_rw32(c_ad.len)),
|
||||
UDF_EXT_FLAGS(udf_rw32(c_ad.len)) >> 30));
|
||||
|
||||
error = udf_append_adslot(udf_node, slot, &c_ad);
|
||||
error = udf_append_adslot(udf_node, &slot, &c_ad);
|
||||
if (error) {
|
||||
buf->b_error = error;
|
||||
goto out;
|
||||
@ -1882,6 +2030,8 @@ udf_record_allocation_in_node(struct udf_mount *ump, struct buf *buf,
|
||||
}
|
||||
|
||||
out:
|
||||
udf_count_alloc_exts(udf_node);
|
||||
|
||||
/* the node's descriptors should now be sane */
|
||||
udf_node_sanity_check(udf_node, &new_inflen, &new_lbrec);
|
||||
UDF_UNLOCK_NODE(udf_node, 0);
|
||||
@ -2094,7 +2244,7 @@ udf_grow_node(struct udf_node *udf_node, uint64_t new_size)
|
||||
|
||||
if (udf_ads_merge(lb_size, &c_ad, &s_ad)) {
|
||||
/* not mergable (anymore) */
|
||||
error = udf_append_adslot(udf_node, slot, &c_ad);
|
||||
error = udf_append_adslot(udf_node, &slot, &c_ad);
|
||||
if (error)
|
||||
goto errorout;
|
||||
slot++;
|
||||
@ -2106,7 +2256,7 @@ udf_grow_node(struct udf_node *udf_node, uint64_t new_size)
|
||||
|
||||
/* if there is a rest piece in the accumulator, append it */
|
||||
if (UDF_EXT_LEN(udf_rw32(c_ad.len)) > 0) {
|
||||
error = udf_append_adslot(udf_node, slot, &c_ad);
|
||||
error = udf_append_adslot(udf_node, &slot, &c_ad);
|
||||
if (error)
|
||||
goto errorout;
|
||||
slot++;
|
||||
@ -2114,7 +2264,7 @@ udf_grow_node(struct udf_node *udf_node, uint64_t new_size)
|
||||
|
||||
/* if there is a rest piece that didn't fit, append it */
|
||||
if (UDF_EXT_LEN(udf_rw32(s_ad.len)) > 0) {
|
||||
error = udf_append_adslot(udf_node, slot, &s_ad);
|
||||
error = udf_append_adslot(udf_node, &slot, &s_ad);
|
||||
if (error)
|
||||
goto errorout;
|
||||
slot++;
|
||||
@ -2146,6 +2296,8 @@ errorout:
|
||||
if (evacuated_data)
|
||||
free(evacuated_data, M_UDFTEMP);
|
||||
|
||||
udf_count_alloc_exts(udf_node);
|
||||
|
||||
udf_node_sanity_check(udf_node, &new_inflen, &new_lbrec);
|
||||
UDF_UNLOCK_NODE(udf_node, 0);
|
||||
|
||||
@ -2444,7 +2596,7 @@ udf_shrink_node(struct udf_node *udf_node, uint64_t new_size)
|
||||
UDF_EXT_LEN(udf_rw32(c_ad.len)),
|
||||
UDF_EXT_FLAGS(udf_rw32(c_ad.len)) >> 30));
|
||||
|
||||
error = udf_append_adslot(udf_node, slot, &c_ad);
|
||||
error = udf_append_adslot(udf_node, &slot, &c_ad);
|
||||
if (error)
|
||||
goto errorout; /* panic? */
|
||||
c_ad = s_ad;
|
||||
@ -2461,7 +2613,7 @@ udf_shrink_node(struct udf_node *udf_node, uint64_t new_size)
|
||||
UDF_EXT_LEN(udf_rw32(c_ad.len)),
|
||||
UDF_EXT_FLAGS(udf_rw32(c_ad.len)) >> 30));
|
||||
|
||||
error = udf_append_adslot(udf_node, slot, &c_ad);
|
||||
error = udf_append_adslot(udf_node, &slot, &c_ad);
|
||||
if (error)
|
||||
goto errorout; /* panic? */
|
||||
;
|
||||
@ -2483,6 +2635,8 @@ udf_shrink_node(struct udf_node *udf_node, uint64_t new_size)
|
||||
errorout:
|
||||
free(node_ad_cpy, M_UDFMNT);
|
||||
|
||||
udf_count_alloc_exts(udf_node);
|
||||
|
||||
udf_node_sanity_check(udf_node, &new_inflen, &new_lbrec);
|
||||
UDF_UNLOCK_NODE(udf_node, 0);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: udf_strat_direct.c,v 1.1 2008/05/14 16:49:48 reinoud Exp $ */
|
||||
/* $NetBSD: udf_strat_direct.c,v 1.2 2008/07/07 18:45:26 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.1 2008/05/14 16:49:48 reinoud Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: udf_strat_direct.c,v 1.2 2008/07/07 18:45:26 reinoud Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
|
||||
@ -108,11 +108,6 @@ udf_wr_nodedscr_callback(struct buf *buf)
|
||||
return;
|
||||
}
|
||||
|
||||
/* XXX noone is waiting on this outstanding_nodedscr */
|
||||
udf_node->outstanding_nodedscr--;
|
||||
if (udf_node->outstanding_nodedscr == 0)
|
||||
wakeup(&udf_node->outstanding_nodedscr);
|
||||
|
||||
/* XXX right flags to mark dirty again on error? */
|
||||
if (buf->b_error) {
|
||||
/* write error on `defect free' media??? how to solve? */
|
||||
@ -120,10 +115,16 @@ udf_wr_nodedscr_callback(struct buf *buf)
|
||||
udf_node->i_flags |= IN_MODIFIED | IN_ACCESSED;
|
||||
}
|
||||
|
||||
/* first unlock the node */
|
||||
KASSERT(udf_node->i_flags & IN_CALLBACK_ULK);
|
||||
UDF_UNLOCK_NODE(udf_node, IN_CALLBACK_ULK);
|
||||
/* decrement outstanding_nodedscr */
|
||||
KASSERT(udf_node->outstanding_nodedscr >= 1);
|
||||
udf_node->outstanding_nodedscr--;
|
||||
if (udf_node->outstanding_nodedscr == 0) {
|
||||
/* unlock the node */
|
||||
KASSERT(udf_node->i_flags & IN_CALLBACK_ULK);
|
||||
UDF_UNLOCK_NODE(udf_node, IN_CALLBACK_ULK);
|
||||
|
||||
wakeup(&udf_node->outstanding_nodedscr);
|
||||
}
|
||||
/* unreference the vnode so it can be recycled */
|
||||
holdrele(udf_node->vnode);
|
||||
|
||||
@ -212,28 +213,33 @@ udf_write_nodedscr_direct(struct udf_strat_args *args)
|
||||
sector = 0;
|
||||
error = udf_translate_vtop(ump, icb, §or, &dummy);
|
||||
if (error)
|
||||
return error;
|
||||
goto out;
|
||||
|
||||
UDF_LOCK_NODE(udf_node, IN_CALLBACK_ULK);
|
||||
/* add reference to the vnode to prevent recycling */
|
||||
vhold(udf_node->vnode);
|
||||
|
||||
if (waitfor) {
|
||||
DPRINTF(WRITE, ("udf_write_nodedscr: sync write\n"));
|
||||
|
||||
error = udf_write_phys_dscr_sync(ump, udf_node, UDF_C_NODE,
|
||||
dscr, sector, logsector);
|
||||
UDF_UNLOCK_NODE(udf_node, IN_CALLBACK_ULK);
|
||||
} else {
|
||||
DPRINTF(WRITE, ("udf_write_nodedscr: no wait, async write\n"));
|
||||
|
||||
/* add reference to the vnode to prevent recycling */
|
||||
vhold(udf_node->vnode);
|
||||
|
||||
udf_node->outstanding_nodedscr++;
|
||||
|
||||
error = udf_write_phys_dscr_async(ump, udf_node, UDF_C_NODE,
|
||||
dscr, sector, logsector, udf_wr_nodedscr_callback);
|
||||
/* will be UNLOCKED in call back */
|
||||
return error;
|
||||
}
|
||||
|
||||
holdrele(udf_node->vnode);
|
||||
out:
|
||||
udf_node->outstanding_nodedscr--;
|
||||
if (udf_node->outstanding_nodedscr == 0) {
|
||||
UDF_UNLOCK_NODE(udf_node, 0);
|
||||
wakeup(&udf_node->outstanding_nodedscr);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: udf_strat_rmw.c,v 1.4 2008/06/17 14:14:05 reinoud Exp $ */
|
||||
/* $NetBSD: udf_strat_rmw.c,v 1.5 2008/07/07 18:45:27 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.4 2008/06/17 14:14:05 reinoud Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: udf_strat_rmw.c,v 1.5 2008/07/07 18:45:27 reinoud Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
|
||||
@ -505,7 +505,7 @@ udf_puteccline(struct udf_eccline *eccline)
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static int
|
||||
udf_create_logvol_dscr_rmw(struct udf_strat_args *args)
|
||||
udf_create_nodedscr_rmw(struct udf_strat_args *args)
|
||||
{
|
||||
union dscrptr **dscrptr = &args->dscr;
|
||||
struct udf_mount *ump = args->ump;
|
||||
@ -545,7 +545,7 @@ udf_create_logvol_dscr_rmw(struct udf_strat_args *args)
|
||||
|
||||
|
||||
static void
|
||||
udf_free_logvol_dscr_rmw(struct udf_strat_args *args)
|
||||
udf_free_nodedscr_rmw(struct udf_strat_args *args)
|
||||
{
|
||||
struct udf_mount *ump = args->ump;
|
||||
struct long_ad *icb = args->icb;
|
||||
@ -573,7 +573,7 @@ udf_free_logvol_dscr_rmw(struct udf_strat_args *args)
|
||||
|
||||
|
||||
static int
|
||||
udf_read_logvol_dscr_rmw(struct udf_strat_args *args)
|
||||
udf_read_nodedscr_rmw(struct udf_strat_args *args)
|
||||
{
|
||||
union dscrptr **dscrptr = &args->dscr;
|
||||
struct udf_mount *ump = args->ump;
|
||||
@ -660,7 +660,7 @@ udf_read_logvol_dscr_rmw(struct udf_strat_args *args)
|
||||
|
||||
|
||||
static int
|
||||
udf_write_logvol_dscr_rmw(struct udf_strat_args *args)
|
||||
udf_write_nodedscr_rmw(struct udf_strat_args *args)
|
||||
{
|
||||
union dscrptr *dscrptr = args->dscr;
|
||||
struct udf_mount *ump = args->ump;
|
||||
@ -681,6 +681,9 @@ udf_write_logvol_dscr_rmw(struct udf_strat_args *args)
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
/* add reference to the vnode to prevent recycling */
|
||||
vhold(udf_node->vnode);
|
||||
|
||||
/* get our eccline */
|
||||
eccline = udf_geteccline(ump, sectornr, 0);
|
||||
eccsect = sectornr - eccline->start_sector;
|
||||
@ -689,7 +692,7 @@ udf_write_logvol_dscr_rmw(struct udf_strat_args *args)
|
||||
|
||||
/* old callback still pending? */
|
||||
if (eccline->bufs[eccsect]) {
|
||||
DPRINTF(WRITE, ("udf_write_logvol_dscr_rmw: writing descriptor"
|
||||
DPRINTF(WRITE, ("udf_write_nodedscr_rmw: writing descriptor"
|
||||
" over buffer?\n"));
|
||||
nestiobuf_done(eccline->bufs[eccsect],
|
||||
eccline->bufs_len[eccsect],
|
||||
@ -697,8 +700,6 @@ udf_write_logvol_dscr_rmw(struct udf_strat_args *args)
|
||||
eccline->bufs[eccsect] = NULL;
|
||||
}
|
||||
|
||||
UDF_LOCK_NODE(udf_node, IN_CALLBACK_ULK);
|
||||
|
||||
/* set sector number in the descriptor and validate */
|
||||
dscrptr = (union dscrptr *)
|
||||
(((uint8_t *) eccline->blob) + eccsect * sector_size);
|
||||
@ -715,10 +716,16 @@ udf_write_logvol_dscr_rmw(struct udf_strat_args *args)
|
||||
eccline->dirty |= bit;
|
||||
|
||||
KASSERT(udf_tagsize(dscrptr, sector_size) <= sector_size);
|
||||
UDF_UNLOCK_NODE(udf_node, IN_CALLBACK_ULK);
|
||||
|
||||
udf_puteccline(eccline);
|
||||
|
||||
holdrele(udf_node->vnode);
|
||||
udf_node->outstanding_nodedscr--;
|
||||
if (udf_node->outstanding_nodedscr == 0) {
|
||||
UDF_UNLOCK_NODE(udf_node, udf_node->i_flags & IN_CALLBACK_ULK);
|
||||
wakeup(&udf_node->outstanding_nodedscr);
|
||||
}
|
||||
|
||||
/* XXX waitfor not used */
|
||||
return 0;
|
||||
}
|
||||
@ -1400,10 +1407,10 @@ udf_discstrat_finish_rmw(struct udf_strat_args *args)
|
||||
|
||||
struct udf_strategy udf_strat_rmw =
|
||||
{
|
||||
udf_create_logvol_dscr_rmw,
|
||||
udf_free_logvol_dscr_rmw,
|
||||
udf_read_logvol_dscr_rmw,
|
||||
udf_write_logvol_dscr_rmw,
|
||||
udf_create_nodedscr_rmw,
|
||||
udf_free_nodedscr_rmw,
|
||||
udf_read_nodedscr_rmw,
|
||||
udf_write_nodedscr_rmw,
|
||||
udf_queuebuf_rmw,
|
||||
udf_discstrat_init_rmw,
|
||||
udf_discstrat_finish_rmw
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: udf_strat_sequential.c,v 1.1 2008/05/14 16:49:48 reinoud Exp $ */
|
||||
/* $NetBSD: udf_strat_sequential.c,v 1.2 2008/07/07 18:45:27 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.1 2008/05/14 16:49:48 reinoud Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: udf_strat_sequential.c,v 1.2 2008/07/07 18:45:27 reinoud Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
|
||||
@ -119,20 +119,22 @@ udf_wr_nodedscr_callback(struct buf *buf)
|
||||
return;
|
||||
}
|
||||
|
||||
/* XXX noone is waiting on this outstanding_nodedscr */
|
||||
udf_node->outstanding_nodedscr--;
|
||||
if (udf_node->outstanding_nodedscr == 0)
|
||||
wakeup(&udf_node->outstanding_nodedscr);
|
||||
|
||||
/* XXX right flags to mark dirty again on error? */
|
||||
if (buf->b_error) {
|
||||
udf_node->i_flags |= IN_MODIFIED | IN_ACCESSED;
|
||||
/* XXX TODO reshedule on error */
|
||||
}
|
||||
|
||||
/* first unlock the node */
|
||||
KASSERT(udf_node->i_flags & IN_CALLBACK_ULK);
|
||||
UDF_UNLOCK_NODE(udf_node, IN_CALLBACK_ULK);
|
||||
/* decrement outstanding_nodedscr */
|
||||
KASSERT(udf_node->outstanding_nodedscr >= 1);
|
||||
udf_node->outstanding_nodedscr--;
|
||||
if (udf_node->outstanding_nodedscr == 0) {
|
||||
/* first unlock the node */
|
||||
KASSERT(udf_node->i_flags & IN_CALLBACK_ULK);
|
||||
UDF_UNLOCK_NODE(udf_node, IN_CALLBACK_ULK);
|
||||
|
||||
wakeup(&udf_node->outstanding_nodedscr);
|
||||
}
|
||||
|
||||
/* unreference the vnode so it can be recycled */
|
||||
holdrele(udf_node->vnode);
|
||||
@ -221,28 +223,32 @@ udf_write_logvol_dscr_seq(struct udf_strat_args *args)
|
||||
if (ump->vtop_tp[vpart] != UDF_VTOP_TYPE_VIRT) {
|
||||
error = udf_translate_vtop(ump, icb, §ornr, &dummy);
|
||||
if (error)
|
||||
return error;
|
||||
goto out;
|
||||
}
|
||||
|
||||
UDF_LOCK_NODE(udf_node, IN_CALLBACK_ULK);
|
||||
/* add reference to the vnode to prevent recycling */
|
||||
vhold(udf_node->vnode);
|
||||
|
||||
if (waitfor) {
|
||||
DPRINTF(WRITE, ("udf_write_logvol_dscr: sync write\n"));
|
||||
|
||||
error = udf_write_phys_dscr_sync(ump, udf_node, UDF_C_NODE,
|
||||
dscr, sectornr, logsectornr);
|
||||
UDF_UNLOCK_NODE(udf_node, IN_CALLBACK_ULK);
|
||||
} else {
|
||||
DPRINTF(WRITE, ("udf_write_logvol_dscr: no wait, async write\n"));
|
||||
|
||||
/* add reference to the vnode to prevent recycling */
|
||||
vhold(udf_node->vnode);
|
||||
|
||||
udf_node->outstanding_nodedscr++;
|
||||
|
||||
error = udf_write_phys_dscr_async(ump, udf_node, UDF_C_NODE,
|
||||
dscr, sectornr, logsectornr, udf_wr_nodedscr_callback);
|
||||
/* will be UNLOCKED in call back */
|
||||
return error;
|
||||
}
|
||||
|
||||
holdrele(udf_node->vnode);
|
||||
out:
|
||||
udf_node->outstanding_nodedscr--;
|
||||
if (udf_node->outstanding_nodedscr == 0) {
|
||||
UDF_UNLOCK_NODE(udf_node, 0);
|
||||
wakeup(&udf_node->outstanding_nodedscr);
|
||||
}
|
||||
|
||||
return error;
|
||||
@ -350,11 +356,10 @@ udf_VAT_mapping_update(struct udf_mount *ump, struct buf *buf)
|
||||
return;
|
||||
}
|
||||
|
||||
/* check for tag location is false for allocation extents */
|
||||
KASSERT(fdscr->tag.tag_loc == udf_node->write_loc.loc.lb_num);
|
||||
|
||||
/* record new position in VAT file */
|
||||
lb_num = udf_rw32(udf_node->write_loc.loc.lb_num);
|
||||
lb_num = udf_rw32(fdscr->tag.tag_loc);
|
||||
|
||||
/* lb_num = udf_rw32(udf_node->write_loc.loc.lb_num); */
|
||||
|
||||
DPRINTF(TRANSLATE, ("VAT entry change (log %u -> phys %u)\n",
|
||||
lb_num, lb_map));
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: udf_subr.c,v 1.54 2008/06/25 16:06:29 reinoud Exp $ */
|
||||
/* $NetBSD: udf_subr.c,v 1.55 2008/07/07 18:45:27 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.54 2008/06/25 16:06:29 reinoud Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: udf_subr.c,v 1.55 2008/07/07 18:45:27 reinoud Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
|
||||
@ -1908,7 +1908,7 @@ udf_update_logvolname(struct udf_mount *ump, char *logvol_id)
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
void
|
||||
udf_inittag(struct udf_mount *ump, struct desc_tag *tag, int tagid,
|
||||
uint32_t sector)
|
||||
{
|
||||
@ -4834,13 +4834,12 @@ udf_get_node(struct udf_mount *ump, struct long_ad *node_icb_loc,
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
|
||||
/* TODO !!!!! writeout alloc_ext_entry's!!! */
|
||||
int
|
||||
udf_writeout_node(struct udf_node *udf_node, int waitfor)
|
||||
{
|
||||
union dscrptr *dscr;
|
||||
struct long_ad *loc;
|
||||
int error;
|
||||
int extnr, flags, error;
|
||||
|
||||
DPRINTF(NODE, ("udf_writeout_node called\n"));
|
||||
|
||||
@ -4854,9 +4853,31 @@ udf_writeout_node(struct udf_node *udf_node, int waitfor)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* lock node */
|
||||
flags = waitfor ? 0 : IN_CALLBACK_ULK;
|
||||
UDF_LOCK_NODE(udf_node, flags);
|
||||
|
||||
/* at least one descriptor writeout */
|
||||
udf_node->outstanding_nodedscr = 1;
|
||||
|
||||
/* we're going to write out the descriptor so clear the flags */
|
||||
udf_node->i_flags &= ~(IN_MODIFIED | IN_ACCESSED);
|
||||
|
||||
/* if we were rebuild, write out the allocation extents */
|
||||
if (udf_node->i_flags & IN_NODE_REBUILD) {
|
||||
/* mark outstanding node dscriptors and issue them */
|
||||
udf_node->outstanding_nodedscr += udf_node->num_extensions;
|
||||
for (extnr = 0; extnr < udf_node->num_extensions; extnr++) {
|
||||
loc = &udf_node->ext_loc[extnr];
|
||||
dscr = (union dscrptr *) udf_node->ext[extnr];
|
||||
error = udf_write_logvol_dscr(udf_node, dscr, loc, 0);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
/* mark allocation extents written out */
|
||||
udf_node->i_flags &= ~(IN_NODE_REBUILD);
|
||||
}
|
||||
|
||||
if (udf_node->fe) {
|
||||
dscr = (union dscrptr *) udf_node->fe;
|
||||
} else {
|
||||
@ -5141,7 +5162,7 @@ udf_free_descriptor_space(struct udf_node *udf_node, struct long_ad *loc, void *
|
||||
return;
|
||||
|
||||
/* got a descriptor here */
|
||||
len = udf_rw32(loc->len);
|
||||
len = UDF_EXT_LEN(udf_rw32(loc->len));
|
||||
lb_num = udf_rw32(loc->loc.lb_num);
|
||||
vpart_num = udf_rw16(loc->loc.part_num);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: udf_subr.h,v 1.7 2008/06/18 21:23:32 reinoud Exp $ */
|
||||
/* $NetBSD: udf_subr.h,v 1.8 2008/07/07 18:45:27 reinoud Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006, 2008 Reinoud Zandijk
|
||||
@ -96,7 +96,7 @@ int udf_translate_vtop(struct udf_mount *ump, struct long_ad *icb_loc,
|
||||
int udf_translate_file_extent(struct udf_node *node,
|
||||
uint32_t from, uint32_t num_lb, uint64_t *map);
|
||||
void udf_get_adslot(struct udf_node *udf_node, int slot, struct long_ad *icb, int *eof);
|
||||
int udf_append_adslot(struct udf_node *udf_node, int slot, struct long_ad *icb);
|
||||
int udf_append_adslot(struct udf_node *udf_node, int *slot, struct long_ad *icb);
|
||||
|
||||
int udf_vat_read(struct udf_node *vat_node, uint8_t *blob, int size, uint32_t offset);
|
||||
int udf_vat_write(struct udf_node *vat_node, uint8_t *blob, int size, uint32_t offset);
|
||||
@ -140,6 +140,7 @@ void udf_discstrat_queuebuf(struct udf_mount *ump, struct buf *nestbuf);
|
||||
int udf_write_terminator(struct udf_mount *ump, uint32_t sector);
|
||||
|
||||
/* structure creators */
|
||||
void udf_inittag(struct udf_mount *ump, struct desc_tag *tag, int tagid, uint32_t sector);
|
||||
void udf_set_regid(struct regid *regid, char const *name);
|
||||
void udf_add_domain_regid(struct udf_mount *ump, struct regid *regid);
|
||||
void udf_add_udf_regid(struct udf_mount *ump, struct regid *regid);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: udf_vnops.c,v 1.23 2008/06/24 15:57:13 reinoud Exp $ */
|
||||
/* $NetBSD: udf_vnops.c,v 1.24 2008/07/07 18:45:27 reinoud Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006, 2008 Reinoud Zandijk
|
||||
@ -32,7 +32,7 @@
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__KERNEL_RCSID(0, "$NetBSD: udf_vnops.c,v 1.23 2008/06/24 15:57:13 reinoud Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: udf_vnops.c,v 1.24 2008/07/07 18:45:27 reinoud Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
|
||||
@ -2050,6 +2050,15 @@ udf_fsync(void *v)
|
||||
wait = (ap->a_flags & FSYNC_WAIT) ? UPDATE_WAIT : 0;
|
||||
vflushbuf(vp, wait);
|
||||
|
||||
if (udf_node == NULL) {
|
||||
printf("udf_fsync() called on NULL udf_node!\n");
|
||||
return 0;
|
||||
}
|
||||
if (vp->v_tag != VT_UDF) {
|
||||
printf("udf_fsync() called on node not tagged as UDF node!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* set our times */
|
||||
udf_itimes(udf_node, NULL, NULL, NULL);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user