Use O_DIRECT for all IO to devices.
Using buffered IO risks non-atomic updates to parts of the device that we don't actually want to write to. This isn't in general safe. So switch to O_DIRECT for all that IO and make sure we have properly aligned buffers.
This commit is contained in:
parent
908ef18519
commit
6416d5275d
2
Grow.c
2
Grow.c
|
@ -69,7 +69,7 @@ int Grow_Add_device(char *devname, int fd, char *newdev)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
nfd = open(newdev, O_RDWR|O_EXCL);
|
nfd = open(newdev, O_RDWR|O_EXCL|O_DIRECT);
|
||||||
if (nfd < 0) {
|
if (nfd < 0) {
|
||||||
fprintf(stderr, Name ": cannot open %s\n", newdev);
|
fprintf(stderr, Name ": cannot open %s\n", newdev);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
2
Kill.c
2
Kill.c
|
@ -44,7 +44,7 @@ int Kill(char *dev, int force, int quiet, int noexcl)
|
||||||
int fd, rv = 0;
|
int fd, rv = 0;
|
||||||
struct supertype *st;
|
struct supertype *st;
|
||||||
|
|
||||||
fd = open(dev, noexcl ? O_RDWR : (O_RDWR|O_EXCL));
|
fd = open(dev, O_DIRECT | (noexcl ? O_RDWR : (O_RDWR|O_EXCL)));
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
if (!quiet)
|
if (!quiet)
|
||||||
fprintf(stderr, Name ": Couldn't open %s for write - not zeroing\n",
|
fprintf(stderr, Name ": Couldn't open %s for write - not zeroing\n",
|
||||||
|
|
4
Manage.c
4
Manage.c
|
@ -315,7 +315,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/* Make sure it isn't in use (in 2.6 or later) */
|
/* Make sure it isn't in use (in 2.6 or later) */
|
||||||
tfd = open(dv->devname, O_RDONLY|O_EXCL);
|
tfd = open(dv->devname, O_RDONLY|O_EXCL|O_DIRECT);
|
||||||
if (tfd < 0) {
|
if (tfd < 0) {
|
||||||
fprintf(stderr, Name ": Cannot open %s: %s\n",
|
fprintf(stderr, Name ": Cannot open %s: %s\n",
|
||||||
dv->devname, strerror(errno));
|
dv->devname, strerror(errno));
|
||||||
|
@ -458,7 +458,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||||
int dfd;
|
int dfd;
|
||||||
if (dv->writemostly)
|
if (dv->writemostly)
|
||||||
disc.state |= 1 << MD_DISK_WRITEMOSTLY;
|
disc.state |= 1 << MD_DISK_WRITEMOSTLY;
|
||||||
dfd = open(dv->devname, O_RDWR | O_EXCL);
|
dfd = open(dv->devname, O_RDWR | O_EXCL|O_DIRECT);
|
||||||
tst->ss->add_to_super(tst, &disc, dfd,
|
tst->ss->add_to_super(tst, &disc, dfd,
|
||||||
dv->devname);
|
dv->devname);
|
||||||
/* write_init_super will close 'dfd' */
|
/* write_init_super will close 'dfd' */
|
||||||
|
|
6
bitmap.c
6
bitmap.c
|
@ -122,11 +122,10 @@ bitmap_info_t *bitmap_fd_read(int fd, int brief)
|
||||||
*/
|
*/
|
||||||
unsigned long long total_bits = 0, read_bits = 0, dirty_bits = 0;
|
unsigned long long total_bits = 0, read_bits = 0, dirty_bits = 0;
|
||||||
bitmap_info_t *info;
|
bitmap_info_t *info;
|
||||||
char *buf, *unaligned;
|
void *buf;
|
||||||
int n, skip;
|
int n, skip;
|
||||||
|
|
||||||
unaligned = malloc(8192*2);
|
posix_memalign(&buf, 512, 8192);
|
||||||
buf = (char*) ((unsigned long)unaligned | 8191)+1;
|
|
||||||
n = read(fd, buf, 8192);
|
n = read(fd, buf, 8192);
|
||||||
|
|
||||||
info = malloc(sizeof(*info));
|
info = malloc(sizeof(*info));
|
||||||
|
@ -145,7 +144,6 @@ bitmap_info_t *bitmap_fd_read(int fd, int brief)
|
||||||
fprintf(stderr, Name ": failed to read superblock of bitmap "
|
fprintf(stderr, Name ": failed to read superblock of bitmap "
|
||||||
"file: %s\n", strerror(errno));
|
"file: %s\n", strerror(errno));
|
||||||
free(info);
|
free(info);
|
||||||
free(unaligned);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
memcpy(&info->sb, buf, sizeof(info->sb));
|
memcpy(&info->sb, buf, sizeof(info->sb));
|
||||||
|
|
5
mdadm.h
5
mdadm.h
|
@ -791,6 +791,11 @@ static inline int dev2minor(int d)
|
||||||
return (-1-d) << MdpMinorShift;
|
return (-1-d) << MdpMinorShift;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int ROUND_UP(int a, int base)
|
||||||
|
{
|
||||||
|
return ((a+base-1)/base)*base;
|
||||||
|
}
|
||||||
|
|
||||||
#define LEVEL_MULTIPATH (-4)
|
#define LEVEL_MULTIPATH (-4)
|
||||||
#define LEVEL_LINEAR (-1)
|
#define LEVEL_LINEAR (-1)
|
||||||
#define LEVEL_FAULTY (-5)
|
#define LEVEL_FAULTY (-5)
|
||||||
|
|
106
super-ddf.c
106
super-ddf.c
|
@ -31,11 +31,6 @@
|
||||||
#include "sha1.h"
|
#include "sha1.h"
|
||||||
#include <values.h>
|
#include <values.h>
|
||||||
|
|
||||||
static inline int ROUND_UP(int a, int base)
|
|
||||||
{
|
|
||||||
return ((a+base-1)/base)*base;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* a non-official T10 name for creation GUIDs */
|
/* a non-official T10 name for creation GUIDs */
|
||||||
static char T10[] = "Linux-MD";
|
static char T10[] = "Linux-MD";
|
||||||
|
|
||||||
|
@ -395,8 +390,9 @@ struct bad_block_log {
|
||||||
* built in Create or Assemble to describe the whole array.
|
* built in Create or Assemble to describe the whole array.
|
||||||
*/
|
*/
|
||||||
struct ddf_super {
|
struct ddf_super {
|
||||||
struct ddf_header anchor, primary, secondary, *active;
|
struct ddf_header anchor, primary, secondary;
|
||||||
struct ddf_controller_data controller;
|
struct ddf_controller_data controller;
|
||||||
|
struct ddf_header *active;
|
||||||
struct phys_disk *phys;
|
struct phys_disk *phys;
|
||||||
struct virtual_disk *virt;
|
struct virtual_disk *virt;
|
||||||
int pdsize, vdsize;
|
int pdsize, vdsize;
|
||||||
|
@ -404,22 +400,32 @@ struct ddf_super {
|
||||||
int currentdev;
|
int currentdev;
|
||||||
int updates_pending;
|
int updates_pending;
|
||||||
struct vcl {
|
struct vcl {
|
||||||
struct vcl *next;
|
union {
|
||||||
__u64 *lba_offset; /* location in 'conf' of
|
char space[512];
|
||||||
* the lba table */
|
struct {
|
||||||
int vcnum; /* index into ->virt */
|
struct vcl *next;
|
||||||
__u64 *block_sizes; /* NULL if all the same */
|
__u64 *lba_offset; /* location in 'conf' of
|
||||||
|
* the lba table */
|
||||||
|
int vcnum; /* index into ->virt */
|
||||||
|
__u64 *block_sizes; /* NULL if all the same */
|
||||||
|
};
|
||||||
|
};
|
||||||
struct vd_config conf;
|
struct vd_config conf;
|
||||||
} *conflist, *currentconf;
|
} *conflist, *currentconf;
|
||||||
struct dl {
|
struct dl {
|
||||||
struct dl *next;
|
union {
|
||||||
|
char space[512];
|
||||||
|
struct {
|
||||||
|
struct dl *next;
|
||||||
|
int major, minor;
|
||||||
|
char *devname;
|
||||||
|
int fd;
|
||||||
|
unsigned long long size; /* sectors */
|
||||||
|
int pdnum; /* index in ->phys */
|
||||||
|
struct spare_assign *spare;
|
||||||
|
};
|
||||||
|
};
|
||||||
struct disk_data disk;
|
struct disk_data disk;
|
||||||
int major, minor;
|
|
||||||
char *devname;
|
|
||||||
int fd;
|
|
||||||
unsigned long long size; /* sectors */
|
|
||||||
int pdnum; /* index in ->phys */
|
|
||||||
struct spare_assign *spare;
|
|
||||||
struct vcl *vlist[0]; /* max_part in size */
|
struct vcl *vlist[0]; /* max_part in size */
|
||||||
} *dlist;
|
} *dlist;
|
||||||
};
|
};
|
||||||
|
@ -497,8 +503,10 @@ static void *load_section(int fd, struct ddf_super *super, void *buf,
|
||||||
/* All pre-allocated sections are a single block */
|
/* All pre-allocated sections are a single block */
|
||||||
if (len != 1)
|
if (len != 1)
|
||||||
return NULL;
|
return NULL;
|
||||||
} else
|
} else {
|
||||||
buf = malloc(len<<9);
|
posix_memalign(&buf, 512, len<<9);
|
||||||
|
}
|
||||||
|
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -633,8 +641,9 @@ static int load_ddf_local(int fd, struct ddf_super *super,
|
||||||
unsigned long long dsize;
|
unsigned long long dsize;
|
||||||
|
|
||||||
/* First the local disk info */
|
/* First the local disk info */
|
||||||
dl = malloc(sizeof(*dl) +
|
posix_memalign((void**)&dl, 512,
|
||||||
(super->max_part) * sizeof(dl->vlist[0]));
|
sizeof(*dl) +
|
||||||
|
(super->max_part) * sizeof(dl->vlist[0]));
|
||||||
|
|
||||||
load_section(fd, super, &dl->disk,
|
load_section(fd, super, &dl->disk,
|
||||||
super->active->data_section_offset,
|
super->active->data_section_offset,
|
||||||
|
@ -683,7 +692,8 @@ static int load_ddf_local(int fd, struct ddf_super *super,
|
||||||
if (vd->magic == DDF_SPARE_ASSIGN_MAGIC) {
|
if (vd->magic == DDF_SPARE_ASSIGN_MAGIC) {
|
||||||
if (dl->spare)
|
if (dl->spare)
|
||||||
continue;
|
continue;
|
||||||
dl->spare = malloc(super->conf_rec_len*512);
|
posix_memalign((void**)&dl->spare, 512,
|
||||||
|
super->conf_rec_len*512);
|
||||||
memcpy(dl->spare, vd, super->conf_rec_len*512);
|
memcpy(dl->spare, vd, super->conf_rec_len*512);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -701,8 +711,9 @@ static int load_ddf_local(int fd, struct ddf_super *super,
|
||||||
__be32_to_cpu(vcl->conf.seqnum))
|
__be32_to_cpu(vcl->conf.seqnum))
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
vcl = malloc(super->conf_rec_len*512 +
|
posix_memalign((void**)&vcl, 512,
|
||||||
offsetof(struct vcl, conf));
|
(super->conf_rec_len*512 +
|
||||||
|
offsetof(struct vcl, conf)));
|
||||||
vcl->next = super->conflist;
|
vcl->next = super->conflist;
|
||||||
vcl->block_sizes = NULL; /* FIXME not for CONCAT */
|
vcl->block_sizes = NULL; /* FIXME not for CONCAT */
|
||||||
super->conflist = vcl;
|
super->conflist = vcl;
|
||||||
|
@ -766,8 +777,7 @@ static int load_super_ddf(struct supertype *st, int fd,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
super = malloc(sizeof(*super));
|
if (posix_memalign((void**)&super, 512, sizeof(*super))!= 0) {
|
||||||
if (!super) {
|
|
||||||
fprintf(stderr, Name ": malloc of %zu failed.\n",
|
fprintf(stderr, Name ": malloc of %zu failed.\n",
|
||||||
sizeof(*super));
|
sizeof(*super));
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1443,7 +1453,7 @@ static int init_super_ddf(struct supertype *st,
|
||||||
return init_super_ddf_bvd(st, info, size, name, homehost,
|
return init_super_ddf_bvd(st, info, size, name, homehost,
|
||||||
uuid);
|
uuid);
|
||||||
|
|
||||||
ddf = malloc(sizeof(*ddf));
|
posix_memalign((void**)&ddf, 512, sizeof(*ddf));
|
||||||
memset(ddf, 0, sizeof(*ddf));
|
memset(ddf, 0, sizeof(*ddf));
|
||||||
ddf->dlist = NULL; /* no physical disks yet */
|
ddf->dlist = NULL; /* no physical disks yet */
|
||||||
ddf->conflist = NULL; /* No virtual disks yet */
|
ddf->conflist = NULL; /* No virtual disks yet */
|
||||||
|
@ -1570,7 +1580,8 @@ static int init_super_ddf(struct supertype *st,
|
||||||
memset(ddf->controller.pad, 0xff, 8);
|
memset(ddf->controller.pad, 0xff, 8);
|
||||||
memset(ddf->controller.vendor_data, 0xff, 448);
|
memset(ddf->controller.vendor_data, 0xff, 448);
|
||||||
|
|
||||||
pd = ddf->phys = malloc(pdsize);
|
posix_memalign((void**)&pd, 512, pdsize);
|
||||||
|
ddf->phys = pd;
|
||||||
ddf->pdsize = pdsize;
|
ddf->pdsize = pdsize;
|
||||||
|
|
||||||
memset(pd, 0xff, pdsize);
|
memset(pd, 0xff, pdsize);
|
||||||
|
@ -1580,7 +1591,8 @@ static int init_super_ddf(struct supertype *st,
|
||||||
pd->max_pdes = __cpu_to_be16(max_phys_disks);
|
pd->max_pdes = __cpu_to_be16(max_phys_disks);
|
||||||
memset(pd->pad, 0xff, 52);
|
memset(pd->pad, 0xff, 52);
|
||||||
|
|
||||||
vd = ddf->virt = malloc(vdsize);
|
posix_memalign((void**)&vd, 512, vdsize);
|
||||||
|
ddf->virt = vd;
|
||||||
ddf->vdsize = vdsize;
|
ddf->vdsize = vdsize;
|
||||||
memset(vd, 0, vdsize);
|
memset(vd, 0, vdsize);
|
||||||
vd->magic = DDF_VIRT_RECORDS_MAGIC;
|
vd->magic = DDF_VIRT_RECORDS_MAGIC;
|
||||||
|
@ -1805,7 +1817,8 @@ static int init_super_ddf_bvd(struct supertype *st,
|
||||||
__cpu_to_be16(__be16_to_cpu(ddf->virt->populated_vdes)+1);
|
__cpu_to_be16(__be16_to_cpu(ddf->virt->populated_vdes)+1);
|
||||||
|
|
||||||
/* Now create a new vd_config */
|
/* Now create a new vd_config */
|
||||||
vcl = malloc(offsetof(struct vcl, conf) + ddf->conf_rec_len * 512);
|
posix_memalign((void**)&vcl, 512,
|
||||||
|
(offsetof(struct vcl, conf) + ddf->conf_rec_len * 512));
|
||||||
vcl->lba_offset = (__u64*) &vcl->conf.phys_refnum[ddf->mppe];
|
vcl->lba_offset = (__u64*) &vcl->conf.phys_refnum[ddf->mppe];
|
||||||
vcl->vcnum = venum;
|
vcl->vcnum = venum;
|
||||||
sprintf(st->subarray, "%d", venum);
|
sprintf(st->subarray, "%d", venum);
|
||||||
|
@ -1974,7 +1987,8 @@ static void add_to_super_ddf(struct supertype *st,
|
||||||
* a phys_disk entry and a more detailed disk_data entry.
|
* a phys_disk entry and a more detailed disk_data entry.
|
||||||
*/
|
*/
|
||||||
fstat(fd, &stb);
|
fstat(fd, &stb);
|
||||||
dd = malloc(sizeof(*dd) + sizeof(dd->vlist[0]) * ddf->max_part);
|
posix_memalign((void**)&dd, 512,
|
||||||
|
sizeof(*dd) + sizeof(dd->vlist[0]) * ddf->max_part);
|
||||||
dd->major = major(stb.st_rdev);
|
dd->major = major(stb.st_rdev);
|
||||||
dd->minor = minor(stb.st_rdev);
|
dd->minor = minor(stb.st_rdev);
|
||||||
dd->devname = devname;
|
dd->devname = devname;
|
||||||
|
@ -2037,7 +2051,7 @@ static void add_to_super_ddf(struct supertype *st,
|
||||||
|
|
||||||
#ifndef MDASSEMBLE
|
#ifndef MDASSEMBLE
|
||||||
|
|
||||||
static unsigned char null_conf[4096];
|
static unsigned char null_conf[4096+512];
|
||||||
|
|
||||||
static int __write_init_super_ddf(struct supertype *st, int do_close)
|
static int __write_init_super_ddf(struct supertype *st, int do_close)
|
||||||
{
|
{
|
||||||
|
@ -2109,14 +2123,15 @@ static int __write_init_super_ddf(struct supertype *st, int do_close)
|
||||||
c->conf.crc = calc_crc(&c->conf, conf_size);
|
c->conf.crc = calc_crc(&c->conf, conf_size);
|
||||||
write(fd, &c->conf, conf_size);
|
write(fd, &c->conf, conf_size);
|
||||||
} else {
|
} else {
|
||||||
|
char *null_aligned = (char*)((((unsigned long)null_conf)+511)&~511UL);
|
||||||
if (null_conf[0] != 0xff)
|
if (null_conf[0] != 0xff)
|
||||||
memset(null_conf, 0xff, sizeof(null_conf));
|
memset(null_conf, 0xff, sizeof(null_conf));
|
||||||
int togo = conf_size;
|
int togo = conf_size;
|
||||||
while (togo > sizeof(null_conf)) {
|
while (togo > sizeof(null_conf)-512) {
|
||||||
write(fd, null_conf, sizeof(null_conf));
|
write(fd, null_aligned, sizeof(null_conf)-512);
|
||||||
togo -= sizeof(null_conf);
|
togo -= sizeof(null_conf)-512;
|
||||||
}
|
}
|
||||||
write(fd, null_conf, togo);
|
write(fd, null_aligned, togo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
d->disk.crc = calc_crc(&d->disk, 512);
|
d->disk.crc = calc_crc(&d->disk, 512);
|
||||||
|
@ -2425,8 +2440,7 @@ static int load_super_ddf_all(struct supertype *st, int fd,
|
||||||
strcmp(sra->text_version, "ddf") != 0)
|
strcmp(sra->text_version, "ddf") != 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
super = malloc(sizeof(*super));
|
if (posix_memalign((void**)&super, 512, sizeof(*super)) != 0)
|
||||||
if (!super)
|
|
||||||
return 1;
|
return 1;
|
||||||
memset(super, 0, sizeof(*super));
|
memset(super, 0, sizeof(*super));
|
||||||
|
|
||||||
|
@ -2584,14 +2598,17 @@ static struct mdinfo *container_content_ddf(struct supertype *st)
|
||||||
static int store_zero_ddf(struct supertype *st, int fd)
|
static int store_zero_ddf(struct supertype *st, int fd)
|
||||||
{
|
{
|
||||||
unsigned long long dsize;
|
unsigned long long dsize;
|
||||||
char buf[512];
|
void *buf;
|
||||||
memset(buf, 0, 512);
|
|
||||||
|
|
||||||
if (!get_dev_size(fd, NULL, &dsize))
|
if (!get_dev_size(fd, NULL, &dsize))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
posix_memalign(&buf, 512, 512);
|
||||||
|
memset(buf, 0, 512);
|
||||||
|
|
||||||
lseek64(fd, dsize-512, 0);
|
lseek64(fd, dsize-512, 0);
|
||||||
write(fd, buf, 512);
|
write(fd, buf, 512);
|
||||||
|
free(buf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2948,8 +2965,9 @@ static void ddf_prepare_update(struct supertype *st,
|
||||||
struct ddf_super *ddf = st->sb;
|
struct ddf_super *ddf = st->sb;
|
||||||
__u32 *magic = (__u32*)update->buf;
|
__u32 *magic = (__u32*)update->buf;
|
||||||
if (*magic == DDF_VD_CONF_MAGIC)
|
if (*magic == DDF_VD_CONF_MAGIC)
|
||||||
update->space = malloc(offsetof(struct vcl, conf)
|
posix_memalign(&update->space, 512,
|
||||||
+ ddf->conf_rec_len * 512);
|
offsetof(struct vcl, conf)
|
||||||
|
+ ddf->conf_rec_len * 512);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -3131,7 +3149,7 @@ static struct mdinfo *ddf_activate_spare(struct active_array *a,
|
||||||
*/
|
*/
|
||||||
mu = malloc(sizeof(*mu));
|
mu = malloc(sizeof(*mu));
|
||||||
mu->buf = malloc(ddf->conf_rec_len * 512);
|
mu->buf = malloc(ddf->conf_rec_len * 512);
|
||||||
mu->space = malloc(sizeof(struct vcl));
|
posix_memalign(&mu->space, 512, sizeof(struct vcl));
|
||||||
mu->len = ddf->conf_rec_len;
|
mu->len = ddf->conf_rec_len;
|
||||||
mu->next = *updates;
|
mu->next = *updates;
|
||||||
vc = find_vdcr(ddf, a->info.container_member);
|
vc = find_vdcr(ddf, a->info.container_member);
|
||||||
|
|
|
@ -762,7 +762,7 @@ static int load_imsm_mpb(int fd, struct intel_super *super, char *devname)
|
||||||
size_t len, mpb_size;
|
size_t len, mpb_size;
|
||||||
unsigned long long sectors;
|
unsigned long long sectors;
|
||||||
struct stat;
|
struct stat;
|
||||||
struct imsm_super anchor;
|
struct imsm_super *anchor;
|
||||||
__u32 check_sum;
|
__u32 check_sum;
|
||||||
|
|
||||||
memset(super, 0, sizeof(*super));
|
memset(super, 0, sizeof(*super));
|
||||||
|
@ -776,44 +776,40 @@ static int load_imsm_mpb(int fd, struct intel_super *super, char *devname)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = sizeof(anchor);
|
len = 512;
|
||||||
if (read(fd, &anchor, len) != len) {
|
posix_memalign((void**)&anchor, 512, len);
|
||||||
|
if (read(fd, anchor, len) != len) {
|
||||||
if (devname)
|
if (devname)
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
Name ": Cannot read anchor block on %s: %s\n",
|
Name ": Cannot read anchor block on %s: %s\n",
|
||||||
devname, strerror(errno));
|
devname, strerror(errno));
|
||||||
|
free(anchor);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strncmp((char *) anchor.sig, MPB_SIGNATURE, MPB_SIG_LEN) != 0) {
|
if (strncmp((char *) anchor->sig, MPB_SIGNATURE, MPB_SIG_LEN) != 0) {
|
||||||
if (devname)
|
if (devname)
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
Name ": no IMSM anchor on %s\n", devname);
|
Name ": no IMSM anchor on %s\n", devname);
|
||||||
|
free(anchor);
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
mpb_size = __le32_to_cpu(anchor.mpb_size);
|
mpb_size = __le32_to_cpu(anchor->mpb_size);
|
||||||
super->mpb = malloc(mpb_size < 512 ? 512 : mpb_size);
|
mpb_size = ROUND_UP(mpb_size, 512);
|
||||||
|
posix_memalign((void**)&super->mpb, 512, mpb_size);
|
||||||
if (!super->mpb) {
|
if (!super->mpb) {
|
||||||
if (devname)
|
if (devname)
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
Name ": unable to allocate %zu byte mpb buffer\n",
|
Name ": unable to allocate %zu byte mpb buffer\n",
|
||||||
mpb_size);
|
mpb_size);
|
||||||
|
free(anchor);
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
memcpy(super->buf, &anchor, sizeof(anchor));
|
memcpy(super->buf, anchor, len);
|
||||||
|
|
||||||
/* read the rest of the first block */
|
sectors = mpb_sectors(anchor) - 1;
|
||||||
len = 512 - sizeof(anchor);
|
free(anchor);
|
||||||
if (read(fd, super->buf + sizeof(anchor), len) != len) {
|
|
||||||
if (devname)
|
|
||||||
fprintf(stderr,
|
|
||||||
Name ": Cannot read anchor remainder on %s: %s\n",
|
|
||||||
devname, strerror(errno));
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
sectors = mpb_sectors(&anchor) - 1;
|
|
||||||
if (!sectors)
|
if (!sectors)
|
||||||
return load_imsm_disk(fd, super, devname, 0);
|
return load_imsm_disk(fd, super, devname, 0);
|
||||||
|
|
||||||
|
@ -1067,7 +1063,7 @@ static int init_super_imsm(struct supertype *st, mdu_array_info_t *info,
|
||||||
if (!super)
|
if (!super)
|
||||||
return 0;
|
return 0;
|
||||||
mpb_size = disks_to_mpb_size(info->nr_disks);
|
mpb_size = disks_to_mpb_size(info->nr_disks);
|
||||||
mpb = malloc(mpb_size);
|
posix_memalign((void**)&mpb, 512, mpb_size);
|
||||||
if (!mpb) {
|
if (!mpb) {
|
||||||
free(super);
|
free(super);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1281,7 +1277,7 @@ static int write_init_super_imsm(struct supertype *st)
|
||||||
static int store_zero_imsm(struct supertype *st, int fd)
|
static int store_zero_imsm(struct supertype *st, int fd)
|
||||||
{
|
{
|
||||||
unsigned long long dsize;
|
unsigned long long dsize;
|
||||||
char buf[512];
|
void *buf;
|
||||||
|
|
||||||
get_dev_size(fd, NULL, &dsize);
|
get_dev_size(fd, NULL, &dsize);
|
||||||
|
|
||||||
|
@ -1289,6 +1285,7 @@ static int store_zero_imsm(struct supertype *st, int fd)
|
||||||
if (lseek64(fd, dsize - (512 * 2), SEEK_SET) < 0)
|
if (lseek64(fd, dsize - (512 * 2), SEEK_SET) < 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
posix_memalign(&buf, 512, 512);
|
||||||
memset(buf, 0, sizeof(buf));
|
memset(buf, 0, sizeof(buf));
|
||||||
if (write(fd, buf, sizeof(buf)) != sizeof(buf))
|
if (write(fd, buf, sizeof(buf)) != sizeof(buf))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
33
super0.c
33
super0.c
|
@ -554,8 +554,10 @@ static int init_super0(struct supertype *st, mdu_array_info_t *info,
|
||||||
unsigned long long size, char *ignored_name, char *homehost,
|
unsigned long long size, char *ignored_name, char *homehost,
|
||||||
int *uuid)
|
int *uuid)
|
||||||
{
|
{
|
||||||
mdp_super_t *sb = malloc(MD_SB_BYTES + sizeof(bitmap_super_t));
|
mdp_super_t *sb;
|
||||||
int spares;
|
int spares;
|
||||||
|
|
||||||
|
posix_memalign((void**)&sb, 512, MD_SB_BYTES + sizeof(bitmap_super_t));
|
||||||
memset(sb, 0, MD_SB_BYTES + sizeof(bitmap_super_t));
|
memset(sb, 0, MD_SB_BYTES + sizeof(bitmap_super_t));
|
||||||
|
|
||||||
st->sb = sb;
|
st->sb = sb;
|
||||||
|
@ -684,7 +686,8 @@ static int store_super0(struct supertype *st, int fd)
|
||||||
if (super->state & (1<<MD_SB_BITMAP_PRESENT)) {
|
if (super->state & (1<<MD_SB_BITMAP_PRESENT)) {
|
||||||
struct bitmap_super_s * bm = (struct bitmap_super_s*)(super+1);
|
struct bitmap_super_s * bm = (struct bitmap_super_s*)(super+1);
|
||||||
if (__le32_to_cpu(bm->magic) == BITMAP_MAGIC)
|
if (__le32_to_cpu(bm->magic) == BITMAP_MAGIC)
|
||||||
if (write(fd, bm, sizeof(*bm)) != sizeof(*bm))
|
if (write(fd, bm, ROUND_UP(sizeof(*bm),512)) !=
|
||||||
|
ROUND_UP(sizeof(*bm),512))
|
||||||
return 5;
|
return 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -744,7 +747,8 @@ static int compare_super0(struct supertype *st, struct supertype *tst)
|
||||||
if (second->md_magic != MD_SB_MAGIC)
|
if (second->md_magic != MD_SB_MAGIC)
|
||||||
return 1;
|
return 1;
|
||||||
if (!first) {
|
if (!first) {
|
||||||
first = malloc(MD_SB_BYTES + sizeof(struct bitmap_super_s));
|
posix_memalign((void**)&first, 512,
|
||||||
|
MD_SB_BYTES + sizeof(struct bitmap_super_s));
|
||||||
memcpy(first, second, MD_SB_BYTES + sizeof(struct bitmap_super_s));
|
memcpy(first, second, MD_SB_BYTES + sizeof(struct bitmap_super_s));
|
||||||
st->sb = first;
|
st->sb = first;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -813,7 +817,7 @@ static int load_super0(struct supertype *st, int fd, char *devname)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
super = malloc(MD_SB_BYTES + sizeof(bitmap_super_t));
|
posix_memalign((void**)&super, 512, MD_SB_BYTES + sizeof(bitmap_super_t)+512);
|
||||||
|
|
||||||
if (read(fd, super, sizeof(*super)) != MD_SB_BYTES) {
|
if (read(fd, super, sizeof(*super)) != MD_SB_BYTES) {
|
||||||
if (devname)
|
if (devname)
|
||||||
|
@ -857,8 +861,8 @@ static int load_super0(struct supertype *st, int fd, char *devname)
|
||||||
* valid. If it doesn't clear the bit. An --assemble --force
|
* valid. If it doesn't clear the bit. An --assemble --force
|
||||||
* should get that written out.
|
* should get that written out.
|
||||||
*/
|
*/
|
||||||
if (read(fd, super+1, sizeof(struct bitmap_super_s))
|
if (read(fd, super+1, ROUND_UP(sizeof(struct bitmap_super_s),512))
|
||||||
!= sizeof(struct bitmap_super_s))
|
!= ROUND_UP(sizeof(struct bitmap_super_s),512))
|
||||||
goto no_bitmap;
|
goto no_bitmap;
|
||||||
|
|
||||||
uuid_from_super0(st, uuid);
|
uuid_from_super0(st, uuid);
|
||||||
|
@ -986,7 +990,8 @@ static int write_bitmap0(struct supertype *st, int fd)
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
|
|
||||||
int towrite, n;
|
int towrite, n;
|
||||||
char buf[4096];
|
char abuf[4096+512];
|
||||||
|
char *buf = (char*)(((long)(abuf+512))&~511UL);
|
||||||
|
|
||||||
if (!get_dev_size(fd, NULL, &dsize))
|
if (!get_dev_size(fd, NULL, &dsize))
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1002,21 +1007,19 @@ static int write_bitmap0(struct supertype *st, int fd)
|
||||||
if (lseek64(fd, offset + 4096, 0)< 0LL)
|
if (lseek64(fd, offset + 4096, 0)< 0LL)
|
||||||
return 3;
|
return 3;
|
||||||
|
|
||||||
|
memset(buf, 0xff, 4096);
|
||||||
if (write(fd, ((char*)sb)+MD_SB_BYTES, sizeof(bitmap_super_t)) !=
|
memcpy(buf, ((char*)sb)+MD_SB_BYTES, sizeof(bitmap_super_t));
|
||||||
sizeof(bitmap_super_t))
|
towrite = 64*1024;
|
||||||
return -2;
|
|
||||||
towrite = 64*1024 - MD_SB_BYTES - sizeof(bitmap_super_t);
|
|
||||||
memset(buf, 0xff, sizeof(buf));
|
|
||||||
while (towrite > 0) {
|
while (towrite > 0) {
|
||||||
n = towrite;
|
n = towrite;
|
||||||
if (n > sizeof(buf))
|
if (n > 4096)
|
||||||
n = sizeof(buf);
|
n = 4096;
|
||||||
n = write(fd, buf, n);
|
n = write(fd, buf, n);
|
||||||
if (n > 0)
|
if (n > 0)
|
||||||
towrite -= n;
|
towrite -= n;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
|
memset(buf, 0xff, 4096);
|
||||||
}
|
}
|
||||||
fsync(fd);
|
fsync(fd);
|
||||||
if (towrite)
|
if (towrite)
|
||||||
|
|
43
super1.c
43
super1.c
|
@ -671,7 +671,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
|
||||||
__le64_to_cpu(sb->data_offset)) {
|
__le64_to_cpu(sb->data_offset)) {
|
||||||
/* set data_size to device size less data_offset */
|
/* set data_size to device size less data_offset */
|
||||||
struct misc_dev_info *misc = (struct misc_dev_info*)
|
struct misc_dev_info *misc = (struct misc_dev_info*)
|
||||||
(st->sb + 1024 + sizeof(struct bitmap_super_s));
|
(st->sb + 1024 + 512);
|
||||||
printf("Size was %llu\n", (unsigned long long)
|
printf("Size was %llu\n", (unsigned long long)
|
||||||
__le64_to_cpu(sb->data_size));
|
__le64_to_cpu(sb->data_size));
|
||||||
sb->data_size = __cpu_to_le64(
|
sb->data_size = __cpu_to_le64(
|
||||||
|
@ -689,11 +689,13 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
|
||||||
static int init_super1(struct supertype *st, mdu_array_info_t *info,
|
static int init_super1(struct supertype *st, mdu_array_info_t *info,
|
||||||
unsigned long long size, char *name, char *homehost, int *uuid)
|
unsigned long long size, char *name, char *homehost, int *uuid)
|
||||||
{
|
{
|
||||||
struct mdp_superblock_1 *sb = malloc(1024 + sizeof(bitmap_super_t) +
|
struct mdp_superblock_1 *sb;
|
||||||
sizeof(struct misc_dev_info));
|
|
||||||
int spares;
|
int spares;
|
||||||
int rfd;
|
int rfd;
|
||||||
char defname[10];
|
char defname[10];
|
||||||
|
|
||||||
|
posix_memalign((void**)&sb, 512, (1024 + 512 +
|
||||||
|
sizeof(struct misc_dev_info)));
|
||||||
memset(sb, 0, 1024);
|
memset(sb, 0, 1024);
|
||||||
|
|
||||||
st->sb = sb;
|
st->sb = sb;
|
||||||
|
@ -857,6 +859,7 @@ static int store_super1(struct supertype *st, int fd)
|
||||||
return 3;
|
return 3;
|
||||||
|
|
||||||
sbsize = sizeof(*sb) + 2 * __le32_to_cpu(sb->max_dev);
|
sbsize = sizeof(*sb) + 2 * __le32_to_cpu(sb->max_dev);
|
||||||
|
sbsize = (sbsize+511)&(~511UL);
|
||||||
|
|
||||||
if (write(fd, sb, sbsize) != sbsize)
|
if (write(fd, sb, sbsize) != sbsize)
|
||||||
return 4;
|
return 4;
|
||||||
|
@ -866,7 +869,8 @@ static int store_super1(struct supertype *st, int fd)
|
||||||
(((char*)sb)+1024);
|
(((char*)sb)+1024);
|
||||||
if (__le32_to_cpu(bm->magic) == BITMAP_MAGIC) {
|
if (__le32_to_cpu(bm->magic) == BITMAP_MAGIC) {
|
||||||
locate_bitmap1(st, fd);
|
locate_bitmap1(st, fd);
|
||||||
if (write(fd, bm, sizeof(*bm)) != sizeof(*bm))
|
if (write(fd, bm, ROUND_UP(sizeof(*bm),512)) !=
|
||||||
|
ROUND_UP(sizeof(*bm),512))
|
||||||
return 5;
|
return 5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1035,9 +1039,10 @@ static int compare_super1(struct supertype *st, struct supertype *tst)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (!first) {
|
if (!first) {
|
||||||
first = malloc(1024+sizeof(bitmap_super_t) +
|
posix_memalign((void**)&first, 512,
|
||||||
|
1024 + 512 +
|
||||||
sizeof(struct misc_dev_info));
|
sizeof(struct misc_dev_info));
|
||||||
memcpy(first, second, 1024+sizeof(bitmap_super_t) +
|
memcpy(first, second, 1024 + 512 +
|
||||||
sizeof(struct misc_dev_info));
|
sizeof(struct misc_dev_info));
|
||||||
st->sb = first;
|
st->sb = first;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1150,7 +1155,8 @@ static int load_super1(struct supertype *st, int fd, char *devname)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
super = malloc(1024 + sizeof(bitmap_super_t) +
|
posix_memalign((void**)&super, 512,
|
||||||
|
1024 + 512 +
|
||||||
sizeof(struct misc_dev_info));
|
sizeof(struct misc_dev_info));
|
||||||
|
|
||||||
if (read(fd, super, 1024) != 1024) {
|
if (read(fd, super, 1024) != 1024) {
|
||||||
|
@ -1187,7 +1193,7 @@ static int load_super1(struct supertype *st, int fd, char *devname)
|
||||||
|
|
||||||
bsb = (struct bitmap_super_s *)(((char*)super)+1024);
|
bsb = (struct bitmap_super_s *)(((char*)super)+1024);
|
||||||
|
|
||||||
misc = (struct misc_dev_info*) (bsb+1);
|
misc = (struct misc_dev_info*) (((char*)super)+1024+512);
|
||||||
misc->device_size = dsize;
|
misc->device_size = dsize;
|
||||||
|
|
||||||
/* Now check on the bitmap superblock */
|
/* Now check on the bitmap superblock */
|
||||||
|
@ -1198,8 +1204,8 @@ static int load_super1(struct supertype *st, int fd, char *devname)
|
||||||
* should get that written out.
|
* should get that written out.
|
||||||
*/
|
*/
|
||||||
locate_bitmap1(st, fd);
|
locate_bitmap1(st, fd);
|
||||||
if (read(fd, ((char*)super)+1024, sizeof(struct bitmap_super_s))
|
if (read(fd, ((char*)super)+1024, 512)
|
||||||
!= sizeof(struct bitmap_super_s))
|
!= 512)
|
||||||
goto no_bitmap;
|
goto no_bitmap;
|
||||||
|
|
||||||
uuid_from_super1(st, uuid);
|
uuid_from_super1(st, uuid);
|
||||||
|
@ -1419,25 +1425,28 @@ static int write_bitmap1(struct supertype *st, int fd)
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
|
|
||||||
int towrite, n;
|
int towrite, n;
|
||||||
char buf[4096];
|
char abuf[4096+512];
|
||||||
|
char *buf = (char*)(((long)(abuf+512))&~511UL);
|
||||||
|
|
||||||
locate_bitmap1(st, fd);
|
locate_bitmap1(st, fd);
|
||||||
|
|
||||||
if (write(fd, ((char*)sb)+1024, sizeof(bitmap_super_t)) !=
|
memset(buf, 0xff, 4096);
|
||||||
sizeof(bitmap_super_t))
|
memcpy(buf, ((char*)sb)+1024, sizeof(bitmap_super_t));
|
||||||
return -2;
|
|
||||||
towrite = __le64_to_cpu(bms->sync_size) / (__le32_to_cpu(bms->chunksize)>>9);
|
towrite = __le64_to_cpu(bms->sync_size) / (__le32_to_cpu(bms->chunksize)>>9);
|
||||||
towrite = (towrite+7) >> 3; /* bits to bytes */
|
towrite = (towrite+7) >> 3; /* bits to bytes */
|
||||||
memset(buf, 0xff, sizeof(buf));
|
towrite += sizeof(bitmap_super_t);
|
||||||
|
towrite = ROUND_UP(towrite, 512);
|
||||||
while (towrite > 0) {
|
while (towrite > 0) {
|
||||||
n = towrite;
|
n = towrite;
|
||||||
if (n > sizeof(buf))
|
if (n > 4096)
|
||||||
n = sizeof(buf);
|
n = 4096;
|
||||||
n = write(fd, buf, n);
|
n = write(fd, buf, n);
|
||||||
if (n > 0)
|
if (n > 0)
|
||||||
towrite -= n;
|
towrite -= n;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
|
memset(buf, 0xff, 4096);
|
||||||
}
|
}
|
||||||
fsync(fd);
|
fsync(fd);
|
||||||
if (towrite)
|
if (towrite)
|
||||||
|
|
4
util.c
4
util.c
|
@ -761,11 +761,11 @@ int dev_open(char *dev, int flags)
|
||||||
snprintf(devname, sizeof(devname), "/dev/.tmp.md.%d:%d:%d",
|
snprintf(devname, sizeof(devname), "/dev/.tmp.md.%d:%d:%d",
|
||||||
(int)getpid(), major, minor);
|
(int)getpid(), major, minor);
|
||||||
if (mknod(devname, S_IFBLK|0600, makedev(major, minor))==0) {
|
if (mknod(devname, S_IFBLK|0600, makedev(major, minor))==0) {
|
||||||
fd = open(devname, flags);
|
fd = open(devname, flags|O_DIRECT);
|
||||||
unlink(devname);
|
unlink(devname);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
fd = open(dev, flags);
|
fd = open(dev, flags|O_DIRECT);
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue