]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
fdisk: API: add write to label operations
authorDavidlohr Bueso <dave@gnu.org>
Mon, 23 Jul 2012 16:47:42 +0000 (18:47 +0200)
committerKarel Zak <kzak@redhat.com>
Tue, 24 Jul 2012 07:13:59 +0000 (09:13 +0200)
[kzak@redhat.com: - rename functions
                  - use errno]

Signed-off-by: Karel Zak <kzak@redhat.com>
Signed-off-by: Davidlohr Bueso <dave@gnu.org>
12 files changed:
fdisks/fdisk.c
fdisks/fdisk.h
fdisks/fdiskaixlabel.c
fdisks/fdiskbsdlabel.c
fdisks/fdiskdoslabel.c
fdisks/fdiskdoslabel.h
fdisks/fdiskmaclabel.c
fdisks/fdisksgilabel.c
fdisks/fdisksgilabel.h
fdisks/fdisksunlabel.c
fdisks/fdisksunlabel.h
fdisks/utils.c

index ec31b14d868e9a6c022ce3b5e0a52095d45c9eeb..f25f2aec05962bf64ad661411250ea75e4ae1d30 100644 (file)
@@ -1420,24 +1420,13 @@ static void new_partition(struct fdisk_context *cxt)
        dos_new_partition(cxt);
 }
 
