patch-2.4.13 linux/fs/udf/super.c
Next file: linux/fs/udf/truncate.c
Previous file: linux/fs/udf/namei.c
Back to the patch index
Back to the overall index
- Lines: 358
- Date:
Thu Oct 11 08:59:24 2001
- Orig file:
v2.4.12/linux/fs/udf/super.c
- Orig date:
Tue Jul 3 17:08:21 2001
diff -u --recursive --new-file v2.4.12/linux/fs/udf/super.c linux/fs/udf/super.c
@@ -85,7 +85,7 @@
static int udf_load_partition(struct super_block *, lb_addr *);
static int udf_load_logicalvol(struct super_block *, struct buffer_head *, lb_addr *);
static void udf_load_logicalvolint(struct super_block *, extent_ad);
-static int udf_find_anchor(struct super_block *, int, int);
+static void udf_find_anchor(struct super_block *);
static int udf_find_fileset(struct super_block *, lb_addr *, lb_addr *);
static void udf_load_pvoldesc(struct super_block *, struct buffer_head *);
static void udf_load_fileset(struct super_block *, struct buffer_head *, lb_addr *);
@@ -164,7 +164,7 @@
* noadinicb Don't embed data in the inode
* shortad Use short ad's
* longad Use long ad's (default)
- * strict Set strict conformance
+ * nostrict Unset strict conformance
* iocharset= Set the NLS character set
*
* The remaining are for debugging and disaster recovery:
@@ -208,8 +208,8 @@
uopt->blocksize = 2048;
uopt->partition = 0xFFFF;
uopt->session = 0xFFFFFFFF;
- uopt->lastblock = 0xFFFFFFFF;
- uopt->anchor = 0xFFFFFFFF;
+ uopt->lastblock = 0;
+ uopt->anchor = 0;
uopt->volume = 0xFFFFFFFF;
uopt->rootdir = 0xFFFFFFFF;
uopt->fileset = 0xFFFFFFFF;
@@ -244,8 +244,8 @@
uopt->gid = simple_strtoul(val, NULL, 0);
else if (!strcmp(opt, "umask") && val)
uopt->umask = simple_strtoul(val, NULL, 0);
- else if (!strcmp(opt, "strict") && !val)
- uopt->flags |= (1 << UDF_FLAG_STRICT);
+ else if (!strcmp(opt, "nostrict") && !val)
+ uopt->flags &= ~(1 << UDF_FLAG_STRICT);
else if (!strcmp(opt, "uid") && val)
uopt->uid = simple_strtoul(val, NULL, 0);
else if (!strcmp(opt, "session") && val)
@@ -496,72 +496,36 @@
* July 1, 1997 - Andrew E. Mileski
* Written, tested, and released.
*/
-static int
-udf_find_anchor(struct super_block *sb, int useranchor, int lastblock)
+static void
+udf_find_anchor(struct super_block *sb)
{
- int varlastblock = udf_variable_to_fixed(lastblock);
- int last[] = { lastblock, lastblock - 2,
- lastblock - 150, lastblock - 152,
- varlastblock, varlastblock - 2,
- varlastblock - 150, varlastblock - 152 };
+ int lastblock = UDF_SB_LASTBLOCK(sb);
struct buffer_head *bh = NULL;
Uint16 ident;
Uint32 location;
int i;
- UDF_SB_ANCHOR(sb)[0] = 0;
- UDF_SB_ANCHOR(sb)[1] = 0;
- UDF_SB_ANCHOR(sb)[2] = 0;
- UDF_SB_ANCHOR(sb)[3] = 256 + UDF_SB_SESSION(sb);
+ if (lastblock)
+ {
+ int varlastblock = udf_variable_to_fixed(lastblock);
+ int last[] = { lastblock, lastblock - 2,
+ lastblock - 150, lastblock - 152,
+ varlastblock, varlastblock - 2,
+ varlastblock - 150, varlastblock - 152 };
- lastblock = 0;
+ lastblock = 0;
- /* Search for an anchor volume descriptor pointer */
+ /* Search for an anchor volume descriptor pointer */
- /* according to spec, anchor is in either:
- * block 256
- * lastblock-256
- * lastblock
- * however, if the disc isn't closed, it could be 512 */
+ /* according to spec, anchor is in either:
+ * block 256
+ * lastblock-256
+ * lastblock
+ * however, if the disc isn't closed, it could be 512 */
- for (i=0; (!lastblock && i<sizeof(last)/sizeof(int)); i++)
- {
- if (last[i] < 0 || !(bh = bread(sb->s_dev, last[i], sb->s_blocksize)))
- {
- ident = location = 0;
- }
- else
+ for (i=0; (!lastblock && i<sizeof(last)/sizeof(int)); i++)
{
- ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
- location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
- udf_release_data(bh);
- }
-
- if (ident == TID_ANCHOR_VOL_DESC_PTR)
- {
- if (location == last[i] - UDF_SB_SESSION(sb))
- {
- lastblock = UDF_SB_ANCHOR(sb)[0] = last[i];
- UDF_SB_ANCHOR(sb)[1] = last[i] - 256;
- }
- else if (location == udf_variable_to_fixed(last[i]) - UDF_SB_SESSION(sb))
- {
- UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
- lastblock = UDF_SB_ANCHOR(sb)[0] = udf_variable_to_fixed(last[i]);
- UDF_SB_ANCHOR(sb)[1] = lastblock - 256;
- }
- else
- udf_debug("Anchor found at block %d, location mismatch %d.\n",
- last[i], location);
- }
- else if (ident == TID_FILE_ENTRY || ident == TID_EXTENDED_FILE_ENTRY)
- {
- lastblock = last[i];
- UDF_SB_ANCHOR(sb)[2] = 512 + UDF_SB_SESSION(sb);
- }
- else
- {
- if (!(bh = bread(sb->s_dev, last[i] - 256, sb->s_blocksize)))
+ if (last[i] < 0 || !(bh = bread(sb->s_dev, last[i], sb->s_blocksize)))
{
ident = location = 0;
}
@@ -571,17 +535,32 @@
location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
udf_release_data(bh);
}
-
- if (ident == TID_ANCHOR_VOL_DESC_PTR &&
- location == last[i] - 256 - UDF_SB_SESSION(sb))
+
+ if (ident == TID_ANCHOR_VOL_DESC_PTR)
+ {
+ if (location == last[i] - UDF_SB_SESSION(sb))
+ {
+ lastblock = UDF_SB_ANCHOR(sb)[0] = last[i];
+ UDF_SB_ANCHOR(sb)[1] = last[i] - 256;
+ }
+ else if (location == udf_variable_to_fixed(last[i]) - UDF_SB_SESSION(sb))
+ {
+ UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
+ lastblock = UDF_SB_ANCHOR(sb)[0] = udf_variable_to_fixed(last[i]);
+ UDF_SB_ANCHOR(sb)[1] = lastblock - 256;
+ }
+ else
+ udf_debug("Anchor found at block %d, location mismatch %d.\n",
+ last[i], location);
+ }
+ else if (ident == TID_FILE_ENTRY || ident == TID_EXTENDED_FILE_ENTRY)
{
lastblock = last[i];
- UDF_SB_ANCHOR(sb)[1] = last[i] - 256;
+ UDF_SB_ANCHOR(sb)[3] = 512 + UDF_SB_SESSION(sb);
}
else
{
- if (!(bh = bread(sb->s_dev, last[i] - 312 - UDF_SB_SESSION(sb),
- sb->s_blocksize)))
+ if (last[i] < 256 || !(bh = bread(sb->s_dev, last[i] - 256, sb->s_blocksize)))
{
ident = location = 0;
}
@@ -591,13 +570,34 @@
location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
udf_release_data(bh);
}
-
+
if (ident == TID_ANCHOR_VOL_DESC_PTR &&
- location == udf_variable_to_fixed(last[i]) - 256)
+ location == last[i] - 256 - UDF_SB_SESSION(sb))
{
- UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
- lastblock = udf_variable_to_fixed(last[i]);
- UDF_SB_ANCHOR(sb)[1] = lastblock - 256;
+ lastblock = last[i];
+ UDF_SB_ANCHOR(sb)[1] = last[i] - 256;
+ }
+ else
+ {
+ if (last[i] < 312 + UDF_SB_SESSION(sb) || !(bh = bread(sb->s_dev, last[i] - 312 - UDF_SB_SESSION(sb),
+ sb->s_blocksize)))
+ {
+ ident = location = 0;
+ }
+ else
+ {
+ ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
+ location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
+ udf_release_data(bh);
+ }
+
+ if (ident == TID_ANCHOR_VOL_DESC_PTR &&
+ location == udf_variable_to_fixed(last[i]) - 256)
+ {
+ UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
+ lastblock = udf_variable_to_fixed(last[i]);
+ UDF_SB_ANCHOR(sb)[1] = lastblock - 256;
+ }
}
}
}
@@ -636,15 +636,9 @@
}
}
}
- else if (useranchor != 0xFFFFFFFF)
- {
- UDF_SB_ANCHOR(sb)[i] = useranchor;
- useranchor = 0xFFFFFFFF;
- i --;
- }
}
- return lastblock;
+ UDF_SB_LASTBLOCK(sb) = lastblock;
}
static int
@@ -985,8 +979,10 @@
struct buffer_head *bh = NULL;
Uint16 ident;
- while ((bh = udf_read_tagged(sb, loc.extLocation, loc.extLocation, &ident)) &&
- ident == TID_LOGICAL_VOL_INTEGRITY_DESC && loc.extLength > 0)
+ while (loc.extLength > 0 &&
+ (bh = udf_read_tagged(sb, loc.extLocation,
+ loc.extLocation, &ident)) &&
+ ident == TID_LOGICAL_VOL_INTEGRITY_DESC)
{
UDF_SB_LVIDBH(sb) = bh;
@@ -1152,6 +1148,8 @@
else if ((block = udf_vrs(sb, silent)) == -1)
{
udf_debug("Failed to read byte 32768. Assuming open disc. Skipping validity check\n");
+ if (!UDF_SB_LASTBLOCK(sb))
+ UDF_SB_LASTBLOCK(sb) = udf_get_last_block(sb);
return 0;
}
else
@@ -1220,6 +1218,12 @@
if (!UDF_SB_LASTBLOCK(sb))
{
+ UDF_SB_LASTBLOCK(sb) = udf_get_last_block(sb);
+ udf_find_anchor(sb);
+ }
+
+ if (!UDF_SB_LASTBLOCK(sb))
+ {
udf_debug("Unable to determine Lastblock (For Virtual Partition)\n");
return 1;
}
@@ -1355,7 +1359,7 @@
struct udf_options uopt;
lb_addr rootdir, fileset;
- uopt.flags = (1 << UDF_FLAG_USE_AD_IN_ICB);
+ uopt.flags = (1 << UDF_FLAG_USE_AD_IN_ICB) | (1 << UDF_FLAG_STRICT);
uopt.uid = -1;
uopt.gid = -1;
uopt.umask = 0;
@@ -1409,14 +1413,10 @@
udf_debug("Multi-session=%d\n", UDF_SB_SESSION(sb));
- if ( uopt.lastblock == 0xFFFFFFFF )
- UDF_SB_LASTBLOCK(sb) = udf_get_last_block(sb);
- else
- UDF_SB_LASTBLOCK(sb) = uopt.lastblock;
-
- UDF_SB_LASTBLOCK(sb) = udf_find_anchor(sb, uopt.anchor, UDF_SB_LASTBLOCK(sb));
-
- udf_debug("Lastblock=%d\n", UDF_SB_LASTBLOCK(sb));
+ UDF_SB_LASTBLOCK(sb) = uopt.lastblock;
+ UDF_SB_ANCHOR(sb)[0] = UDF_SB_ANCHOR(sb)[1] = 0;
+ UDF_SB_ANCHOR(sb)[2] = uopt.anchor;
+ UDF_SB_ANCHOR(sb)[3] = UDF_SB_SESSION(sb) + 256;
if (udf_check_valid(sb, uopt.novrs, silent)) /* read volume recognition sequences */
{
@@ -1424,6 +1424,8 @@
goto error_out;
}
+ udf_find_anchor(sb);
+
/* Fill in the rest of the superblock */
sb->s_op = &udf_sb_ops;
sb->dq_op = NULL;
@@ -1436,6 +1438,8 @@
goto error_out;
}
+ udf_debug("Lastblock=%d\n", UDF_SB_LASTBLOCK(sb));
+
if ( UDF_SB_LVIDBH(sb) )
{
Uint16 minUDFReadRev = le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFReadRev);
@@ -1744,7 +1748,7 @@
unsigned int accum = 0;
Uint32 extoffset, elen;
lb_addr bloc, eloc;
- char etype;
+ Sint8 etype;
struct buffer_head *bh = NULL;
bloc = UDF_I_LOCATION(table);
@@ -1763,6 +1767,20 @@
{
unsigned int accum = 0;
+ if (UDF_SB_LVIDBH(sb))
+ {
+ if (le32_to_cpu(UDF_SB_LVID(sb)->numOfPartitions) > UDF_SB_PARTITION(sb))
+ {
+ accum = le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)]);
+
+ if (accum == 0xFFFFFFFF)
+ accum = 0;
+ }
+ }
+
+ if (accum)
+ return accum;
+
if (UDF_SB_PARTFLAGS(sb,UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_BITMAP)
{
accum += udf_count_free_bitmap(sb,
@@ -1786,18 +1804,6 @@
accum += udf_count_free_table(sb,
UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.s_table);
}
- if (accum)
- return accum;
- if (UDF_SB_LVIDBH(sb))
- {
- if (le32_to_cpu(UDF_SB_LVID(sb)->numOfPartitions) > UDF_SB_PARTITION(sb))
- {
- accum = le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)]);
-
- if (accum == 0xFFFFFFFF)
- accum = 0;
- }
- }
return accum;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)