Alien-Libjio
view release on metacpan or search on metacpan
libjio/libjio/check.c view on Meta::CPAN
off_t filelen, lr;
tfd = -1;
filelen = 0;
dir = NULL;
fs.fd = -1;
fs.jfd = -1;
fs.jdir = NULL;
fs.jdirfd = -1;
fs.jmap = MAP_FAILED;
map = NULL;
ret = 0;
res->total = 0;
res->invalid = 0;
res->in_progress = 0;
res->broken = 0;
res->corrupt = 0;
res->reapplied = 0;
fs.fd = open(name, O_RDWR | O_SYNC);
if (fs.fd < 0) {
ret = J_EIO;
if (errno == ENOENT)
ret = J_ENOENT;
goto exit;
}
fs.name = (char *) name;
/* Locking the whole file protect us from concurrent runs, but it's
* not to be trusted nor assumed (lingering transactions break it): it
* just helps prevent some accidents. */
lr = plockf(fs.fd, F_LOCKW, 0, 0);
if (lr == -1) {
/* In the future, we may want to differentiate this case from
* a normal I/O error. */
ret = J_EIO;
goto exit;
}
if (jdir == NULL) {
fs.jdir = (char *) malloc(PATH_MAX);
if (fs.jdir == NULL) {
ret = J_ENOMEM;
goto exit;
}
if (!get_jdir(name, fs.jdir)) {
ret = J_ENOMEM;
goto exit;
}
} else {
fs.jdir = strdup(jdir);
if (fs.jdir == NULL) {
ret = J_ENOMEM;
goto exit;
}
}
rv = lstat(fs.jdir, &sinfo);
if (rv < 0) {
ret = J_EIO;
if (errno == ENOENT)
ret = J_ENOJOURNAL;
goto exit;
}
if (!S_ISDIR(sinfo.st_mode)) {
ret = J_ENOJOURNAL;
goto exit;
}
fs.jdirfd = open(fs.jdir, O_RDONLY);
if (fs.jdirfd < 0) {
ret = J_EIO;
if (errno == ENOENT)
ret = J_ENOJOURNAL;
goto exit;
}
/* open the lock file, which is only used to complete the jfs
* structure */
snprintf(jlockfile, PATH_MAX, "%s/%s", fs.jdir, "lock");
rv = open(jlockfile, O_RDWR | O_CREAT, 0600);
if (rv < 0) {
ret = J_EIO;
if (errno == ENOENT)
ret = J_ENOJOURNAL;
goto exit;
}
fs.jfd = rv;
fs.jmap = (unsigned int *) mmap(NULL, sizeof(unsigned int),
PROT_READ | PROT_WRITE, MAP_SHARED, fs.jfd, 0);
if (fs.jmap == MAP_FAILED) {
ret = J_EIO;
goto exit;
}
dir = opendir(fs.jdir);
if (dir == NULL) {
ret = J_EIO;
if (errno == ENOENT)
ret = J_ENOJOURNAL;
goto exit;
}
/* find the greatest transaction number by looking into the journal
* directory */
maxtid = 0;
for (errno = 0, dent = readdir(dir); dent != NULL;
errno = 0, dent = readdir(dir)) {
/* see if the file is named like a transaction, ignore
* otherwise; as transactions are named as numbers > 0, a
* simple atoi() is enough testing */
rv = atoi(dent->d_name);
if (rv <= 0)
continue;
if (rv > maxtid)
maxtid = rv;
}
( run in 0.642 second using v1.01-cache-2.11-cpan-524268b4103 )