Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F1842025
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/gfs2/libgfs2/buf.c b/gfs2/libgfs2/buf.c
index b706375c0..e3c437b7c 100644
--- a/gfs2/libgfs2/buf.c
+++ b/gfs2/libgfs2/buf.c
@@ -1,182 +1,183 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <linux/types.h>
#include "libgfs2.h"
static __inline__ osi_list_t *
blkno2head(struct gfs2_sbd *sdp, uint64_t blkno)
{
return sdp->buf_hash +
(gfs2_disk_hash((char *)&blkno, sizeof(uint64_t)) & BUF_HASH_MASK);
}
void write_buffer(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh)
{
osi_list_del(&bh->b_list);
osi_list_del(&bh->b_hash);
sdp->num_bufs--;
if (bh->b_changed) {
do_lseek(sdp->device_fd, bh->b_blocknr * sdp->bsize);
do_write(sdp->device_fd, bh->b_data, sdp->bsize);
sdp->writes++;
}
free(bh);
}
static void
add_buffer(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh)
{
osi_list_t *head = blkno2head(sdp, bh->b_blocknr);
osi_list_add(&bh->b_list, &sdp->buf_list);
osi_list_add(&bh->b_hash, head);
sdp->num_bufs++;
while (sdp->num_bufs * sdp->bsize > 128 << 20) {
bh = osi_list_entry(sdp->buf_list.prev, struct gfs2_buffer_head,
b_list);
if (bh->b_count) {
osi_list_del(&bh->b_list);
osi_list_add(&bh->b_list, &sdp->buf_list);
continue;
}
write_buffer(sdp, bh);
sdp->spills++;
}
}
struct gfs2_buffer_head *bfind(struct gfs2_sbd *sdp, uint64_t num)
{
osi_list_t *head = blkno2head(sdp, num);
osi_list_t *tmp;
struct gfs2_buffer_head *bh;
for (tmp = head->next; tmp != head; tmp = tmp->next) {
bh = osi_list_entry(tmp, struct gfs2_buffer_head, b_hash);
if (bh->b_blocknr == num) {
osi_list_del(&bh->b_list);
osi_list_add(&bh->b_list, &sdp->buf_list);
osi_list_del(&bh->b_hash);
osi_list_add(&bh->b_hash, head);
bh->b_count++;
return bh;
}
}
return NULL;
}
struct gfs2_buffer_head *bget_generic(struct gfs2_sbd *sdp, uint64_t num,
int find_existing, int read_disk)
{
struct gfs2_buffer_head *bh;
if (find_existing) {
bh = bfind(sdp, num);
if (bh)
return bh;
}
zalloc(bh, sizeof(struct gfs2_buffer_head) + sdp->bsize);
bh->b_count = 1;
bh->b_blocknr = num;
bh->b_data = (char *)bh + sizeof(struct gfs2_buffer_head);
if (read_disk) {
do_lseek(sdp->device_fd, num * sdp->bsize);
do_read(sdp->device_fd, bh->b_data, sdp->bsize);
}
add_buffer(sdp, bh);
bh->b_changed = FALSE;
return bh;
}
struct gfs2_buffer_head *bget(struct gfs2_sbd *sdp, uint64_t num)
{
return bget_generic(sdp, num, TRUE, FALSE);
}
struct gfs2_buffer_head *bread(struct gfs2_sbd *sdp, uint64_t num)
{
return bget_generic(sdp, num, TRUE, TRUE);
}
struct gfs2_buffer_head *bget_zero(struct gfs2_sbd *sdp, uint64_t num)
{
return bget_generic(sdp, num, FALSE, FALSE);
}
struct gfs2_buffer_head *bhold(struct gfs2_buffer_head *bh)
{
if (!bh->b_count)
die("buffer hold error for block %" PRIu64 " (0x%" PRIx64")\n",
bh->b_blocknr, bh->b_blocknr);
bh->b_count++;
return bh;
}
void brelse(struct gfs2_buffer_head *bh, enum update_flags updated)
{
/* We can't just say b_changed = updated because we don't want to */
/* set it FALSE if it's TRUE until we write the changed data to disk. */
if (updated)
bh->b_changed = TRUE;
if (!bh->b_count)
die("buffer count underflow for block %" PRIu64 " (0x%" PRIx64")\n",
bh->b_blocknr, bh->b_blocknr);
bh->b_count--;
}
void bsync(struct gfs2_sbd *sdp)
{
struct gfs2_buffer_head *bh;
while (!osi_list_empty(&sdp->buf_list)) {
bh = osi_list_entry(sdp->buf_list.prev, struct gfs2_buffer_head,
b_list);
if (bh->b_count)
die("buffer still held for block: %" PRIu64 " (0x%" PRIx64")\n",
bh->b_blocknr, bh->b_blocknr);
write_buffer(sdp, bh);
}
}
/* commit buffers to disk but do not discard */
void bcommit(struct gfs2_sbd *sdp)
{
osi_list_t *tmp, *x;
struct gfs2_buffer_head *bh;
osi_list_foreach_safe(tmp, &sdp->buf_list, x) {
bh = osi_list_entry(tmp, struct gfs2_buffer_head, b_list);
if (!bh->b_count) /* if not reserved for later */
write_buffer(sdp, bh); /* write the data, free the memory */
else if (bh->b_changed) { /* if buffer has changed */
do_lseek(sdp->device_fd, bh->b_blocknr * sdp->bsize);
do_write(sdp->device_fd, bh->b_data, sdp->bsize); /* write it out */
bh->b_changed = FALSE; /* no longer changed */
}
}
+ fsync(sdp->device_fd);
}
/* Check for unreleased buffers */
void bcheck(struct gfs2_sbd *sdp)
{
osi_list_t *tmp;
struct gfs2_buffer_head *bh;
osi_list_foreach(tmp, &sdp->buf_list) {
bh = osi_list_entry(tmp, struct gfs2_buffer_head, b_list);
if (bh->b_count)
die("buffer still held: %"PRIu64"\n", bh->b_blocknr);
}
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Nov 23, 11:07 AM (1 d, 17 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1018647
Default Alt Text
(4 KB)
Attached To
Mode
rR Resource Agents
Attached
Detach File
Event Timeline
Log In to Comment