Return errno in case of write failed

so make ::pwrite return an int
This commit is contained in:
benrubson 2017-03-11 19:38:17 +01:00
parent ac87a8ba0e
commit 63d11e6989
12 changed files with 43 additions and 38 deletions

View File

@ -94,15 +94,15 @@ ssize_t BlockFileIO::cacheReadOneBlock(const IORequest &req) const {
}
}
bool BlockFileIO::cacheWriteOneBlock(const IORequest &req) {
int BlockFileIO::cacheWriteOneBlock(const IORequest &req) {
// cache results of write (before pass-thru, because it may be modified
// in-place)
memcpy(_cache.data, req.data, req.dataLen);
_cache.offset = req.offset;
_cache.dataLen = req.dataLen;
bool ok = writeOneBlock(req);
if (!ok) clearCache(_cache, _blockSize);
return ok;
int res = writeOneBlock(req);
if (res) clearCache(_cache, _blockSize);
return res;
}
/**
@ -171,11 +171,11 @@ ssize_t BlockFileIO::read(const IORequest &req) const {
return result;
}
bool BlockFileIO::write(const IORequest &req) {
int BlockFileIO::write(const IORequest &req) {
CHECK(_blockSize != 0);
off_t fileSize = getSize();
if (fileSize < 0) return false;
if (fileSize < 0) return fileSize;
// where write request begins
off_t blockNum = req.offset / _blockSize;
@ -213,7 +213,7 @@ bool BlockFileIO::write(const IORequest &req) {
blockReq.data = NULL;
blockReq.dataLen = _blockSize;
bool ok = true;
int res = 0;
size_t size = req.dataLen;
unsigned char *inPtr = req.data;
while (size) {
@ -251,8 +251,8 @@ bool BlockFileIO::write(const IORequest &req) {
}
// Finally, write the damn thing!
if (!cacheWriteOneBlock(blockReq)) {
ok = false;
res = cacheWriteOneBlock(blockReq);
if (res) {
break;
}
@ -265,7 +265,7 @@ bool BlockFileIO::write(const IORequest &req) {
if (mb.data) MemoryPool::release(mb);
return ok;
return res;
}
int BlockFileIO::blockSize() const { return _blockSize; }
@ -378,9 +378,9 @@ int BlockFileIO::truncateBase(off_t size, FileIO *base) {
// write back out partial block
req.dataLen = partialBlock;
bool wrRes = cacheWriteOneBlock(req);
int wrRes = cacheWriteOneBlock(req);
if ((rdSz < 0) || (!wrRes)) {
if ((rdSz < 0) || (wrRes)) {
// rwarning - unlikely to ever occur..
RLOG(WARNING) << "truncate failure: read " << rdSz
<< " bytes, partial block of " << partialBlock;

View File

@ -43,7 +43,7 @@ class BlockFileIO : public FileIO {
// implemented in terms of blocks.
virtual ssize_t read(const IORequest &req) const;
virtual bool write(const IORequest &req);
virtual int write(const IORequest &req);
virtual int blockSize() const;
@ -54,10 +54,10 @@ class BlockFileIO : public FileIO {
// same as read(), except that the request.offset field is guarenteed to be
// block aligned, and the request size will not be larger then 1 block.
virtual ssize_t readOneBlock(const IORequest &req) const = 0;
virtual bool writeOneBlock(const IORequest &req) = 0;
virtual int writeOneBlock(const IORequest &req) = 0;
ssize_t cacheReadOneBlock(const IORequest &req) const;
bool cacheWriteOneBlock(const IORequest &req);
int cacheWriteOneBlock(const IORequest &req);
int _blockSize;
bool _allowHoles;

View File

@ -346,12 +346,12 @@ ssize_t CipherFileIO::readOneBlock(const IORequest &req) const {
return readSize;
}
bool CipherFileIO::writeOneBlock(const IORequest &req) {
int CipherFileIO::writeOneBlock(const IORequest &req) {
if (haveHeader && fsConfig->reverseEncryption) {
VLOG(1)
<< "writing to a reverse mount with per-file IVs is not implemented";
return false;
return -EPERM;
}
int bs = blockSize();
@ -366,19 +366,20 @@ bool CipherFileIO::writeOneBlock(const IORequest &req) {
ok = blockWrite(req.data, (int)req.dataLen, blockNum ^ fileIV);
}
int res = 0;
if (ok) {
if (haveHeader) {
IORequest tmpReq = req;
tmpReq.offset += HEADER_SIZE;
ok = base->write(tmpReq);
res = base->write(tmpReq);
} else
ok = base->write(req);
res = base->write(req);
} else {
VLOG(1) << "encodeBlock failed for block " << blockNum << ", size "
<< req.dataLen;
ok = false;
res = -EBADMSG;
}
return ok;
return res;
}
bool CipherFileIO::blockWrite(unsigned char *buf, int size,

View File

@ -65,7 +65,7 @@ class CipherFileIO : public BlockFileIO {
private:
virtual ssize_t readOneBlock(const IORequest &req) const;
virtual bool writeOneBlock(const IORequest &req);
virtual int writeOneBlock(const IORequest &req);
virtual void generateReverseHeader(unsigned char *data);
void initHeader();

View File

@ -68,7 +68,7 @@ class FileIO {
virtual off_t getSize() const = 0;
virtual ssize_t read(const IORequest &req) const = 0;
virtual bool write(const IORequest &req) = 0;
virtual int write(const IORequest &req) = 0;
virtual int truncate(off_t size) = 0;

View File

@ -209,7 +209,7 @@ ssize_t FileNode::read(off_t offset, unsigned char *data, ssize_t size) const {
return io->read(req);
}
bool FileNode::write(off_t offset, unsigned char *data, ssize_t size) {
int FileNode::write(off_t offset, unsigned char *data, ssize_t size) {
VLOG(1) << "FileNode::write offset " << offset << ", data size " << size;
IORequest req;

View File

@ -68,7 +68,7 @@ class FileNode {
off_t getSize() const;
ssize_t read(off_t offset, unsigned char *data, ssize_t size) const;
bool write(off_t offset, unsigned char *data, ssize_t size);
int write(off_t offset, unsigned char *data, ssize_t size);
// truncate the file to a particular size
int truncate(off_t size);

View File

@ -208,7 +208,7 @@ ssize_t MACFileIO::readOneBlock(const IORequest &req) const {
return readSize;
}
bool MACFileIO::writeOneBlock(const IORequest &req) {
int MACFileIO::writeOneBlock(const IORequest &req) {
int headerSize = macBytes + randBytes;
int bs = blockSize() + headerSize;
@ -225,7 +225,7 @@ bool MACFileIO::writeOneBlock(const IORequest &req) {
memcpy(newReq.data + headerSize, req.data, req.dataLen);
if (randBytes > 0) {
if (!cipher->randomize(newReq.data + macBytes, randBytes, false))
return false;
return -EBADMSG;
}
if (macBytes > 0) {
@ -240,11 +240,11 @@ bool MACFileIO::writeOneBlock(const IORequest &req) {
}
// now, we can let the next level have it..
bool ok = base->write(newReq);
int res = base->write(newReq);
MemoryPool::release(mb);
return ok;
return res;
}
int MACFileIO::truncate(off_t size) {

View File

@ -64,7 +64,7 @@ class MACFileIO : public BlockFileIO {
private:
virtual ssize_t readOneBlock(const IORequest &req) const;
virtual bool writeOneBlock(const IORequest &req);
virtual int writeOneBlock(const IORequest &req);
std::shared_ptr<FileIO> base;
std::shared_ptr<Cipher> cipher;

View File

@ -206,7 +206,7 @@ ssize_t RawFileIO::read(const IORequest &req) const {
return readSize;
}
bool RawFileIO::write(const IORequest &req) {
int RawFileIO::write(const IORequest &req) {
rAssert(fd >= 0);
rAssert(true == canWrite);
@ -215,14 +215,17 @@ bool RawFileIO::write(const IORequest &req) {
ssize_t bytes = req.dataLen;
off_t offset = req.offset;
int eno = 0;
while (bytes && retrys > 0) {
errno = 0;
ssize_t writeSize = ::pwrite(fd, buf, bytes, offset);
eno = errno;
if (writeSize < 0) {
knownSize = false;
RLOG(WARNING) << "write failed at offset " << offset << " for " << bytes
<< " bytes: " << strerror(errno);
return false;
<< " bytes: " << strerror(eno);
return -eno;
}
bytes -= writeSize;
@ -235,14 +238,14 @@ bool RawFileIO::write(const IORequest &req) {
RLOG(ERROR) << "Write error: wrote " << req.dataLen - bytes << " bytes of "
<< req.dataLen << ", max retries reached";
knownSize = false;
return false;
return (eno) ? -eno : -EIO;
} else {
if (knownSize) {
off_t last = req.offset + req.dataLen;
if (last > fileSize) fileSize = last;
}
return true;
return 0;
}
}

View File

@ -46,7 +46,7 @@ class RawFileIO : public FileIO {
virtual off_t getSize() const;
virtual ssize_t read(const IORequest &req) const;
virtual bool write(const IORequest &req);
virtual int write(const IORequest &req);
virtual int truncate(off_t size);

View File

@ -619,10 +619,11 @@ int encfs_fsync(const char *path, int dataSync, struct fuse_file_info *file) {
}
int _do_write(FileNode *fnode, unsigned char *ptr, size_t size, off_t offset) {
if (fnode->write(offset, ptr, size))
int res = fnode->write(offset, ptr, size);
if (!res)
return size;
else
return -EIO;
return res;
}
int encfs_write(const char *path, const char *buf, size_t size, off_t offset,