Date: Mon, 18 Jun 2012 11:49:24 +0000 From: oleksandr@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r237888 - soc2012/oleksandr/udf-head/sys/fs/udf2 Message-ID: <20120618114924.6230B1065676@hub.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: oleksandr Date: Mon Jun 18 11:49:23 2012 New Revision: 237888 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=237888 Log: Add some debug section and function udf_find_raw_phys Modified: soc2012/oleksandr/udf-head/sys/fs/udf2/udf.h soc2012/oleksandr/udf-head/sys/fs/udf2/udf_readwrite.c soc2012/oleksandr/udf-head/sys/fs/udf2/udf_subr.c soc2012/oleksandr/udf-head/sys/fs/udf2/udf_vfsops.c Modified: soc2012/oleksandr/udf-head/sys/fs/udf2/udf.h ============================================================================== --- soc2012/oleksandr/udf-head/sys/fs/udf2/udf.h Mon Jun 18 10:56:29 2012 (r237887) +++ soc2012/oleksandr/udf-head/sys/fs/udf2/udf.h Mon Jun 18 11:49:23 2012 (r237888) @@ -28,6 +28,8 @@ #define _FS_UDF_UDF_H_ #include "udf_osta.h" +#include "udf_mount.h" +#include "udfio.h" /* lets see debug stuff for now */ #define DEBUG @@ -253,9 +255,9 @@ struct cdev *dev; struct g_consumer *geomcp; struct bufobj *bo; -/* struct mmc_discinfo discinfo; */ + struct mmc_discinfo discinfo; uint32_t sector_size; -// struct udf_args mount_args; + struct udf_args mount_args; int flags; uid_t anon_uid; gid_t anon_gid; Modified: soc2012/oleksandr/udf-head/sys/fs/udf2/udf_readwrite.c ============================================================================== --- soc2012/oleksandr/udf-head/sys/fs/udf2/udf_readwrite.c Mon Jun 18 10:56:29 2012 (r237887) +++ soc2012/oleksandr/udf-head/sys/fs/udf2/udf_readwrite.c Mon Jun 18 11:49:23 2012 (r237888) @@ -35,7 +35,7 @@ #include "ecma167-udf.h" #include "udf.h" #include "udf_subr.h" - +#include "udf_mount.h" static int udf_read_phys_sectors(struct udf_mount *ump, int what, void *blob, uint32_t start, uint32_t sectors); Modified: soc2012/oleksandr/udf-head/sys/fs/udf2/udf_subr.c ============================================================================== --- soc2012/oleksandr/udf-head/sys/fs/udf2/udf_subr.c Mon Jun 18 10:56:29 2012 (r237887) +++ soc2012/oleksandr/udf-head/sys/fs/udf2/udf_subr.c Mon Jun 18 11:49:23 2012 (r237888) @@ -38,6 +38,7 @@ #include "udf.h" #include "udf_subr.h" #include "udf_mount.h" +#include "udfio.h" #define VTOI(vnode) ((struct udf_node *) (vnode)->v_data) @@ -386,7 +387,6 @@ return 0; } - /* * NOTE: this is the only routine in this file that directly peeks into the * metadata file but since its at a larval state of the mount it can't hurt. @@ -937,6 +937,10 @@ int error, anch, ok, first_anchor; uint32_t positions[4], track_start, track_end; +// struct udf_args *args = &ump->mount_args; +// struct mmc_trackinfo first_track; +// struct mmc_trackinfo second_track; + track_start = ump->session_start; track_end = ump->session_end; @@ -968,6 +972,88 @@ } return ok; +#if 0 + struct udf_args *args = &ump->mount_args; + struct mmc_trackinfo first_track; + struct mmc_trackinfo second_track; + struct mmc_trackinfo last_track; + struct anchor_vdp **anchorsp; + uint32_t track_start; + uint32_t track_end; + uint32_t positions[4]; + int first_tracknr, last_tracknr; + int error, anch, ok, first_anchor; + + /* search the first and last track of the specified session */ + error = udf_search_tracks(ump, args, &first_tracknr, &last_tracknr); + if (!error) { + first_track.tracknr = first_tracknr; + error = udf_update_trackinfo(ump, &first_track); + } + if (!error) { + last_track.tracknr = last_tracknr; + error = udf_update_trackinfo(ump, &last_track); + } + if ((!error) && (first_tracknr != last_tracknr)) { + second_track.tracknr = first_tracknr+1; + error = udf_update_trackinfo(ump, &second_track); + } + if (error) { + printf("UDF mount: reading disc geometry failed\n"); + return 0; + } + + track_start = first_track.track_start; + + /* `end' is not as straitforward as start. */ + track_end = last_track.track_start + + last_track.track_size - last_track.free_blocks - 1; + + if (ump->discinfo.mmc_cur & MMC_CAP_SEQUENTIAL) { + /* end of track is not straitforward here */ + if (last_track.flags & MMC_TRACKINFO_LRA_VALID) + track_end = last_track.last_recorded; + else if (last_track.flags & MMC_TRACKINFO_NWA_VALID) + track_end = last_track.next_writable + - ump->discinfo.link_block_penalty; + } + + /* its no use reading a blank track */ + first_anchor = 0; + if (first_track.flags & MMC_TRACKINFO_BLANK) + first_anchor = 1; + + /* get our packet size */ + ump->packet_size = first_track.packet_size; + if (first_track.flags & MMC_TRACKINFO_BLANK) + ump->packet_size = second_track.packet_size; + + if (ump->packet_size <= 1) { + /* take max, but not bigger than 64 */ + ump->packet_size = MAXPHYS / ump->discinfo.sector_size; + ump->packet_size = MIN(ump->packet_size, 64); + } + KASSERT(ump->packet_size >= 1); + + /* read anchors start+256, start+512, end-256, end */ + positions[0] = track_start+256; + positions[1] = track_end-256; + positions[2] = track_end; + positions[3] = track_start+512; /* [UDF 2.60/6.11.2] */ + /* XXX shouldn't +512 be prefered above +256 for compat with Roxio CD */ + + ok = 0; + anchorsp = ump->anchors; + for (anch = first_anchor; anch < 4; anch++) { + DPRINTF(VOLUMES, ("Read anchor %d at sector %d\n", anch, + positions[anch])); + error = udf_read_anchor(ump, positions[anch], anchorsp); + if (!error) { + anchorsp++; + ok++; + } + } +#endif } /* --------------------------------------------------------------------- */ @@ -1002,6 +1088,28 @@ return vpart_num; } #endif + +/* + * BUGALERT: some rogue implementations use random physical partition + * numbers to break other implementations so lookup the number. + */ + +static uint16_t +udf_find_raw_phys(struct udf_mount *ump, uint16_t raw_phys_part) +{ + struct part_desc *part; + uint16_t phys_part; + + for (phys_part = 0; phys_part < UDF_PARTITIONS; phys_part++) { + part = ump->partitions[phys_part]; + if (part == NULL) + break; + if (le16toh(part->part_num) == raw_phys_part) + break; + } + return phys_part; +} + /* --------------------------------------------------------------------- */ /* we dont try to be smart; we just record the parts */ @@ -1013,9 +1121,10 @@ static int udf_process_vds_descriptor(struct udf_mount *ump, union dscrptr *dscr) { - struct part_desc *part; uint16_t phys_part, raw_phys_part; + DPRINTF(VOLUMES, ("\tprocessing VDS descr %d\n", + le16toh(dscr->tag.id))); switch (le16toh(dscr->tag.id)) { case TAGID_PRI_VOL : /* primary partition */ UDF_UPDATE_DSCR(ump->primary_vol, &dscr->pvd); @@ -1043,13 +1152,8 @@ * the number. */ raw_phys_part = le16toh(dscr->pd.part_num); - for (phys_part = 0; phys_part < UDF_PARTITIONS; phys_part++) { - part = ump->partitions[phys_part]; - if (part == NULL) - break; - if (le16toh(part->part_num) == raw_phys_part) - break; - } + phys_part = udf_find_raw_phys(ump, raw_phys_part); + if (phys_part == UDF_PARTITIONS) { free(dscr, M_UDFTEMP); return EINVAL; @@ -1058,9 +1162,12 @@ UDF_UPDATE_DSCR(ump->partitions[phys_part], &dscr->pd); break; case TAGID_VOL : /* volume space extender; rare */ + DPRINTF(VOLUMES, ("VDS extender ignored\n")); free(dscr, M_UDFTEMP); break; default : + DPRINTF(VOLUMES, ("Unhandled VDS type %d\n", + le16toh(dscr->tag.id))); free(dscr, M_UDFTEMP); } @@ -1224,6 +1331,9 @@ lvint = &dscr->lvid; dscr = NULL; } /* else hope for the best... maybe the next is ok */ + + DPRINTFIF(VOLUMES, lvint, ("logvol integrity read, state %s\n", + le32toh(lvint->integrity_type) ? "CLOSED" : "OPEN")); /* proceed sequential */ lbnum += 1; @@ -1236,6 +1346,7 @@ if (trace_len >= UDF_LVDINT_SEGMENTS-1) { /* IEK! segment link full... */ + DPRINTF(VOLUMES, ("lvdint segments full\n")); error = EINVAL; } else { trace++; @@ -1851,14 +1962,21 @@ /* struct udf_args *args = &ump->mount_args; */ union udf_pmap *mapping; struct logvol_int_desc *lvint; - struct part_desc *part; struct udf_logvol_info *lvinfo; int pmap_stype, pmap_size, pmap_type, log_part, phys_part, error; - int raw_phys_part, maps_on, n_phys, n_virt, n_spar, n_meta, len; + int raw_phys_part, maps_on, len; + int n_phys, n_virt, n_spar, n_meta; uint32_t n_pm, mt_l; char *domain_name, *map_name; /* bits[128]; */ const char *check_name; uint8_t *pmap_pos; + + if (ump == NULL) + return ENOENT; + + /* we need at least an anchor (trivial, but for safety) */ + if (ump->anchors[0] == NULL) + return EINVAL; /* we need at least one primary and one logical volume descriptor */ if ((ump->primary_vol == NULL) || (ump->logical_vol) == NULL) @@ -1889,14 +2007,18 @@ return EINVAL; } + /* retrieve logical volume integrity sequence */ + error = udf_retrieve_lvint(ump); + if (error != 0) + return EINVAL; // previously it always returned this on error. + /* * We need at least one logvol integrity descriptor recorded. Note * that its OK to have an open logical volume integrity here. The VAT * will close/update the integrity. */ - error = udf_retrieve_lvint(ump); - if (error != 0) - return EINVAL; // previously it always returned this on error. + if (ump->logvol_integrity == NULL) + return EINVAL; /* process derived structures */ n_pm = le32toh(ump->logical_vol->n_pm); /* num partmaps */ @@ -1911,6 +2033,7 @@ * check and recording of the mapping results. Saves expensive * strncmp() in tight places. */ + DPRINTF(VOLUMES, ("checking logvol mappings\n")); n_pm = le32toh(ump->logical_vol->n_pm); /* num partmaps */ mt_l = le32toh(ump->logical_vol->mt_l); /* partmaps data length */ pmap_pos = ump->logical_vol->maps; @@ -1963,7 +2086,7 @@ } check_name = "*UDF Metadata Partition"; if (strncmp(map_name, check_name, len) == 0) { -printf("*UDF Metadata Partition\n"); + printf("*UDF Metadata Partition\n"); pmap_type = UDF_VTOP_TYPE_META; n_meta++; ump->node_part = log_part; @@ -1980,14 +2103,11 @@ * partition numbers to break other implementations so lookup * the number. */ - for (phys_part = 0; phys_part < UDF_PARTITIONS; phys_part++) { - part = ump->partitions[phys_part]; - if (part == NULL) - continue; - if (le16toh(part->part_num) == raw_phys_part) - break; - } + phys_part = udf_find_raw_phys(ump, raw_phys_part); + DPRINTF(VOLUMES, ("\t%d -> %d(%d) type %d\n", log_part, + raw_phys_part, phys_part, pmap_type)); + if (phys_part == UDF_PARTITIONS) return EINVAL; if (pmap_type == UDF_VTOP_TYPE_UNKNOWN) @@ -2092,6 +2212,13 @@ if (ump->vfs_mountp->mnt_flag & MNT_RDONLY) ump->strategy = &udf_strat_direct; #endif + /*print results */ + DPRINTF(VOLUMES, ("\tdata partition %d\n", ump->data_part)); + DPRINTF(VOLUMES, ("\t\talloc scheme %d\n", ump->vtop_alloc[ump->data_part])); + DPRINTF(VOLUMES, ("\tnode partition %d\n", ump->node_part)); + DPRINTF(VOLUMES, ("\t\talloc scheme %d\n", ump->vtop_alloc[ump->node_part])); + DPRINTF(VOLUMES, ("\tfids partition %d\n", ump->fids_part)); + DPRINTF(VOLUMES, ("\t\talloc scheme %d\n", ump->vtop_alloc[ump->fids_part])); snprintb(bits, sizeof(bits), UDFLOGVOL_BITS, ump->lvopen); DPRINTF(VOLUMES, ("\tactions on logvol open %s\n", bits)); Modified: soc2012/oleksandr/udf-head/sys/fs/udf2/udf_vfsops.c ============================================================================== --- soc2012/oleksandr/udf-head/sys/fs/udf2/udf_vfsops.c Mon Jun 18 10:56:29 2012 (r237887) +++ soc2012/oleksandr/udf-head/sys/fs/udf2/udf_vfsops.c Mon Jun 18 11:49:23 2012 (r237888) @@ -50,8 +50,12 @@ MALLOC_DEFINE(M_UDFTEMP, "UDF temp", "UDF allocation space"); uma_zone_t udf_zone_node = NULL; +/* verbose levels of the udf filingsystem */ +int udf_verbose = UDF_DEBUGGING; + struct iconv_functions *udf2_iconv = NULL; +/* internal finctions */ static int udf_mountfs(struct vnode *, struct mount *); /* --------------------------------------------------------------------- */ @@ -368,7 +372,7 @@ mp->mnt_flag &= ~MNT_LOCAL; MNT_IUNLOCK(mp); - return 0; + return (0); } /* --------------------------------------------------------------------- */ @@ -812,9 +816,8 @@ * used for reference to files by unique ID and for NFSv3. * (optional) TODO lookup why some sources state NFSv3 - - This done as in the current udf implementation. I really have no idea - if it is correct. + * This done as in the current udf implementation. I really have no idea + * if it is correct. */ int udf_vget(struct mount *mp, ino_t ino, int flags, struct vnode **vpp) @@ -827,7 +830,11 @@ error = vfs_hash_get(mp, ino, flags, curthread, vpp, NULL, NULL); if (error || *vpp != NULL) return error; - + + /* + * We must promote to an exclusive lock for vnode creation. This + * can happen if lookup is passed LOCKSHARED. + */ if ((flags & LK_TYPE_MASK) == LK_SHARED) { flags &= ~LK_TYPE_MASK; flags |= LK_EXCLUSIVE; @@ -932,27 +939,27 @@ udf_fhtovp(struct mount *mp, struct fid *fhp, int flags, struct vnode **vpp) { - struct vnode *vp; + struct vnode *nvp; struct udf_fid *ufid = (struct udf_fid*)fhp; struct udf_node *udf_node; uint64_t filelen; int error; - error = VFS_VGET(mp, ufid->ino, LK_EXCLUSIVE, &vp); + error = VFS_VGET(mp, ufid->ino, LK_EXCLUSIVE, &nvp); if (error != 0) { *vpp = NULLVP; return error; } - udf_node = VTOI(vp); + udf_node = VTOI(nvp); if (udf_node->efe) filelen = le64toh(udf_node->efe->inf_len); else filelen = le64toh(udf_node->fe->inf_len); - vnode_create_vobject(vp, filelen, curthread); - *vpp = vp; + *vpp = nvp; + vnode_create_vobject(*vpp, filelen, curthread); - return 0; + return (0); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120618114924.6230B1065676>