mirror of
https://github.com/vgough/encfs.git
synced 2024-11-28 19:03:42 +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
|
// cache results of write (before pass-thru, because it may be modified
|
||||||
// in-place)
|
// in-place)
|
||||||
memcpy(_cache.data, req.data, req.dataLen);
|
memcpy(_cache.data, req.data, req.dataLen);
|
||||||
_cache.offset = req.offset;
|
_cache.offset = req.offset;
|
||||||
_cache.dataLen = req.dataLen;
|
_cache.dataLen = req.dataLen;
|
||||||
bool ok = writeOneBlock(req);
|
int res = writeOneBlock(req);
|
||||||
if (!ok) clearCache(_cache, _blockSize);
|
if (res) clearCache(_cache, _blockSize);
|
||||||
return ok;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -171,11 +171,11 @@ ssize_t BlockFileIO::read(const IORequest &req) const {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BlockFileIO::write(const IORequest &req) {
|
int BlockFileIO::write(const IORequest &req) {
|
||||||
CHECK(_blockSize != 0);
|
CHECK(_blockSize != 0);
|
||||||
|
|
||||||
off_t fileSize = getSize();
|
off_t fileSize = getSize();
|
||||||
if (fileSize < 0) return false;
|
if (fileSize < 0) return fileSize;
|
||||||
|
|
||||||
// where write request begins
|
// where write request begins
|
||||||
off_t blockNum = req.offset / _blockSize;
|
off_t blockNum = req.offset / _blockSize;
|
||||||
@ -213,7 +213,7 @@ bool BlockFileIO::write(const IORequest &req) {
|
|||||||
blockReq.data = NULL;
|
blockReq.data = NULL;
|
||||||
blockReq.dataLen = _blockSize;
|
blockReq.dataLen = _blockSize;
|
||||||
|
|
||||||
bool ok = true;
|
int res = 0;
|
||||||
size_t size = req.dataLen;
|
size_t size = req.dataLen;
|
||||||
unsigned char *inPtr = req.data;
|
unsigned char *inPtr = req.data;
|
||||||
while (size) {
|
while (size) {
|
||||||
@ -251,8 +251,8 @@ bool BlockFileIO::write(const IORequest &req) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Finally, write the damn thing!
|
// Finally, write the damn thing!
|
||||||
if (!cacheWriteOneBlock(blockReq)) {
|
res = cacheWriteOneBlock(blockReq);
|
||||||
ok = false;
|
if (res) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,7 +265,7 @@ bool BlockFileIO::write(const IORequest &req) {
|
|||||||
|
|
||||||
if (mb.data) MemoryPool::release(mb);
|
if (mb.data) MemoryPool::release(mb);
|
||||||
|
|
||||||
return ok;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int BlockFileIO::blockSize() const { return _blockSize; }
|
int BlockFileIO::blockSize() const { return _blockSize; }
|
||||||
@ -378,9 +378,9 @@ int BlockFileIO::truncateBase(off_t size, FileIO *base) {
|
|||||||
|
|
||||||
// write back out partial block
|
// write back out partial block
|
||||||
req.dataLen = partialBlock;
|
req.dataLen = partialBlock;
|
||||||
bool wrRes = cacheWriteOneBlock(req);
|
int wrRes = cacheWriteOneBlock(req);
|
||||||
|
|
||||||
if ((rdSz < 0) || (!wrRes)) {
|
if ((rdSz < 0) || (wrRes)) {
|
||||||
// rwarning - unlikely to ever occur..
|
// rwarning - unlikely to ever occur..
|
||||||
RLOG(WARNING) << "truncate failure: read " << rdSz
|
RLOG(WARNING) << "truncate failure: read " << rdSz
|
||||||
<< " bytes, partial block of " << partialBlock;
|
<< " bytes, partial block of " << partialBlock;
|
||||||
|
@ -43,7 +43,7 @@ class BlockFileIO : public FileIO {
|
|||||||
|
|
||||||
// implemented in terms of blocks.
|
// implemented in terms of blocks.
|
||||||
virtual ssize_t read(const IORequest &req) const;
|
virtual ssize_t read(const IORequest &req) const;
|
||||||
virtual bool write(const IORequest &req);
|
virtual int write(const IORequest &req);
|
||||||
|
|
||||||
virtual int blockSize() const;
|
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
|
// 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.
|
// block aligned, and the request size will not be larger then 1 block.
|
||||||
virtual ssize_t readOneBlock(const IORequest &req) const = 0;
|
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;
|
ssize_t cacheReadOneBlock(const IORequest &req) const;
|
||||||
bool cacheWriteOneBlock(const IORequest &req);
|
int cacheWriteOneBlock(const IORequest &req);
|
||||||
|
|
||||||
int _blockSize;
|
int _blockSize;
|
||||||
bool _allowHoles;
|
bool _allowHoles;
|
||||||
|
@ -346,12 +346,12 @@ ssize_t CipherFileIO::readOneBlock(const IORequest &req) const {
|
|||||||
return readSize;
|
return readSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CipherFileIO::writeOneBlock(const IORequest &req) {
|
int CipherFileIO::writeOneBlock(const IORequest &req) {
|
||||||
|
|
||||||
if (haveHeader && fsConfig->reverseEncryption) {
|
if (haveHeader && fsConfig->reverseEncryption) {
|
||||||
VLOG(1)
|
VLOG(1)
|
||||||
<< "writing to a reverse mount with per-file IVs is not implemented";
|
<< "writing to a reverse mount with per-file IVs is not implemented";
|
||||||
return false;
|
return -EPERM;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bs = blockSize();
|
int bs = blockSize();
|
||||||
@ -366,19 +366,20 @@ bool CipherFileIO::writeOneBlock(const IORequest &req) {
|
|||||||
ok = blockWrite(req.data, (int)req.dataLen, blockNum ^ fileIV);
|
ok = blockWrite(req.data, (int)req.dataLen, blockNum ^ fileIV);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int res = 0;
|
||||||
if (ok) {
|
if (ok) {
|
||||||
if (haveHeader) {
|
if (haveHeader) {
|
||||||
IORequest tmpReq = req;
|
IORequest tmpReq = req;
|
||||||
tmpReq.offset += HEADER_SIZE;
|
tmpReq.offset += HEADER_SIZE;
|
||||||
ok = base->write(tmpReq);
|
res = base->write(tmpReq);
|
||||||
} else
|
} else
|
||||||
ok = base->write(req);
|
res = base->write(req);
|
||||||
} else {
|
} else {
|
||||||
VLOG(1) << "encodeBlock failed for block " << blockNum << ", size "
|
VLOG(1) << "encodeBlock failed for block " << blockNum << ", size "
|
||||||
<< req.dataLen;
|
<< req.dataLen;
|
||||||
ok = false;
|
res = -EBADMSG;
|
||||||
}
|
}
|
||||||
return ok;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CipherFileIO::blockWrite(unsigned char *buf, int size,
|
bool CipherFileIO::blockWrite(unsigned char *buf, int size,
|
||||||
|
@ -65,7 +65,7 @@ class CipherFileIO : public BlockFileIO {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
virtual ssize_t readOneBlock(const IORequest &req) const;
|
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);
|
virtual void generateReverseHeader(unsigned char *data);
|
||||||
|
|
||||||
void initHeader();
|
void initHeader();
|
||||||
|
@ -68,7 +68,7 @@ class FileIO {
|
|||||||
virtual off_t getSize() const = 0;
|
virtual off_t getSize() const = 0;
|
||||||
|
|
||||||
virtual ssize_t read(const IORequest &req) 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;
|
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);
|
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;
|
VLOG(1) << "FileNode::write offset " << offset << ", data size " << size;
|
||||||
|
|
||||||
IORequest req;
|
IORequest req;
|
||||||
|
@ -68,7 +68,7 @@ class FileNode {
|
|||||||
off_t getSize() const;
|
off_t getSize() const;
|
||||||
|
|
||||||
ssize_t read(off_t offset, unsigned char *data, ssize_t size) 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
|
// truncate the file to a particular size
|
||||||
int truncate(off_t size);
|
int truncate(off_t size);
|
||||||
|
@ -208,7 +208,7 @@ ssize_t MACFileIO::readOneBlock(const IORequest &req) const {
|
|||||||
return readSize;
|
return readSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MACFileIO::writeOneBlock(const IORequest &req) {
|
int MACFileIO::writeOneBlock(const IORequest &req) {
|
||||||
int headerSize = macBytes + randBytes;
|
int headerSize = macBytes + randBytes;
|
||||||
|
|
||||||
int bs = blockSize() + headerSize;
|
int bs = blockSize() + headerSize;
|
||||||
@ -225,7 +225,7 @@ bool MACFileIO::writeOneBlock(const IORequest &req) {
|
|||||||
memcpy(newReq.data + headerSize, req.data, req.dataLen);
|
memcpy(newReq.data + headerSize, req.data, req.dataLen);
|
||||||
if (randBytes > 0) {
|
if (randBytes > 0) {
|
||||||
if (!cipher->randomize(newReq.data + macBytes, randBytes, false))
|
if (!cipher->randomize(newReq.data + macBytes, randBytes, false))
|
||||||
return false;
|
return -EBADMSG;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (macBytes > 0) {
|
if (macBytes > 0) {
|
||||||
@ -240,11 +240,11 @@ bool MACFileIO::writeOneBlock(const IORequest &req) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// now, we can let the next level have it..
|
// now, we can let the next level have it..
|
||||||
bool ok = base->write(newReq);
|
int res = base->write(newReq);
|
||||||
|
|
||||||
MemoryPool::release(mb);
|
MemoryPool::release(mb);
|
||||||
|
|
||||||
return ok;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int MACFileIO::truncate(off_t size) {
|
int MACFileIO::truncate(off_t size) {
|
||||||
|
@ -64,7 +64,7 @@ class MACFileIO : public BlockFileIO {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
virtual ssize_t readOneBlock(const IORequest &req) const;
|
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<FileIO> base;
|
||||||
std::shared_ptr<Cipher> cipher;
|
std::shared_ptr<Cipher> cipher;
|
||||||
|
@ -206,7 +206,7 @@ ssize_t RawFileIO::read(const IORequest &req) const {
|
|||||||
return readSize;
|
return readSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RawFileIO::write(const IORequest &req) {
|
int RawFileIO::write(const IORequest &req) {
|
||||||
rAssert(fd >= 0);
|
rAssert(fd >= 0);
|
||||||
rAssert(true == canWrite);
|
rAssert(true == canWrite);
|
||||||
|
|
||||||
@ -215,14 +215,17 @@ bool RawFileIO::write(const IORequest &req) {
|
|||||||
ssize_t bytes = req.dataLen;
|
ssize_t bytes = req.dataLen;
|
||||||
off_t offset = req.offset;
|
off_t offset = req.offset;
|
||||||
|
|
||||||
|
int eno = 0;
|
||||||
while (bytes && retrys > 0) {
|
while (bytes && retrys > 0) {
|
||||||
|
errno = 0;
|
||||||
ssize_t writeSize = ::pwrite(fd, buf, bytes, offset);
|
ssize_t writeSize = ::pwrite(fd, buf, bytes, offset);
|
||||||
|
eno = errno;
|
||||||
|
|
||||||
if (writeSize < 0) {
|
if (writeSize < 0) {
|
||||||
knownSize = false;
|
knownSize = false;
|
||||||
RLOG(WARNING) << "write failed at offset " << offset << " for " << bytes
|
RLOG(WARNING) << "write failed at offset " << offset << " for " << bytes
|
||||||
<< " bytes: " << strerror(errno);
|
<< " bytes: " << strerror(eno);
|
||||||
return false;
|
return -eno;
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes -= writeSize;
|
bytes -= writeSize;
|
||||||
@ -235,14 +238,14 @@ bool RawFileIO::write(const IORequest &req) {
|
|||||||
RLOG(ERROR) << "Write error: wrote " << req.dataLen - bytes << " bytes of "
|
RLOG(ERROR) << "Write error: wrote " << req.dataLen - bytes << " bytes of "
|
||||||
<< req.dataLen << ", max retries reached";
|
<< req.dataLen << ", max retries reached";
|
||||||
knownSize = false;
|
knownSize = false;
|
||||||
return false;
|
return (eno) ? -eno : -EIO;
|
||||||
} else {
|
} else {
|
||||||
if (knownSize) {
|
if (knownSize) {
|
||||||
off_t last = req.offset + req.dataLen;
|
off_t last = req.offset + req.dataLen;
|
||||||
if (last > fileSize) fileSize = last;
|
if (last > fileSize) fileSize = last;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ class RawFileIO : public FileIO {
|
|||||||
virtual off_t getSize() const;
|
virtual off_t getSize() const;
|
||||||
|
|
||||||
virtual ssize_t read(const IORequest &req) 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);
|
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) {
|
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;
|
return size;
|
||||||
else
|
else
|
||||||
return -EIO;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int encfs_write(const char *path, const char *buf, size_t size, off_t offset,
|
int encfs_write(const char *path, const char *buf, size_t size, off_t offset,
|
||||||
|
Loading…
Reference in New Issue
Block a user