Handle errors or short reads from pread when looking for the journal end mark. To simplify the code flow also remove jrnl_has_end_mark and IS_END_MARK_SET in favour of inlining them into jrnl_recover. Signed-off-by: Christoph Hellwig --- sheep/journal.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) Index: sheepdog/sheep/journal.c =================================================================== --- sheepdog.orig/sheep/journal.c 2012-04-25 10:07:11.292166667 +0200 +++ sheepdog/sheep/journal.c 2012-04-25 10:12:25.604174716 +0200 @@ -20,7 +20,6 @@ #include "sheep_priv.h" #define JRNL_END_MARK 0x87654321UL -#define IS_END_MARK_SET(var) (var == JRNL_END_MARK) /* Journal header for data object */ struct jrnl_head { @@ -89,18 +88,6 @@ static int jrnl_remove(struct jrnl_descr return ret; } -static int jrnl_has_end_mark(struct jrnl_descriptor *jd) -{ - ssize_t ret; - uint32_t end_mark = 0; - struct jrnl_head *head = (struct jrnl_head *) &jd->head; - - ret = pread64(jd->fd, &end_mark, sizeof(end_mark), - sizeof(*head) + head->size); - - return IS_END_MARK_SET(end_mark); -} - static int jrnl_write_header(struct jrnl_descriptor *jd) { ssize_t ret; @@ -253,8 +240,9 @@ int jrnl_recover(const char *jrnl_dir) vprintf(SDOG_NOTICE, "starting journal recovery\n"); while ((d = readdir(dir))) { - int ret; struct jrnl_descriptor jd; + uint32_t end_mark = 0; + int ret; if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, "..")) continue; @@ -267,8 +255,18 @@ int jrnl_recover(const char *jrnl_dir) jrnl_file_path); goto end_while_3; } - if (!jrnl_has_end_mark(&jd)) + + ret = pread64(jd.fd, &end_mark, sizeof(end_mark), + sizeof(jd.head) + jd.head.size); + if (ret != sizeof(end_mark)) { + eprintf("can't read journal end mark for object %s\n", + jd.head.target_path); goto end_while_2; + } + + if (end_mark != JRNL_END_MARK) + goto end_while_2; + jd.target_fd = open(jd.head.target_path, O_DSYNC | O_RDWR); if (ret) { eprintf("unable to open the object file %s for recovery\n",