nfs4: Add support for O_APPEND mode

This commit is contained in:
Pawel Dziepak
2012-06-29 02:15:08 +02:00
parent 636e922e5c
commit 86d2cab33f
4 changed files with 46 additions and 5 deletions
+39 -3
View File
@@ -1022,21 +1022,39 @@ Inode::Read(OpenFileCookie* cookie, off_t pos, void* buffer, size_t* _length)
status_t
Inode::Write(OpenFileCookie* cookie, off_t pos, const void* _buffer,
size_t length)
size_t *_length)
{
uint32 size = 0;
uint32 len = 0;
uint64 fileSize;
const char* buffer = reinterpret_cast<const char*>(_buffer);
while (size < length) {
while (size < *_length) {
do {
RPC::Server* serv = fFilesystem->Server();
Request request(serv);
RequestBuilder& req = request.Builder();
if (size == 0 && (cookie->fMode & O_APPEND) == O_APPEND) {
struct stat st;
status_t result = Stat(&st);
if (result != B_OK)
return result;
fileSize = st.st_size;
pos = fileSize;
}
req.PutFH(fHandle);
if ((cookie->fMode & O_APPEND) == O_APPEND) {
AttrValue attr;
attr.fAttribute = FATTR4_SIZE;
attr.fFreePointer = false;
attr.fData.fValue64 = fileSize + size;
req.Verify(&attr, 1);
}
req.Write(cookie->fStateId, cookie->fStateSeq, buffer + size,
pos + size, length - size);
pos + size, *_length - size);
status_t result = request.Send(cookie);
if (result != B_OK)
@@ -1044,6 +1062,16 @@ Inode::Write(OpenFileCookie* cookie, off_t pos, const void* _buffer,
ReplyInterpreter& reply = request.Reply();
// append: race condition
if (reply.NFS4Error() == NFS4ERR_NOT_SAME) {
if (size == 0)
continue;
else {
*_length = size;
return B_OK;
}
}
// filehandle has expired
if (reply.NFS4Error() == NFS4ERR_FHEXPIRED) {
_LookUpFilehandle();
@@ -1074,6 +1102,12 @@ Inode::Write(OpenFileCookie* cookie, off_t pos, const void* _buffer,
if (result != B_OK)
return result;
if ((cookie->fMode & O_APPEND) == O_APPEND) {
result = reply.Verify();
if (result != B_OK)
return result;
}
result = reply.Write(&len);
if (result != B_OK)
return result;
@@ -1084,6 +1118,8 @@ Inode::Write(OpenFileCookie* cookie, off_t pos, const void* _buffer,
} while (true);
}
*_length = size;
return B_OK;
}
+1 -1
View File
@@ -50,7 +50,7 @@ public:
status_t Read(OpenFileCookie* cookie, off_t pos,
void* buffer, size_t* length);
status_t Write(OpenFileCookie* cookie, off_t pos,
const void* buffer, size_t length);
const void* buffer, size_t *_length);
status_t OpenDir(OpenDirCookie* cookie);
status_t ReadDir(void* buffer, uint32 size,
@@ -573,6 +573,11 @@ RequestBuilder::_EncodeAttrs(XDR::WriteStream& stream, AttrValue* attr,
i++;
}
if (i < count && attr[i].fAttribute == FATTR4_SIZE) {
str.AddUHyper(attr[i].fData.fValue64);
i++;
}
if (i < count && attr[i].fAttribute == FATTR4_MODE) {
str.AddUInt(attr[i].fData.fValue32);
i++;
@@ -372,7 +372,7 @@ nfs4_write(fs_volume* volume, fs_vnode* vnode, void* _cookie, off_t pos,
OpenFileCookie* cookie = reinterpret_cast<OpenFileCookie*>(_cookie);
return inode->Write(cookie, pos, buffer, *length);
return inode->Write(cookie, pos, buffer, length);
}