recount_geometry(cxt);
fdisk_reset_alignment(cxt);
+ if (cxt->firstsector_bufsz != cxt->sector_size)
+ fdisk_read_firstsector(cxt);
DBG(CXT, ul_debugobj(cxt, "new C/H/S: %u/%u/%u",
(unsigned) cxt->geom.cylinders,
if (cxt->label && cxt->label->op->reset_alignment)
rc = cxt->label->op->reset_alignment(cxt);
- DBG(CXT, ul_debugobj(cxt, "%s alignment reseted to: "
+ DBG(CXT, ul_debugobj(cxt, "alignment reseted to: "
"first LBA=%ju, last LBA=%ju, grain=%lu [rc=%d]",
- cxt->label ? cxt->label->name : NULL,
(uintmax_t) cxt->first_lba, (uintmax_t) cxt->last_lba,
cxt->grain, rc));
return rc;
cxt->dev_fd = -1;
cxt->dev_path = NULL;
cxt->firstsector = NULL;
+ cxt->firstsector_bufsz = 0;
fdisk_zeroize_device_properties(cxt);
static int dos_create_disklabel(struct fdisk_context *cxt)
{
unsigned int id;
+ int rc;
assert(cxt);
assert(cxt->label);
random_get_bytes(&id, sizeof(id));
dos_init(cxt);
- fdisk_zeroize_firstsector(cxt);
+ rc = fdisk_init_firstsector_buffer(cxt);
+ if (rc)
+ return rc;
fdisk_label_set_changed(cxt->label, 1);
/* Generate an MBR ID for this disk */
struct fdisk_context {
int dev_fd; /* device descriptor */
char *dev_path; /* device path */
+
unsigned char *firstsector; /* buffer with master boot record */
+ unsigned long firstsector_bufsz;
/* topology */
unsigned long io_size; /* I/O size used by fdisk */
extern void fdisk_zeroize_device_properties(struct fdisk_context *cxt);
/* utils.c */
-extern void fdisk_zeroize_firstsector(struct fdisk_context *cxt);
+extern int fdisk_init_firstsector_buffer(struct fdisk_context *cxt);
extern int fdisk_read_firstsector(struct fdisk_context *cxt);
extern char *fdisk_partname(const char *dev, size_t partno);
static int gpt_mknew_pmbr(struct fdisk_context *cxt)
{
struct gpt_legacy_mbr *pmbr = NULL;
+ int rc;
if (!cxt || !cxt->firstsector)
return -ENOSYS;
- fdisk_zeroize_firstsector(cxt);
+ rc = fdisk_init_firstsector_buffer(cxt);
+ if (rc)
+ return rc;
pmbr = (struct gpt_legacy_mbr *) cxt->firstsector;
{
struct fdisk_sgi_label *sgi;
struct sgi_disklabel *sgilabel;
+ int rc;
assert(cxt);
assert(cxt->label);
}
}
#endif
- fdisk_zeroize_firstsector(cxt);
+ rc = fdisk_init_firstsector_buffer(cxt);
+ if (rc)
+ return rc;
+
sgi = (struct fdisk_sgi_label *) cxt->label;
sgi->header = (struct sgi_disklabel *) cxt->firstsector;
unsigned int ndiv;
struct fdisk_sun_label *sun; /* libfdisk sun handler */
struct sun_disklabel *sunlabel; /* on disk data */
+ int rc = 0;
assert(cxt);
assert(cxt->label);
assert(fdisk_is_disklabel(cxt, SUN));
/* map first sector to header */
- fdisk_zeroize_firstsector(cxt);
+ rc = fdisk_init_firstsector_buffer(cxt);
+ if (rc)
+ return rc;
+
sun = (struct fdisk_sun_label *) cxt->label;
sun->header = (struct sun_disklabel *) cxt->firstsector;
#include <ctype.h>
-
/*
* Zeros in-memory first sector buffer
*/
-void fdisk_zeroize_firstsector(struct fdisk_context *cxt)
+int fdisk_init_firstsector_buffer(struct fdisk_context *cxt)
{
- if (!cxt || !cxt->firstsector)
- return;
+ if (!cxt)
+ return -EINVAL;
+
+ if (!cxt->firstsector || cxt->firstsector_bufsz != cxt->sector_size) {
+ /* Let's allocate a new buffer if no allocated yet, or the
+ * current buffer has incorrect size */
+ free(cxt->firstsector);
+
+ DBG(CXT, ul_debugobj(cxt, "initialize in-memory first sector "
+ "buffer [sector_size=%lu]", cxt->sector_size));
+ cxt->firstsector = calloc(1, cxt->sector_size);
+ if (!cxt->firstsector)
+ return -ENOMEM;
+
+ cxt->firstsector_bufsz = cxt->sector_size;
+ return 0;
+ }
DBG(CXT, ul_debugobj(cxt, "zeroize in-memory first sector buffer"));
- memset(cxt->firstsector, 0, cxt->sector_size);
+ memset(cxt->firstsector, 0, cxt->firstsector_bufsz);
+ return 0;
}
int fdisk_read_firstsector(struct fdisk_context *cxt)
{
ssize_t r;
+ int rc;
assert(cxt);
assert(cxt->sector_size);
- DBG(CXT, ul_debugobj(cxt, "initialize first sector "
- "buffer [sector_size=%lu]", cxt->sector_size));
+ rc = fdisk_init_firstsector_buffer(cxt);
+ if (rc)
+ return rc;
- if (!cxt->firstsector) {
- cxt->firstsector = calloc(1, cxt->sector_size);
- if (!cxt->firstsector)
- return -ENOMEM;
- } else
- fdisk_zeroize_firstsector(cxt);
+ assert(cxt->sector_size == cxt->firstsector_bufsz);
+
+ DBG(CXT, ul_debugobj(cxt, "reading first sector "
+ "buffer [sector_size=%lu]", cxt->sector_size));
r = read(cxt->dev_fd, cxt->firstsector, cxt->sector_size);