X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=lib%2Fext2fs%2Fmmp.c;h=e96a227327fcaa691d3aa9fe5d8eaef26bb8d999;hb=947315c86645e3ac3e814a49a7e7ab4b3498f64b;hp=12bfc0f4257b5dcaf3050bf3ea9dee72d228f95f;hpb=e4681bca170094430ef173b67345d2d8f0cfcea8;p=thirdparty%2Fe2fsprogs.git diff --git a/lib/ext2fs/mmp.c b/lib/ext2fs/mmp.c index 12bfc0f42..e96a22732 100644 --- a/lib/ext2fs/mmp.c +++ b/lib/ext2fs/mmp.c @@ -12,6 +12,9 @@ #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif +#ifndef _DEFAULT_SOURCE +#define _DEFAULT_SOURCE /* since glibc 2.20 _SVID_SOURCE is deprecated */ +#endif #include "config.h" @@ -31,6 +34,13 @@ #define O_DIRECT 0 #endif +#if __GNUC_PREREQ (4, 6) +#pragma GCC diagnostic push +#ifndef CONFIG_MMP +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif +#endif + errcode_t ext2fs_mmp_read(ext2_filsys fs, blk64_t mmp_blk, void *buf) { #ifdef CONFIG_MMP @@ -47,8 +57,21 @@ errcode_t ext2fs_mmp_read(ext2_filsys fs, blk64_t mmp_blk, void *buf) * regardless of how the io_manager is doing reads, to avoid caching of * the MMP block by the io_manager or the VM. It needs to be fresh. */ if (fs->mmp_fd <= 0) { - fs->mmp_fd = open(fs->device_name, O_RDWR | O_DIRECT); + int flags = O_RDWR | O_DIRECT; + +retry: + fs->mmp_fd = open(fs->device_name, flags); if (fs->mmp_fd < 0) { + struct stat st; + + /* Avoid O_DIRECT for filesystem image files if open + * fails, since it breaks when running on tmpfs. */ + if (errno == EINVAL && (flags & O_DIRECT) && + stat(fs->device_name, &st) == 0 && + S_ISREG(st.st_mode)) { + flags &= ~O_DIRECT; + goto retry; + } retval = EXT2_ET_MMP_OPEN_DIRECT; goto out; } @@ -144,7 +167,7 @@ errcode_t ext2fs_mmp_write(ext2_filsys fs, blk64_t mmp_blk, void *buf) #define rand() random() #endif -unsigned ext2fs_mmp_new_seq() +unsigned ext2fs_mmp_new_seq(void) { #ifdef CONFIG_MMP unsigned new_seq; @@ -168,6 +191,7 @@ unsigned ext2fs_mmp_new_seq() #endif } +#ifdef CONFIG_MMP static errcode_t ext2fs_mmp_reset(ext2_filsys fs) { struct mmp_struct *mmp_s = NULL; @@ -185,7 +209,7 @@ static errcode_t ext2fs_mmp_reset(ext2_filsys fs) mmp_s->mmp_magic = EXT4_MMP_MAGIC; mmp_s->mmp_seq = EXT4_MMP_SEQ_CLEAN; mmp_s->mmp_time = 0; -#if _BSD_SOURCE || _XOPEN_SOURCE >= 500 +#ifdef HAVE_GETHOSTNAME gethostname(mmp_s->mmp_nodename, sizeof(mmp_s->mmp_nodename)); #else mmp_s->mmp_nodename[0] = '\0'; @@ -201,6 +225,7 @@ static errcode_t ext2fs_mmp_reset(ext2_filsys fs) out: return retval; } +#endif errcode_t ext2fs_mmp_update(ext2_filsys fs) { @@ -259,6 +284,10 @@ out: #endif } +#ifndef min +#define min(x, y) ((x) < (y) ? (x) : (y)) +#endif + /* * Make sure that the fs is not mounted or being fsck'ed while opening the fs. */ @@ -306,7 +335,7 @@ errcode_t ext2fs_mmp_start(ext2_filsys fs) if (mmp_s->mmp_check_interval > mmp_check_interval) mmp_check_interval = mmp_s->mmp_check_interval; - sleep(2 * mmp_check_interval + 1); + sleep(min(mmp_check_interval * 2 + 1, mmp_check_interval + 60)); retval = ext2fs_mmp_read(fs, fs->super->s_mmp_block, fs->mmp_buf); if (retval) @@ -322,7 +351,7 @@ clean_seq: goto mmp_error; mmp_s->mmp_seq = seq = ext2fs_mmp_new_seq(); -#if _BSD_SOURCE || _XOPEN_SOURCE >= 500 +#ifdef HAVE_GETHOSTNAME gethostname(mmp_s->mmp_nodename, sizeof(mmp_s->mmp_nodename)); #else strcpy(mmp_s->mmp_nodename, "unknown host"); @@ -334,7 +363,7 @@ clean_seq: if (retval) goto mmp_error; - sleep(2 * mmp_check_interval + 1); + sleep(min(2 * mmp_check_interval + 1, mmp_check_interval + 60)); retval = ext2fs_mmp_read(fs, fs->super->s_mmp_block, fs->mmp_buf); if (retval) @@ -371,7 +400,7 @@ errcode_t ext2fs_mmp_stop(ext2_filsys fs) struct mmp_struct *mmp, *mmp_cmp; errcode_t retval = 0; - if (!(fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_MMP) || + if (!ext2fs_has_feature_mmp(fs->super) || !(fs->flags & EXT2_FLAG_RW) || (fs->flags & EXT2_FLAG_SKIP_MMP)) goto mmp_error; @@ -398,6 +427,10 @@ mmp_error: return retval; #else + if (!ext2fs_has_feature_mmp(fs->super) || + !(fs->flags & EXT2_FLAG_RW) || (fs->flags & EXT2_FLAG_SKIP_MMP)) + return 0; + return EXT2_ET_OP_NOT_SUPPORTED; #endif } @@ -414,7 +447,7 @@ errcode_t ext2fs_mmp_update2(ext2_filsys fs, int immediately) struct timeval tv; errcode_t retval = 0; - if (!(fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_MMP) || + if (!ext2fs_has_feature_mmp(fs->super) || !(fs->flags & EXT2_FLAG_RW) || (fs->flags & EXT2_FLAG_SKIP_MMP)) return 0; @@ -440,6 +473,13 @@ errcode_t ext2fs_mmp_update2(ext2_filsys fs, int immediately) mmp_error: return retval; #else + if (!ext2fs_has_feature_mmp(fs->super) || + !(fs->flags & EXT2_FLAG_RW) || (fs->flags & EXT2_FLAG_SKIP_MMP)) + return 0; + return EXT2_ET_OP_NOT_SUPPORTED; #endif } +#if __GNUC_PREREQ (4, 6) +#pragma GCC diagnostic pop +#endif