|
a/src/utils/circache.cpp |
|
b/src/utils/circache.cpp |
|
... |
|
... |
612 |
string CirCache::getReason()
|
612 |
string CirCache::getReason()
|
613 |
{
|
613 |
{
|
614 |
return m_d ? m_d->m_reason.str() : "Not initialized";
|
614 |
return m_d ? m_d->m_reason.str() : "Not initialized";
|
615 |
}
|
615 |
}
|
616 |
|
616 |
|
|
|
617 |
// A scan callback which just records the last header offset and
|
|
|
618 |
// padsize seen. This is used with a scan(nofold) to find the last
|
|
|
619 |
// physical record in the file
|
|
|
620 |
class CCScanHookRecord : public CCScanHook {
|
|
|
621 |
public:
|
|
|
622 |
off_t headoffs;
|
|
|
623 |
off_t padsize;
|
|
|
624 |
CCScanHookRecord()
|
|
|
625 |
: headoffs(0), padsize(0)
|
|
|
626 |
{
|
|
|
627 |
}
|
|
|
628 |
virtual status takeone(off_t offs, const string& udi,
|
|
|
629 |
const EntryHeaderData& d)
|
|
|
630 |
{
|
|
|
631 |
headoffs = offs;
|
|
|
632 |
padsize = d.padsize;
|
|
|
633 |
LOGDEB2(("CCScanHookRecord::takeone: offs %lld padsize %lld\n",
|
|
|
634 |
headoffs, padsize));
|
|
|
635 |
return Continue;
|
|
|
636 |
}
|
|
|
637 |
};
|
|
|
638 |
|
617 |
bool CirCache::create(off_t m_maxsize, int flags)
|
639 |
bool CirCache::create(off_t maxsize, int flags)
|
618 |
{
|
640 |
{
|
619 |
LOGDEB(("CirCache::create: [%s] flags 0x%x\n", m_dir.c_str(), flags));
|
641 |
LOGDEB(("CirCache::create: [%s] maxsz %lld flags 0x%x\n",
|
|
|
642 |
m_dir.c_str(), maxsize, flags));
|
620 |
if (m_d == 0) {
|
643 |
if (m_d == 0) {
|
621 |
LOGERR(("CirCache::create: null data\n"));
|
644 |
LOGERR(("CirCache::create: null data\n"));
|
622 |
return false;
|
645 |
return false;
|
623 |
}
|
646 |
}
|
624 |
|
647 |
|
625 |
{
|
|
|
626 |
struct stat st;
|
648 |
struct stat st;
|
627 |
if (stat(m_dir.c_str(), &st) < 0) {
|
649 |
if (stat(m_dir.c_str(), &st) < 0) {
|
628 |
// Directory does not exist, create it
|
650 |
// Directory does not exist, create it
|
629 |
if (mkdir(m_dir.c_str(), 0777) < 0) {
|
651 |
if (mkdir(m_dir.c_str(), 0777) < 0) {
|
630 |
m_d->m_reason << "CirCache::create: mkdir(" << m_dir <<
|
652 |
m_d->m_reason << "CirCache::create: mkdir(" << m_dir <<
|
631 |
") failed" << " errno " << errno;
|
653 |
") failed" << " errno " << errno;
|
|
|
654 |
return false;
|
|
|
655 |
}
|
|
|
656 |
} else {
|
|
|
657 |
// If the file exists too, and truncate is not set, switch
|
|
|
658 |
// to open-mode. Still may need to update header params.
|
|
|
659 |
if (access(m_d->datafn(m_dir).c_str(), 0) >= 0 &&
|
|
|
660 |
!(flags & CC_CRTRUNCATE)) {
|
|
|
661 |
if (!open(CC_OPWRITE)) {
|
632 |
return false;
|
662 |
return false;
|
633 |
}
|
663 |
}
|
634 |
} else {
|
664 |
if (maxsize == m_d->m_maxsize &&
|
635 |
// Directory exists but file might still not exist:
|
665 |
((flags & CC_CRUNIQUE) != 0) == m_d->m_uniquentries) {
|
636 |
// e.g. the user is using a non default directory and
|
666 |
LOGDEB(("Header unchanged, no rewrite\n"));
|
637 |
// created it for us.
|
667 |
return true;
|
638 |
if (access(m_d->datafn(m_dir).c_str(), 0) >= 0) {
|
|
|
639 |
// File exists, switch to "open" mode, except if we're told to
|
|
|
640 |
// truncate.
|
|
|
641 |
if (!(flags & CC_CRTRUNCATE)) {
|
|
|
642 |
return open(CC_OPWRITE);
|
|
|
643 |
}
|
|
|
644 |
}
|
668 |
}
|
|
|
669 |
// If the new maxsize is bigger than current size, we need
|
|
|
670 |
// to stop recycling if this is what we are doing.
|
|
|
671 |
if (maxsize > m_d->m_maxsize && maxsize > st.st_size) {
|
|
|
672 |
// Scan the file to find the last physical record. The
|
|
|
673 |
// ohead is set at physical eof, and nhead is the last
|
|
|
674 |
// scanned record
|
|
|
675 |
CCScanHookRecord rec;
|
|
|
676 |
m_d->scan(CIRCACHE_FIRSTBLOCK_SIZE, &rec, false);
|
|
|
677 |
m_d->m_oheadoffs = lseek(m_d->m_fd, 0, SEEK_END);
|
|
|
678 |
m_d->m_nheadoffs = rec.headoffs;
|
|
|
679 |
m_d->m_npadsize = rec.padsize;
|
|
|
680 |
}
|
|
|
681 |
m_d->m_maxsize = maxsize;
|
|
|
682 |
m_d->m_uniquentries = ((flags & CC_CRUNIQUE) != 0);
|
|
|
683 |
LOGDEB(("CirCache::create: rewriting header with "
|
|
|
684 |
"maxsize %lld oheadoffs %lld nheadoffs %lld "
|
|
|
685 |
"npadsize %d unient %d\n",
|
|
|
686 |
m_d->m_maxsize, m_d->m_oheadoffs, m_d->m_nheadoffs,
|
|
|
687 |
m_d->m_npadsize, int(m_d->m_uniquentries)));
|
|
|
688 |
return m_d->writefirstblock();
|
|
|
689 |
}
|
645 |
// Else fall through to create file
|
690 |
// Else fallthrough to create file
|
646 |
}
|
|
|
647 |
}
|
691 |
}
|
648 |
|
692 |
|
649 |
if ((m_d->m_fd = ::open(m_d->datafn(m_dir).c_str(),
|
693 |
if ((m_d->m_fd = ::open(m_d->datafn(m_dir).c_str(),
|
650 |
O_CREAT | O_RDWR | O_TRUNC, 0666)) < 0) {
|
694 |
O_CREAT | O_RDWR | O_TRUNC, 0666)) < 0) {
|
651 |
m_d->m_reason << "CirCache::create: open/creat(" <<
|
695 |
m_d->m_reason << "CirCache::create: open/creat(" <<
|
652 |
m_d->datafn(m_dir) << ") failed " << "errno " << errno;
|
696 |
m_d->datafn(m_dir) << ") failed " << "errno " << errno;
|
653 |
return false;
|
697 |
return false;
|
654 |
}
|
698 |
}
|
655 |
|
699 |
|
656 |
m_d->m_maxsize = m_maxsize;
|
700 |
m_d->m_maxsize = maxsize;
|
657 |
m_d->m_oheadoffs = CIRCACHE_FIRSTBLOCK_SIZE;
|
701 |
m_d->m_oheadoffs = CIRCACHE_FIRSTBLOCK_SIZE;
|
658 |
m_d->m_uniquentries = ((flags & CC_CRUNIQUE) != 0);
|
702 |
m_d->m_uniquentries = ((flags & CC_CRUNIQUE) != 0);
|
659 |
|
703 |
|
660 |
char buf[CIRCACHE_FIRSTBLOCK_SIZE];
|
704 |
char buf[CIRCACHE_FIRSTBLOCK_SIZE];
|
661 |
memset(buf, 0, CIRCACHE_FIRSTBLOCK_SIZE);
|
705 |
memset(buf, 0, CIRCACHE_FIRSTBLOCK_SIZE);
|