[syslinux] [PATCH 6/9] Make sector size dynamic in extlinux
Frediano Ziglio
frediano.ziglio at citrix.com
Wed Oct 3 07:26:11 PDT 2012
Instead of using SECTOR_SIZE as a constant everywhere pass the sector size
to syslinux_patch.
This patch compute read sector size only in extlinux.
Signed-off-by: Frediano Ziglio <frediano.ziglio at citrix.com>
---
dos/syslinux.c | 2 +-
extlinux/main.c | 36 +++++++++++++++++++++++++-----------
libinstaller/syslinux.h | 3 ++-
libinstaller/syslxcom.c | 30 +++++++++++++++---------------
libinstaller/syslxcom.h | 2 +-
libinstaller/syslxmod.c | 14 ++++++++------
linux/syslinux.c | 4 ++--
mtools/syslinux.c | 2 +-
win/syslinux.c | 3 ++-
9 files changed, 57 insertions(+), 39 deletions(-)
diff --git a/dos/syslinux.c b/dos/syslinux.c
index fa4bf38..6cd36d0 100644
--- a/dos/syslinux.c
+++ b/dos/syslinux.c
@@ -723,7 +723,7 @@ int main(int argc, char *argv[])
/*
* Patch ldlinux.sys and the boot sector
*/
- i = syslinux_patch(sectors, nsectors, opt.stupid_mode, opt.raid_mode, opt.directory, NULL);
+ i = syslinux_patch(sectors, nsectors, opt.stupid_mode, opt.raid_mode, opt.directory, NULL, SECTOR_SIZE);
patch_sectors = (i + SECTOR_SIZE - 1) >> SECTOR_SHIFT;
/*
diff --git a/extlinux/main.c b/extlinux/main.c
index f0d8e11..e40b4d7 100644
--- a/extlinux/main.c
+++ b/extlinux/main.c
@@ -95,6 +95,18 @@ static uint64_t get_size(int devfd)
}
/*
+ * Get sector size
+ */
+static unsigned get_sector_size(int devfd)
+{
+ int size;
+
+ if (!ioctl(devfd, BLKSSZGET, &size))
+ return size;
+ return SECTOR_SIZE;
+}
+
+/*
* Get device geometry and partition offset
*/
struct geometry_table {
@@ -145,7 +157,7 @@ static const struct geometry_table standard_geometries[] = {
{0, {0, 0, 0, 0}}
};
-int get_geometry(int devfd, uint64_t totalbytes, struct hd_geometry *geo)
+static int get_geometry(int devfd, uint64_t totalbytes, unsigned sector_size, struct hd_geometry *geo)
{
struct floppy_struct fd_str;
struct loop_info li;
@@ -179,7 +191,7 @@ int get_geometry(int devfd, uint64_t totalbytes, struct hd_geometry *geo)
geo->heads = opt.heads ? : 64;
geo->sectors = opt.sectors ? : 32;
- geo->cylinders = totalbytes / (geo->heads * geo->sectors << SECTOR_SHIFT);
+ geo->cylinders = totalbytes / (geo->heads * geo->sectors * sector_size);
geo->start = 0;
if (!opt.sectors && !opt.heads) {
@@ -193,11 +205,11 @@ int get_geometry(int devfd, uint64_t totalbytes, struct hd_geometry *geo)
ok:
/* If this is a loopback device, try to set the start */
if (!ioctl(devfd, LOOP_GET_STATUS64, &li64))
- geo->start = li64.lo_offset >> SECTOR_SHIFT;
+ geo->start = li64.lo_offset / sector_size;
else if (!ioctl(devfd, LOOP_GET_STATUS, &li))
- geo->start = (unsigned int)li.lo_offset >> SECTOR_SHIFT;
+ geo->start = (unsigned int)li.lo_offset / sector_size;
else if (!sysfs_get_offset(devfd, &geo->start)) {
- /* OK */
+ geo->start /= (sector_size / SECTOR_SIZE);
}
return rv;
@@ -220,6 +232,7 @@ static int patch_file_and_bootblock(int fd, const char *dir, int devfd)
struct fat_boot_sector *sbs;
char *dirpath, *subpath, *xdirpath;
int rv;
+ unsigned sector_size;
dirpath = realpath(dir, NULL);
if (!dirpath || stat(dir, &dirst)) {
@@ -262,7 +275,8 @@ static int patch_file_and_bootblock(int fd, const char *dir, int devfd)
dprintf("subpath = %s\n", subpath);
totalbytes = get_size(devfd);
- get_geometry(devfd, totalbytes, &geo);
+ sector_size = get_sector_size(devfd);
+ get_geometry(devfd, totalbytes, sector_size, &geo);
if (opt.heads)
geo.heads = opt.heads;
@@ -276,7 +290,7 @@ static int patch_file_and_bootblock(int fd, const char *dir, int devfd)
sbs = (struct fat_boot_sector *)syslinux_bootsect;
- totalsectors = totalbytes >> SECTOR_SHIFT;
+ totalsectors = totalbytes / sector_size;
if (totalsectors >= 65536) {
set_16(&sbs->bsSectors, 0);
} else {
@@ -284,7 +298,7 @@ static int patch_file_and_bootblock(int fd, const char *dir, int devfd)
}
set_32(&sbs->bsHugeSectors, totalsectors);
- set_16(&sbs->bsBytesPerSec, SECTOR_SIZE);
+ set_16(&sbs->bsBytesPerSec, sector_size);
set_16(&sbs->bsSecPerTrack, geo.sectors);
set_16(&sbs->bsHeads, geo.heads);
set_32(&sbs->bsHiddenSecs, geo.start);
@@ -292,11 +306,11 @@ static int patch_file_and_bootblock(int fd, const char *dir, int devfd)
/* Construct the boot file map */
dprintf("directory inode = %lu\n", (unsigned long)dirst.st_ino);
- nsect = (boot_image_len + SECTOR_SIZE - 1) >> SECTOR_SHIFT;
+ nsect = (boot_image_len + sector_size - 1) / sector_size;
nsect += 2; /* Two sectors for the ADV */
sectp = alloca(sizeof(sector_t) * nsect);
if (fs_type == EXT2 || fs_type == VFAT || fs_type == NTFS) {
- if (sectmap(fd, sectp, nsect)) {
+ if (sectmap(fd, sectp, nsect, sector_size)) {
perror("bmap");
exit(1);
}
@@ -312,7 +326,7 @@ static int patch_file_and_bootblock(int fd, const char *dir, int devfd)
/* Create the modified image in memory */
rv = syslinux_patch(sectp, nsect, opt.stupid_mode,
- opt.raid_mode, subpath, subvol);
+ opt.raid_mode, subpath, subvol, sector_size);
free(dirpath);
return rv;
diff --git a/libinstaller/syslinux.h b/libinstaller/syslinux.h
index 8b86f88..75ed451 100644
--- a/libinstaller/syslinux.h
+++ b/libinstaller/syslinux.h
@@ -49,6 +49,7 @@ const char *syslinux_check_bootsect(const void *bs, int *fs_type);
typedef uint64_t sector_t;
int syslinux_patch(const sector_t *sectors, int nsectors,
int stupid, int raid_mode,
- const char *subdir, const char *subvol);
+ const char *subdir, const char *subvol,
+ unsigned sector_size);
#endif
diff --git a/libinstaller/syslxcom.c b/libinstaller/syslxcom.c
index 57f13cd..95a7110 100644
--- a/libinstaller/syslxcom.c
+++ b/libinstaller/syslxcom.c
@@ -45,8 +45,6 @@ int fs_type;
# define dprintf(...) ((void)0)
#endif
-#define SECTOR_SHIFT 9
-
static void die(const char *msg)
{
fputs(msg, stderr);
@@ -176,7 +174,7 @@ void set_attributes(int fd)
}
/* New FIEMAP based mapping */
-static int sectmap_fie(int fd, sector_t *sectors, int nsectors)
+static int sectmap_fie(int fd, sector_t *sectors, int nsectors, unsigned sector_size)
{
struct fiemap *fm;
struct fiemap_extent *fe;
@@ -193,7 +191,7 @@ static int sectmap_fie(int fd, sector_t *sectors, int nsectors)
memset(fm, 0, sizeof *fm);
- maplen = (uint64_t)nsectors << SECTOR_SHIFT;
+ maplen = (uint64_t)nsectors * sector_size;
if (maplen > (uint64_t)st.st_size)
maplen = st.st_size;
@@ -217,12 +215,12 @@ static int sectmap_fie(int fd, sector_t *sectors, int nsectors)
for (i = 0; i < fm->fm_mapped_extents; i++) {
if (fe->fe_flags & FIEMAP_EXTENT_LAST) {
/* If this is the *final* extent, pad the length */
- fe->fe_length = (fe->fe_length + SECTOR_SIZE - 1)
- & ~(SECTOR_SIZE - 1);
+ fe->fe_length = (fe->fe_length + sector_size - 1)
+ & ~(sector_size - 1);
}
if ((fe->fe_logical | fe->fe_physical| fe->fe_length) &
- (SECTOR_SIZE - 1))
+ (sector_size - 1))
return -1;
if (fe->fe_flags & (FIEMAP_EXTENT_UNKNOWN|
@@ -232,9 +230,9 @@ static int sectmap_fie(int fd, sector_t *sectors, int nsectors)
FIEMAP_EXTENT_UNWRITTEN))
return -1;
- secp = sectors + (fe->fe_logical >> SECTOR_SHIFT);
- sec = fe->fe_physical >> SECTOR_SHIFT;
- nsec = fe->fe_length >> SECTOR_SHIFT;
+ secp = sectors + (fe->fe_logical / sector_size);
+ sec = fe->fe_physical / sector_size;
+ nsec = fe->fe_length / sector_size;
while (nsec--) {
if (secp >= esec)
@@ -249,7 +247,7 @@ static int sectmap_fie(int fd, sector_t *sectors, int nsectors)
}
/* Legacy FIBMAP based mapping */
-static int sectmap_fib(int fd, sector_t *sectors, int nsectors)
+static int sectmap_fib(int fd, sector_t *sectors, int nsectors, unsigned sector_size)
{
unsigned int blk, nblk;
unsigned int i;
@@ -261,7 +259,9 @@ static int sectmap_fib(int fd, sector_t *sectors, int nsectors)
return -1;
/* Number of sectors per block */
- blksize >>= SECTOR_SHIFT;
+ blksize /= sector_size;
+ if (blksize == 0)
+ return -1;
nblk = 0;
while (nsectors) {
@@ -283,12 +283,12 @@ static int sectmap_fib(int fd, sector_t *sectors, int nsectors)
/*
* Produce file map
*/
-int sectmap(int fd, sector_t *sectors, int nsectors)
+int sectmap(int fd, sector_t *sectors, int nsectors, unsigned sector_size)
{
- if (!sectmap_fie(fd, sectors, nsectors))
+ if (!sectmap_fie(fd, sectors, nsectors, sector_size))
return 0;
- return sectmap_fib(fd, sectors, nsectors);
+ return sectmap_fib(fd, sectors, nsectors, sector_size);
}
/*
diff --git a/libinstaller/syslxcom.h b/libinstaller/syslxcom.h
index 8b3b461..111b634 100644
--- a/libinstaller/syslxcom.h
+++ b/libinstaller/syslxcom.h
@@ -8,7 +8,7 @@ ssize_t xpread(int fd, void *buf, size_t count, off_t offset);
ssize_t xpwrite(int fd, const void *buf, size_t count, off_t offset);
void clear_attributes(int fd);
void set_attributes(int fd);
-int sectmap(int fd, sector_t *sectors, int nsectors);
+int sectmap(int fd, sector_t *sectors, int nsectors, unsigned sector_size);
int syslinux_already_installed(int dev_fd);
#endif
diff --git a/libinstaller/syslxmod.c b/libinstaller/syslxmod.c
index c706f2c..be101f9 100644
--- a/libinstaller/syslxmod.c
+++ b/libinstaller/syslxmod.c
@@ -31,7 +31,8 @@
* Generate sector extents
*/
static void generate_extents(struct syslinux_extent *ex, int nptrs,
- const sector_t *sectp, int nsect)
+ const sector_t *sectp, int nsect,
+ unsigned sector_size)
{
uint32_t addr = 0x8000; /* ldlinux.sys starts loading here */
uint32_t base;
@@ -47,7 +48,7 @@ static void generate_extents(struct syslinux_extent *ex, int nptrs,
sect = *sectp++;
if (len) {
- uint32_t xbytes = (len + 1) * SECTOR_SIZE;
+ uint32_t xbytes = (len + 1) * sector_size;
if (sect == lba + len && xbytes < 65536 &&
((addr ^ (base + xbytes - 1)) & 0xffff0000) == 0) {
@@ -66,7 +67,7 @@ static void generate_extents(struct syslinux_extent *ex, int nptrs,
len = 1;
next:
- addr += SECTOR_SIZE;
+ addr += sector_size;
nsect--;
}
@@ -98,13 +99,14 @@ static inline void *ptr(void *img, uint16_t *offset_p)
*/
int syslinux_patch(const sector_t *sectp, int nsectors,
int stupid, int raid_mode,
- const char *subdir, const char *subvol)
+ const char *subdir, const char *subvol,
+ unsigned sector_size)
{
struct patch_area *patcharea;
struct ext_patch_area *epa;
struct syslinux_extent *ex;
uint32_t *wp;
- int nsect = ((boot_image_len + SECTOR_SIZE - 1) >> SECTOR_SHIFT) + 2;
+ int nsect = ((boot_image_len + sector_size - 1) / sector_size) + 2;
uint32_t csum;
int i, dw, nptrs;
struct fat_boot_sector *sbs = (struct fat_boot_sector *)boot_sector;
@@ -154,7 +156,7 @@ int syslinux_patch(const sector_t *sectp, int nsectors,
}
/* -1 for the pointer in the boot sector, -2 for the two ADVs */
- generate_extents(ex, nptrs, sectp, nsect-1-2);
+ generate_extents(ex, nptrs, sectp, nsect-1-2, sector_size);
/* ADV pointers */
advptrs = ptr(boot_image, &epa->advptroffset);
diff --git a/linux/syslinux.c b/linux/syslinux.c
index 4b13b7f..22983f9 100755
--- a/linux/syslinux.c
+++ b/linux/syslinux.c
@@ -444,7 +444,7 @@ int main(int argc, char *argv[])
*/
ldlinux_sectors += 2; /* 2 ADV sectors */
sectors = calloc(ldlinux_sectors, sizeof *sectors);
- if (sectmap(fd, sectors, ldlinux_sectors)) {
+ if (sectmap(fd, sectors, ldlinux_sectors, SECTOR_SIZE)) {
perror("bmap");
exit(1);
}
@@ -463,7 +463,7 @@ umount:
* Patch ldlinux.sys and the boot sector
*/
i = syslinux_patch(sectors, ldlinux_sectors, opt.stupid_mode,
- opt.raid_mode, subdir, NULL);
+ opt.raid_mode, subdir, NULL, SECTOR_SIZE);
patch_sectors = (i + SECTOR_SIZE - 1) >> SECTOR_SHIFT;
/*
diff --git a/mtools/syslinux.c b/mtools/syslinux.c
index c65021b..6f3550f 100755
--- a/mtools/syslinux.c
+++ b/mtools/syslinux.c
@@ -273,7 +273,7 @@ int main(int argc, char *argv[])
/* Patch ldlinux.sys and the boot sector */
i = syslinux_patch(sectors, nsectors, opt.stupid_mode, opt.raid_mode,
- opt.directory, NULL);
+ opt.directory, NULL, SECTOR_SIZE);
patch_sectors = (i + SECTOR_SIZE - 1) >> SECTOR_SHIFT;
/* Write the now-patched first sectors of ldlinux.sys */
diff --git a/win/syslinux.c b/win/syslinux.c
index 669450e..cbf003f 100644
--- a/win/syslinux.c
+++ b/win/syslinux.c
@@ -432,7 +432,8 @@ map_done:
/*
* Patch ldlinux.sys and the boot sector
*/
- syslinux_patch(sectors, nsectors, opt.stupid_mode, opt.raid_mode, opt.directory, NULL);
+ syslinux_patch(sectors, nsectors, opt.stupid_mode, opt.raid_mode, opt.directory, NULL,
+ SECTOR_SIZE);
/*
* Rewrite the file
--
1.7.5.4
More information about the Syslinux
mailing list