mirror of
https://github.com/vgough/encfs.git
synced 2024-11-25 01:13:12 +01:00
Return errno in case of write failed
so make ::pwrite return an int
This commit is contained in:
parent
ac87a8ba0e
commit
63d11e6989
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user