/* * This is a special case code to check for an MDRAID device. We do * this special since it requires checking for a superblock at the end * of the device. */ static int check_mdraid(int fd, unsigned char *ret_uuid) { struct mdp_superblock_s *md; blkid_loff_t offset; char buf[4096]; if (fd < 0) return -BLKID_ERR_PARAM; offset = (blkid_get_dev_size(fd) & ~((blkid_loff_t)65535)) - 65536; if (blkid_llseek(fd, offset, 0) < 0 || read(fd, buf, 4096) != 4096) return -BLKID_ERR_IO; /* Check for magic number */ if (memcmp("\251+N\374", buf, 4) && memcmp("\374N+\251", buf, 4)) return -BLKID_ERR_PARAM; if (!ret_uuid) return 0; *ret_uuid = 0; /* The MD UUID is not contiguous in the superblock, make it so */ md = (struct mdp_superblock_s *)buf; if (md->set_uuid0 || md->set_uuid1 || md->set_uuid2 || md->set_uuid3) { memcpy(ret_uuid, &md->set_uuid0, 4); memcpy(ret_uuid + 4, &md->set_uuid1, 12); } return 0; }
static int valid_offset(int fd, blkid_loff_t offset) { char ch; if (blkid_llseek(fd, offset, 0) < 0) return 0; if (read(fd, &ch, 1) < 1) return 0; return 1; }
static unsigned char *get_buffer(struct blkid_probe *pr, blkid_loff_t off, size_t len) { ssize_t ret_read; unsigned char *newbuf; if (off + len <= SB_BUFFER_SIZE) { if (!pr->sbbuf) { pr->sbbuf = malloc(SB_BUFFER_SIZE); if (!pr->sbbuf) return NULL; if (lseek(pr->fd, 0, SEEK_SET) < 0) return NULL; ret_read = read(pr->fd, pr->sbbuf, SB_BUFFER_SIZE); if (ret_read < 0) ret_read = 0; pr->sb_valid = ret_read; } if (off+len > pr->sb_valid) return NULL; return pr->sbbuf + off; } else { if (len > pr->buf_max) { newbuf = realloc(pr->buf, len); if (newbuf == NULL) return NULL; pr->buf = newbuf; pr->buf_max = len; } if (blkid_llseek(pr->fd, off, SEEK_SET) < 0) return NULL; ret_read = read(pr->fd, pr->buf, len); if (ret_read != (ssize_t) len) return NULL; return pr->buf; } }