Line data Source code
1 : #include "clusterautoconfig.h" 2 : 3 : #include <stdio.h> 4 : #include <stdlib.h> 5 : #include <string.h> 6 : #include <stdint.h> 7 : #include <inttypes.h> 8 : #include <sys/types.h> 9 : #include <sys/stat.h> 10 : #include <sys/time.h> 11 : #include <fcntl.h> 12 : #include <unistd.h> 13 : #include <errno.h> 14 : 15 : #include "libgfs2.h" 16 : 17 : #ifndef IOV_MAX 18 : #ifdef UIO_MAXIOV 19 : #define IOV_MAX UIO_MAXIOV 20 : #else 21 : #define IOV_MAX (1024) 22 : #endif 23 : #endif 24 : 25 14334804 : struct lgfs2_buffer_head *lgfs2_bget(struct lgfs2_sbd *sdp, uint64_t num) 26 : { 27 : struct lgfs2_buffer_head *bh; 28 : 29 14334804 : bh = calloc(1, sizeof(struct lgfs2_buffer_head) + sdp->sd_bsize); 30 14334804 : if (bh == NULL) 31 0 : return NULL; 32 : 33 14334804 : bh->b_blocknr = num; 34 14334804 : bh->sdp = sdp; 35 14334804 : bh->iov.iov_base = (char *)bh + sizeof(struct lgfs2_buffer_head); 36 14334804 : bh->iov.iov_len = sdp->sd_bsize; 37 : 38 14334804 : return bh; 39 : } 40 : 41 14333298 : struct lgfs2_buffer_head *__lgfs2_bread(struct lgfs2_sbd *sdp, uint64_t num, int line, 42 : const char *caller) 43 : { 44 : struct lgfs2_buffer_head *bh; 45 : ssize_t ret; 46 : 47 14333298 : bh = lgfs2_bget(sdp, num); 48 14333298 : if (bh == NULL) 49 0 : return NULL; 50 : 51 14333298 : ret = pread(sdp->device_fd, bh->b_data, sdp->sd_bsize, num * sdp->sd_bsize); 52 14333298 : if (ret != sdp->sd_bsize) { 53 0 : fprintf(stderr, "%s:%d: Error reading block %"PRIu64": %s\n", 54 0 : caller, line, num, strerror(errno)); 55 0 : free(bh); 56 0 : bh = NULL; 57 : } 58 14333298 : return bh; 59 : } 60 : 61 200973 : int lgfs2_bwrite(struct lgfs2_buffer_head *bh) 62 : { 63 200973 : struct lgfs2_sbd *sdp = bh->sdp; 64 : 65 200973 : if (pwritev(sdp->device_fd, &bh->iov, 1, bh->b_blocknr * sdp->sd_bsize) != bh->iov.iov_len) 66 0 : return -1; 67 200973 : bh->b_modified = 0; 68 200973 : return 0; 69 : } 70 : 71 14321285 : int lgfs2_brelse(struct lgfs2_buffer_head *bh) 72 : { 73 14321285 : int error = 0; 74 : 75 14321285 : if (bh->b_blocknr == -1) 76 0 : printf("Double free!\n"); 77 14321285 : if (bh->b_modified) 78 192743 : error = lgfs2_bwrite(bh); 79 14321285 : bh->b_blocknr = -1; 80 14321285 : if (bh->b_altlist.next && !osi_list_empty(&bh->b_altlist)) 81 22018 : osi_list_del(&bh->b_altlist); 82 14321285 : free(bh); 83 14321285 : return error; 84 : } 85 : 86 : /** 87 : * Free a buffer head, discarding modifications. 88 : * @bhp: Pointer to the buffer 89 : */ 90 12 : void lgfs2_bfree(struct lgfs2_buffer_head **bhp) 91 : { 92 12 : free(*bhp); 93 12 : *bhp = NULL; 94 12 : } 95 : 96 23 : uint32_t lgfs2_get_block_type(const char *buf) 97 : { 98 23 : const struct gfs2_meta_header *mh = (void *)buf; 99 : 100 23 : if (be32_to_cpu(mh->mh_magic) == GFS2_MAGIC) 101 23 : return be32_to_cpu(mh->mh_type); 102 : 103 0 : return 0; 104 : }