Linux fsync和syncfs行为

时间:2019-05-15 21:24:10

标签: linux fsync

测试:

  1. 写入目标设备-可验证模式,记录大小512b。
  2. 每n次迭代同步目标设备。
  3. 将有关上述写入的信息写入日志设备。
  4. fsync每次迭代记录日志。
  5. 转到步骤1。

步骤2可以在syncfs()和fsync()调用之间切换。目标设备是原始块设备。

开始测试,等待几分钟,重新设置电源。重新启动后,测试将读取日志文件以找出最后一个有效记录,并在目标设备上查找该记录。目标设备上记录的读取失败被视为失败。

结果:

每次在目标设备上使用fsync()时,测试都会通过,但是在使用syncfs()时,测试会间歇性地失败。知道为什么吗?

一些相关的代码段。如果需要,我可以发布完整文件。

static char recordbuff[RECORD_SIZE] __attribute__ ((aligned(RECORD_SIZE)));

static inline
void writerecord(int fd, struct msg *m, int dosync) {
        int rc;

        memcpy(recordbuff, m, sizeof(*m));

        rc = write(fd, recordbuff, sizeof(recordbuff));
        assert(rc == sizeof(recordbuff));

        if (dosync) {
                if (use_syncfs) {
                        rc = syncfs(fd);
                } else {
                        rc = fsync(fd);
                }
                assert (rc == 0);
        }
}

static inline
void writelog(int logfd, unsigned int iter) {
        int rc;

        rc=lseek(logfd, 0, SEEK_SET);
        assert(rc==0);

        rc = write(logfd, &iter, sizeof(iter));
        assert (rc == sizeof(iter));

        rc = fsync(logfd);
        assert (rc == 0);
}

static void main()
{
...
        while (1) {
                // create new record
                next_msg(&m, &n);
                dump_msg("new msg", &n);

                if ((n.iteration % MAX_ITERATIONS) == 0) {
                        /* wrap over */
                        rc = lseek(fd, 0, SEEK_SET);
                        assert (rc == 0);
                }

                // write new record
                if ((n.iteration % SYNC_ITERATION) == 0) {
                        writerecord(fd, &n, !(mode & O_SYNC));
                        writelog(logfd, n.iteration);
                } else {
                        writerecord(fd, &n, 0);
                }

                memcpy(&m, &n, sizeof(m));
        }
}

0 个答案:

没有答案