EXPORTED int mappedfile_readlock(struct mappedfile *mf) { struct stat sbuf, sbuffile; int newfd = -1; assert(mf->lock_status == MF_UNLOCKED); assert(mf->fd != -1); assert(!mf->dirty); for (;;) { if (lock_shared(mf->fd, mf->fname) < 0) { syslog(LOG_ERR, "IOERROR: lock_shared %s: %m", mf->fname); return -EIO; } if (fstat(mf->fd, &sbuf) == -1) { syslog(LOG_ERR, "IOERROR: fstat %s: %m", mf->fname); lock_unlock(mf->fd, mf->fname); return -EIO; } if (stat(mf->fname, &sbuffile) == -1) { syslog(LOG_ERR, "IOERROR: stat %s: %m", mf->fname); lock_unlock(mf->fd, mf->fname); return -EIO; } if (sbuf.st_ino == sbuffile.st_ino) break; newfd = open(mf->fname, O_RDWR, 0644); if (newfd == -1) { syslog(LOG_ERR, "IOERROR: open %s: %m", mf->fname); lock_unlock(mf->fd, mf->fname); return -EIO; } dup2(newfd, mf->fd); close(newfd); } mf->lock_status = MF_READLOCKED; /* XXX - can we guarantee the fd isn't reused? */ if (mf->map_ino != sbuf.st_ino) { buf_free(&mf->map_buf); } _ensure_mapped(mf, sbuf.st_size, /*update*/0); return 0; }
void shared_spinlock::lock_upgrade() { lock_shared(); }