* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
- * USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
}
/*
+ * Magic records per track calculation, copied from fdasd.c
*/
-int
+static unsigned int ceil_quot(unsigned int d1, unsigned int d2)
+{
+ return (d1 + (d2 - 1)) / d2;
+}
+
+unsigned int recs_per_track(unsigned int dl)
+{
+ int dn = ceil_quot(dl + 6, 232) + 1;
+ return 1729 / (10 + 9 + ceil_quot(dl + 6 * dn, 34));
+}
+
+
+typedef unsigned int __attribute__((__may_alias__)) label_ints_t;
+
+/*
+ */
+int
read_dasd_pt(int fd, struct slice all, struct slice *sp, int ns)
{
int retval = -1;
* major/minor into an openable device file, so we have
* to create one for ourselves.
*/
-
+
sprintf(pathname, "/dev/.kpartx-node-%u-%u",
(unsigned int)major(dev), (unsigned int)minor(dev));
if ((fd_dasd = open(pathname, O_RDONLY)) == -1) {
}
if (ioctl(fd_dasd, BIODASDINFO, (unsigned long)&info) != 0) {
- goto out;
+ info.label_block = 2;
+ info.FBA_layout = 0;
+ memcpy(info.type, "ECKD", sizeof(info.type));
}
- if (ioctl(fd_dasd, HDIO_GETGEO, (unsigned long)&geo) != 0) {
+ if (ioctl(fd_dasd, BLKSSZGET, &blocksize) != 0)
goto out;
- }
if (ioctl(fd_dasd, BLKGETSIZE64, &disksize) != 0)
goto out;
- disksize >>= 9;
- if (ioctl(fd_dasd, BLKSSZGET, &blocksize) != 0)
- goto out;
+ if (ioctl(fd_dasd, HDIO_GETGEO, (unsigned long)&geo) != 0) {
+ unsigned int cyl;
+
+ geo.heads = 15;
+ geo.sectors = recs_per_track(blocksize);
+ cyl = disksize / (blocksize * geo.heads * geo.sectors);
+ if (cyl < LV_COMPAT_CYL)
+ geo.cylinders = cyl;
+ else
+ geo.cylinders = LV_COMPAT_CYL;
+ geo.start = 0;
+ }
+
+ disksize >>= 9;
if (blocksize < 512 || blocksize > 4096)
goto out;
/*
* VM style CMS1 labeled disk
*/
- unsigned int *label = (unsigned int *) &vlabel;
+ label_ints_t *label = (label_ints_t *) &vlabel;
blocksize = label[4];
if (label[14] != 0) {
|| EBCtoASC[f1.DS1FMTID] == '5'
|| EBCtoASC[f1.DS1FMTID] == '7'
|| EBCtoASC[f1.DS1FMTID] == '9') {
- blk++;
+ blk++;
continue;
}
break;
/* OK, we got valid partition data */
- offset = cchh2blk(&f1.DS1EXT1.llimit, &geo);
+ offset = cchh2blk(&f1.DS1EXT1.llimit, &geo);
size = cchh2blk(&f1.DS1EXT1.ulimit, &geo) -
offset + geo.sectors;
sp[counter].start = sectors512(offset, blocksize);
retval = 1;
}
- out:
+out:
if (data != NULL)
free(data);
if (fd_dasd != -1 && fd_dasd != fd)