summaryrefslogtreecommitdiffstats
path: root/xlators/cluster/nsr-recon
diff options
context:
space:
mode:
authorJeff Darcy <jdarcy@redhat.com>2014-01-30 22:10:19 +0000
committerJeff Darcy <jdarcy@redhat.com>2014-02-11 13:57:04 +0000
commiteaac191c29733173cbe2fbfd5604c26bd478002d (patch)
treed8c0b84f29a7f09ea25ffb47af409589c5d39270 /xlators/cluster/nsr-recon
parentef9d6ebe81e75463cd1ff0d3cf9a649bd2002421 (diff)
nsr-recon: fix entry-count error when logs are preallocated
Change-Id: I48dc83f5ea5a47ec8ef7eaadf8ecbc5f2a725fd3 Signed-off-by: Jeff Darcy <jdarcy@redhat.com>
Diffstat (limited to 'xlators/cluster/nsr-recon')
-rw-r--r--xlators/cluster/nsr-recon/src/recon_xlator.c77
1 files changed, 65 insertions, 12 deletions
diff --git a/xlators/cluster/nsr-recon/src/recon_xlator.c b/xlators/cluster/nsr-recon/src/recon_xlator.c
index b527633d8..da14aab93 100644
--- a/xlators/cluster/nsr-recon/src/recon_xlator.c
+++ b/xlators/cluster/nsr-recon/src/recon_xlator.c
@@ -114,26 +114,79 @@ static void get_frame(nsr_recon_private_t *priv,
GF_ASSERT(0);
}
+#define ENTRY_SIZE 128
+
+long
+get_entry_count (char *path)
+{
+ int fd;
+ struct stat buf;
+ unsigned long entries = -1;
+ long min; /* last entry not known to be empty */
+ long max; /* first entry known to be empty */
+ long curr;
+ char entry[ENTRY_SIZE];
+ void *err_label = &&done;
+
+ fd = open(path,O_RDONLY);
+ if (fd < 0) {
+ goto *err_label;
+ }
+ err_label = &&close_fd;
+
+ if (fstat(fd,&buf) < 0) {
+ goto *err_label;
+ }
+
+ min = 0;
+ max = buf.st_size / ENTRY_SIZE;
+ printf("max = %ld\n",max);
+
+ while ((min+1) < max) {
+ curr = (min + max) / 2;
+ printf("trying entry %ld\n",curr);
+ if (lseek(fd,curr*ENTRY_SIZE,SEEK_SET) < 0) {
+ goto *err_label;
+ }
+ if (read(fd,entry,sizeof(entry)) != sizeof(entry)) {
+ goto *err_label;
+ }
+ if ((entry[0] == '_') && (entry[1] == 'P')) {
+ min = curr;
+ }
+ else {
+ max = curr;
+ }
+ }
+
+ entries = max;
+
+close_fd:
+ close(fd);
+done:
+ return entries;
+}
+
// Get the term info for the term number specified
void nsr_recon_libchangelog_get_this_term_info(xlator_t *this, char *bp, int32_t term, nsr_recon_last_term_info_t *lt)
{
- struct stat buf;
char path[PATH_MAX];
+ long entries;
bzero(lt, sizeof(nsr_recon_last_term_info_t));
lt->last_term = term;
sprintf(path,"%s/%s%d",bp,"TERM.",term);
- if (!stat(path, &buf) && (buf.st_size > 128)) {
- if (buf.st_size <= 128) {
- lt->first_index = 0;
- lt->last_index = 0;
- lt->commited_ops = 0;
- }
- else {
- lt->first_index = 1;
- lt->last_index = ((buf.st_size - 128)/128) + 1 ;
- lt->commited_ops = lt->last_index - lt->first_index + 1;
- }
+ entries = get_entry_count(path);
+ if (entries > 1) {
+ /* The first entry is actually a header. */
+ lt->first_index = 1;
+ /*
+ * This seems wrong, because it means that last_index*128 will
+ * be exactly at EOF and commited_ops will be one greater than
+ * it should be. Maybe some other code makes the exact
+ * opposite mistake to compensate.
+ */
+ lt->last_index = lt->commited_ops = (int)entries;
}
recon_main_log (this->name, GF_LOG_INFO, "for term=%d got first_index=%d last_index=%d commited_ops=%d\n",
term, lt->first_index, lt->last_index, lt->commited_ops);