-static void
-write_table(struct fdisk_context *cxt) {
-       int i;
+static void write_table(struct fdisk_context *cxt)
+{
+       int rc;
 
-       if (disklabel == DOS_LABEL)
-               dos_write_table(cxt);
-       else if (disklabel == SGI_LABEL)
-               /* no test on change? the printf below might be mistaken */
-               sgi_write_table(cxt);
-       else if (disklabel == SUN_LABEL) {
-               int needw = 0;
-
-               for (i=0; i<8; i++)
-                       if (ptes[i].changed)
-                               needw = 1;
-               if (needw)
-                       sun_write_table(cxt);
-       }
+       rc = fdisk_write_disklabel(cxt);
+       if (rc)
+               err(EXIT_FAILURE, _("cannot write disk label"));
 
        printf(_("The partition table has been altered!\n\n"));
        reread_partition_table(cxt, 1);
index 2a04b8372ccddcee09cdf9743c7a6bfc2c7f4f9e..9ce2c25b06e727b0b4220afffc37752eeaa27f3b 100644 (file)
@@ -137,6 +137,8 @@ struct fdisk_label {
 
        /* probe disk label */
        int (*probe)(struct fdisk_context *cxt);
+       /* write in-memory changes to disk */
+       int (*write)(struct fdisk_context *cxt);
        /* delete partition */
        void (*part_delete)(struct fdisk_context *cxt, int partnum);
 };
@@ -163,6 +165,7 @@ extern int fdisk_context_set_user_geometry(struct fdisk_context *cxt,
                            unsigned int sectors);
 extern int fdisk_create_default_disklabel(struct fdisk_context *cxt);
 extern int fdisk_delete_partition(struct fdisk_context *cxt, int partnum);
+extern int fdisk_write_disklabel(struct fdisk_context *cxt);
 
 /* prototypes for fdisk.c */
 extern char *disk_device, *line_ptr;
@@ -265,13 +268,6 @@ static inline void read_sector(struct fdisk_context *cxt, sector_t secno, unsign
                fatal(cxt, unable_to_read);
 }
 
-static inline void write_sector(struct fdisk_context *cxt, sector_t secno, unsigned char *buf)
-{
-       seek_sector(cxt, secno);
-       if (write(cxt->dev_fd, buf, cxt->sector_size) != (ssize_t) cxt->sector_size)
-               fatal(cxt, unable_to_write);
-}
-
 static inline sector_t get_start_sect(struct partition *p)
 {
        return read4_little_endian(p->start4);
index 658b7e4cfc41f1e51bfc6811d403aca122b9f6a6..c8cb660e0c4fec2c9c45d9ef4adcd94be765d209 100644 (file)
@@ -69,5 +69,6 @@ const struct fdisk_label aix_label =
 {
        .name = "aix",
        .probe = aix_probe_label,
+       .write = NULL,
        .part_delete = NULL,
 };
index ae83d2e7f4fbf1bd6dfa081f3f5e33da30cc8faa..50bd840d78aa00d925f8a2fe7b96510863f97227 100644 (file)
@@ -63,7 +63,6 @@
 
 static void xbsd_delete_part (struct fdisk_context *cxt, int partnum);
 static void xbsd_new_part (struct fdisk_context *cxt);
-static void xbsd_write_disklabel (struct fdisk_context *cxt);
 static int xbsd_create_disklabel (struct fdisk_context *cxt);
 static void xbsd_edit_disklabel (void);
 static void xbsd_write_bootstrap (struct fdisk_context *cxt);
@@ -140,6 +139,21 @@ is_bsd_partition_type(int type) {
 }
 #endif
 
+static int xbsd_write_disklabel (struct fdisk_context *cxt)
+{
+#if defined (__alpha__)
+       printf (_("Writing disklabel to %s.\n"), cxt->dev_path);
+       xbsd_writelabel (cxt, NULL, &xbsd_dlabel);
+#else
+       printf (_("Writing disklabel to %s.\n"),
+               partname(cxt->dev_path, xbsd_part_index+1, 0));
+       xbsd_writelabel (cxt, xbsd_part, &xbsd_dlabel);
+#endif
+       reread_partition_table(cxt, 0); /* no exit yet */
+
+       return 0;
+}
+
 void
 bsd_command_prompt (struct fdisk_context *cxt)
 {
@@ -376,19 +390,6 @@ xbsd_print_disklabel (struct fdisk_context *cxt, int show_all) {
   }
 }
 
-static void
-xbsd_write_disklabel (struct fdisk_context *cxt) {
-#if defined (__alpha__)
-       printf (_("Writing disklabel to %s.\n"), cxt->dev_path);
-       xbsd_writelabel (cxt, NULL, &xbsd_dlabel);
-#else
-       printf (_("Writing disklabel to %s.\n"),
-               partname(cxt->dev_path, xbsd_part_index+1, 0));
-       xbsd_writelabel (cxt, xbsd_part, &xbsd_dlabel);
-#endif
-       reread_partition_table(cxt, 0); /* no exit yet */
-}
-
 static int
 xbsd_create_disklabel (struct fdisk_context *cxt) {
        char c;
@@ -846,5 +847,6 @@ const struct fdisk_label bsd_label =
 {
        .name = "bsd",
        .probe = osf_probe_label,
+       .write = xbsd_write_disklabel,
        .part_delete = xbsd_delete_part,
 };
index d9369b6917e224562057fdc9884be8a59d8525cc..398e5e0402a832add3dea31875307731d88a9f46 100644 (file)
@@ -706,9 +706,18 @@ void dos_new_partition(struct fdisk_context *cxt)
        }
 }
 
-void dos_write_table(struct fdisk_context *cxt)
+static int write_sector(struct fdisk_context *cxt, sector_t secno,
+                              unsigned char *buf)
 {
-       int i;
+       seek_sector(cxt, secno);
+       if (write(cxt->dev_fd, buf, cxt->sector_size) != (ssize_t) cxt->sector_size)
+               return -errno;
+       return 0;
+}
+
+static int dos_write_disklabel(struct fdisk_context *cxt)
+{
+       int i, rc = 0;
 
        /* MBR (primary partitions) */
        if (!MBRbuffer_changed) {
@@ -718,7 +727,9 @@ void dos_write_table(struct fdisk_context *cxt)
        }
        if (MBRbuffer_changed) {
                mbr_set_magic(cxt->firstsector);
-               write_sector(cxt, 0, cxt->firstsector);
+               rc = write_sector(cxt, 0, cxt->firstsector);
+               if (rc)
+                       goto done;
        }
        /* EBR (logical partitions) */
        for (i = 4; i < partitions; i++) {
@@ -726,14 +737,20 @@ void dos_write_table(struct fdisk_context *cxt)
 
                if (pe->changed) {
                        mbr_set_magic(pe->sectorbuffer);
-                       write_sector(cxt, pe->offset, pe->sectorbuffer);
+                       rc = write_sector(cxt, pe->offset, pe->sectorbuffer);
+                       if (rc)
+                               goto done;
                }
        }
+
+done:
+       return rc;
 }
 
 const struct fdisk_label dos_label =
 {
        .name = "dos",
        .probe = dos_probe_label,
+       .write = dos_write_disklabel,
        .part_delete = dos_delete_partition,
 };
index 2d3620019f79e4e6b2db9f3d5c6abaac1399fd80..d7361a806cb4f83be37ee240774d8d2d28b26a80 100644 (file)
@@ -44,7 +44,6 @@ extern int is_dos_partition(int t);
 extern void dos_init(struct fdisk_context *cxt);
 extern void dos_add_partition(struct fdisk_context *cxt, int n, int sys);
 extern void dos_new_partition(struct fdisk_context *cxt);
-extern void dos_write_table(struct fdisk_context *cxt);
 
 extern int mbr_is_valid_magic(unsigned char *b);
 
index c579a58f1e338e393556594dc70fd332c8207fa3..4e80d395bdb38b8493cfa2c3f7d80327f4cede0f 100644 (file)
@@ -84,5 +84,6 @@ const struct fdisk_label mac_label =
 {
        .name = "mac",
        .probe = mac_probe_label,
+       .write = NULL,
        .part_delete = NULL,
 };
index 0ee3a83afc6a932bb45e6cdc9d7011366d50cf5c..836b9d4a7ad22c78034caaa98350c743e3727578 100644 (file)
@@ -39,6 +39,8 @@ static        int     other_endian = 0;
 static int     debug = 0;
 static  short volumes=1;
 
+static sgiinfo *fill_sgiinfo(void);
+
 /*
  * only dealing with free blocks here
  */
@@ -328,10 +330,11 @@ create_sgiinfo(struct fdisk_context *cxt) {
        strncpy((char *) sgilabel->directory[0].vol_file_name, "sgilabel", 8);
 }
 
-sgiinfo *fill_sgiinfo(void);
 
-void
-sgi_write_table(struct fdisk_context *cxt) {
+static int sgi_write_disklabel(struct fdisk_context *cxt)
+{
+       sgiinfo *info = NULL;
+
        sgilabel->csum = 0;
        sgilabel->csum = SSWAP32(two_s_complement_32bit_sum(
                (unsigned int*)sgilabel,
@@ -339,23 +342,34 @@ sgi_write_table(struct fdisk_context *cxt) {
        assert(two_s_complement_32bit_sum(
                (unsigned int*)sgilabel, sizeof(*sgilabel)) == 0);
        if (lseek(cxt->dev_fd, 0, SEEK_SET) < 0)
-               fatal(cxt, unable_to_seek);
+               goto err;
        if (write(cxt->dev_fd, sgilabel, SECTOR_SIZE) != SECTOR_SIZE)
-               fatal(cxt, unable_to_write);
-       if (! strncmp((char *) sgilabel->directory[0].vol_file_name, "sgilabel", 8)) {
+               goto err;
+       if (!strncmp((char *) sgilabel->directory[0].vol_file_name, "sgilabel", 8)) {
                /*
                 * keep this habit of first writing the "sgilabel".
                 * I never tested whether it works without (AN 981002).
                 */
-               sgiinfo *info = fill_sgiinfo();
-               int infostartblock = SSWAP32(sgilabel->directory[0].vol_file_start);
-               if (lseek(cxt->dev_fd, (off_t) infostartblock*
-                               SECTOR_SIZE, SEEK_SET) < 0)
-                       fatal(cxt, unable_to_seek);
+               int infostartblock
+                       = SSWAP32(sgilabel->directory[0].vol_file_start);
+
+               if (lseek(cxt->dev_fd, (off_t) infostartblock *
+                                               SECTOR_SIZE, SEEK_SET) < 0)
+                       goto err;
+
+               info = fill_sgiinfo();
+               if (!info)
+                       goto err;
+
                if (write(cxt->dev_fd, info, SECTOR_SIZE) != SECTOR_SIZE)
-                       fatal(cxt, unable_to_write);
-               free(info);
+                       goto err;
        }
+
+       free(info);
+       return 0;
+err:
+       free(info);
+       return -errno;
 }
 
 static int
@@ -865,10 +879,13 @@ sgi_set_ncyl(void)
 /* _____________________________________________________________
  */
 
-sgiinfo *
-fill_sgiinfo(void)
+static sgiinfo *fill_sgiinfo(void)
 {
-       sgiinfo *info=xcalloc(1, sizeof(sgiinfo));
+       sgiinfo *info = calloc(1, sizeof(sgiinfo));
+
+       if (!info)
+               return NULL;
+
        info->magic=SSWAP32(SGI_INFO_MAGIC);
        info->b1=SSWAP32(-1);
        info->b2=SSWAP16(-1);
@@ -885,5 +902,6 @@ const struct fdisk_label sgi_label =
 {
        .name = "sgi",
        .probe = sgi_probe_label,
+       .write = sgi_write_disklabel,
        .part_delete = sgi_delete_partition,
 };
index 96e96548e9679a404df6f94279a7f505ea13e238..412ec7422c8159a7d445bc06f1d5ae5289cea746 100644 (file)
@@ -120,7 +120,6 @@ extern void sgi_add_partition( struct fdisk_context *cxt, int n, int sys );
 extern void    create_sgilabel( struct fdisk_context *cxt );
 extern void    create_sgiinfo(struct fdisk_context *cxt);
 extern int     verify_sgi(struct fdisk_context *cxt, int verbose );
-extern void    sgi_write_table( struct fdisk_context *cxt );
 extern void    sgi_set_ilfact( void );
 extern void    sgi_set_rspeed( void );
 extern void    sgi_set_pcylcount( void );
index 7c369f3e64ddaeb59af608ef9c46694708fc46fd..3b0b757adb5a2d48adef4b9cfb42c898118ef7a6 100644 (file)
@@ -626,7 +626,7 @@ void sun_set_pcylcount(struct fdisk_context *cxt)
                                 _("Number of physical cylinders")));
 }
 
-void sun_write_table(struct fdisk_context *cxt)
+static int sun_write_disklabel(struct fdisk_context *cxt)
 {
        unsigned short *ush = (unsigned short *)sunlabel;
        unsigned short csum = 0;
@@ -635,9 +635,11 @@ void sun_write_table(struct fdisk_context *cxt)
                csum ^= *ush++;
        sunlabel->cksum = csum;
        if (lseek(cxt->dev_fd, 0, SEEK_SET) < 0)
-               fatal(cxt, unable_to_seek);
+               return -errno;
        if (write(cxt->dev_fd, sunlabel, SECTOR_SIZE) != SECTOR_SIZE)
-               fatal(cxt, unable_to_write);
+               return -errno;
+
+       return 0;
 }
 
 int sun_get_sysid(struct fdisk_context *cxt, int i)
@@ -649,5 +651,6 @@ const struct fdisk_label sun_label =
 {
        .name = "sun",
        .probe = sun_probe_label,
+       .write = sun_write_disklabel,
        .part_delete = sun_delete_partition,
 };
index d416401ba97c89acdeeecba2d797fc263b938e5e..d33a5aa6f81932e99b5f6a1fa96553e63fdb4931 100644 (file)
@@ -82,7 +82,6 @@ extern int sun_change_sysid(struct fdisk_context *cxt, int i, uint16_t sys);
 extern void sun_list_table(struct fdisk_context *cxt, int xtra);
 extern void verify_sun(struct fdisk_context *cxt);
 extern void add_sun_partition(struct fdisk_context *cxt, int n, int sys);
-extern void sun_write_table(struct fdisk_context *cxt);
 extern void sun_set_alt_cyl(struct fdisk_context *cxt);
 extern void sun_set_ncyl(struct fdisk_context *cxt, int cyl);
 extern void sun_set_xcyl(struct fdisk_context *cxt);
index 932fa16f003d83d184bc1782070125e07043aa24..08f0fe6bd6c95e7d3c451b1d1cd90f2c4312ea2f 100644 (file)
@@ -47,6 +47,22 @@ static const struct fdisk_label *labels[] =
        &mac_label,
 };
 
+/**
+ * fdisk_write_disklabel
+ * @cxt: fdisk context
+ *
+ * Write in-memory changes to disk
+ *
+ * Returns 0 on success, otherwise, a corresponding error.
+ */
+int fdisk_write_disklabel(struct fdisk_context *cxt)
+{
+       if (!cxt)
+               return -EINVAL;
+
+       return cxt->label->write(cxt);
+}
+
 /**
  * fdisk_delete_partition:
  * @cxt: fdisk context