|
Packit |
6ef888 |
#include "clusterautoconfig.h"
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
#include <stdio.h>
|
|
Packit |
6ef888 |
#include <stdlib.h>
|
|
Packit |
6ef888 |
#include <string.h>
|
|
Packit |
6ef888 |
#include <stdint.h>
|
|
Packit |
6ef888 |
#include <inttypes.h>
|
|
Packit |
6ef888 |
#include <sys/types.h>
|
|
Packit |
6ef888 |
#include <sys/stat.h>
|
|
Packit |
6ef888 |
#include <sys/time.h>
|
|
Packit |
6ef888 |
#include <fcntl.h>
|
|
Packit |
6ef888 |
#include <unistd.h>
|
|
Packit |
6ef888 |
#include <errno.h>
|
|
Packit |
6ef888 |
#include <linux/types.h>
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
#include "libgfs2.h"
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
#ifndef IOV_MAX
|
|
Packit |
6ef888 |
#ifdef UIO_MAXIOV
|
|
Packit |
6ef888 |
#define IOV_MAX UIO_MAXIOV
|
|
Packit |
6ef888 |
#else
|
|
Packit |
6ef888 |
#define IOV_MAX (1024)
|
|
Packit |
6ef888 |
#endif
|
|
Packit |
6ef888 |
#endif
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
struct gfs2_buffer_head *bget(struct gfs2_sbd *sdp, uint64_t num)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
struct gfs2_buffer_head *bh;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
bh = calloc(1, sizeof(struct gfs2_buffer_head) + sdp->bsize);
|
|
Packit |
6ef888 |
if (bh == NULL)
|
|
Packit |
6ef888 |
return NULL;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
bh->b_blocknr = num;
|
|
Packit |
6ef888 |
bh->sdp = sdp;
|
|
Packit |
6ef888 |
bh->iov.iov_base = (char *)bh + sizeof(struct gfs2_buffer_head);
|
|
Packit |
6ef888 |
bh->iov.iov_len = sdp->bsize;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
return bh;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
int __breadm(struct gfs2_sbd *sdp, struct gfs2_buffer_head **bhs, size_t n,
|
|
Packit |
6ef888 |
uint64_t block, int line, const char *caller)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
size_t v = (n < IOV_MAX) ? n : IOV_MAX;
|
|
Packit |
6ef888 |
struct iovec *iov = alloca(v * sizeof(struct iovec));
|
|
Packit |
6ef888 |
struct iovec *iovbase = iov;
|
|
Packit |
6ef888 |
size_t i = 0;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
while (i < n) {
|
|
Packit |
6ef888 |
int j;
|
|
Packit |
6ef888 |
ssize_t ret;
|
|
Packit |
6ef888 |
ssize_t size = 0;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
for (j = 0; (i + j < n) && (j < IOV_MAX); j++) {
|
|
Packit |
6ef888 |
bhs[i + j] = bget(sdp, block + i + j);
|
|
Packit |
6ef888 |
if (bhs[i + j] == NULL)
|
|
Packit |
6ef888 |
return -1;
|
|
Packit |
6ef888 |
iov[j] = bhs[i + j]->iov;
|
|
Packit |
6ef888 |
size += bhs[i + j]->iov.iov_len;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
ret = preadv(sdp->device_fd, iovbase, j, (block + i) * sdp->bsize);
|
|
Packit |
6ef888 |
if (ret != size) {
|
|
Packit |
6ef888 |
fprintf(stderr, "bad read: %s from %s:%d: block %llu (0x%llx) "
|
|
Packit |
6ef888 |
"count: %d size: %zd ret: %zd\n", strerror(errno),
|
|
Packit |
6ef888 |
caller, line, (unsigned long long)block,
|
|
Packit |
6ef888 |
(unsigned long long)block, j, size, ret);
|
|
Packit |
6ef888 |
exit(-1);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
i += j;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
return 0;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
struct gfs2_buffer_head *__bread(struct gfs2_sbd *sdp, uint64_t num, int line,
|
|
Packit |
6ef888 |
const char *caller)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
struct gfs2_buffer_head *bh;
|
|
Packit |
6ef888 |
int ret;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
ret = __breadm(sdp, &bh, 1, num, line, caller);
|
|
Packit |
6ef888 |
if (ret >= 0)
|
|
Packit |
6ef888 |
return bh;
|
|
Packit |
6ef888 |
return NULL;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
int bwrite(struct gfs2_buffer_head *bh)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
struct gfs2_sbd *sdp = bh->sdp;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
if (pwritev(sdp->device_fd, &bh->iov, 1, bh->b_blocknr * sdp->bsize) != bh->iov.iov_len)
|
|
Packit |
6ef888 |
return -1;
|
|
Packit |
6ef888 |
bh->b_modified = 0;
|
|
Packit |
6ef888 |
return 0;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
int brelse(struct gfs2_buffer_head *bh)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
int error = 0;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
if (bh->b_blocknr == -1)
|
|
Packit |
6ef888 |
printf("Double free!\n");
|
|
Packit |
6ef888 |
if (bh->b_modified)
|
|
Packit |
6ef888 |
error = bwrite(bh);
|
|
Packit |
6ef888 |
bh->b_blocknr = -1;
|
|
Packit |
6ef888 |
if (bh->b_altlist.next && !osi_list_empty(&bh->b_altlist))
|
|
Packit |
6ef888 |
osi_list_del(&bh->b_altlist);
|
|
Packit |
6ef888 |
free(bh);
|
|
Packit |
6ef888 |
return error;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
uint32_t lgfs2_get_block_type(const struct gfs2_buffer_head *lbh)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
const struct gfs2_meta_header *mh = lbh->iov.iov_base;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
if (be32_to_cpu(mh->mh_magic) == GFS2_MAGIC)
|
|
Packit |
6ef888 |
return be32_to_cpu(mh->mh_type);
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
return 0;
|
|
Packit |
6ef888 |
}
|