Implemented write stat.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29260 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -76,6 +76,7 @@ public:
|
|||||||
ino_t InodeNumber() { return fInodeNumber; }
|
ino_t InodeNumber() { return fInodeNumber; }
|
||||||
|
|
||||||
status_t ReadStat(struct stat *stat);
|
status_t ReadStat(struct stat *stat);
|
||||||
|
status_t WriteStat(const struct stat *stat, uint32 statMask);
|
||||||
|
|
||||||
status_t Open(int openMode, void **cookie);
|
status_t Open(int openMode, void **cookie);
|
||||||
status_t Close(void *cookie);
|
status_t Close(void *cookie);
|
||||||
@@ -91,8 +92,8 @@ private:
|
|||||||
ino_t fInodeNumber;
|
ino_t fInodeNumber;
|
||||||
write_buffer * fWriteBuffers;
|
write_buffer * fWriteBuffers;
|
||||||
off_t fOriginalNodeLength;
|
off_t fOriginalNodeLength;
|
||||||
off_t fCurrentNodeLength;
|
struct stat fStat;
|
||||||
time_t fModificationTime;
|
bool fHasStat;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -120,7 +121,7 @@ OverlayInode::OverlayInode(OverlayVolume *volume, fs_vnode *superVnode,
|
|||||||
fInodeNumber(inodeNumber),
|
fInodeNumber(inodeNumber),
|
||||||
fWriteBuffers(NULL),
|
fWriteBuffers(NULL),
|
||||||
fOriginalNodeLength(-1),
|
fOriginalNodeLength(-1),
|
||||||
fCurrentNodeLength(-1)
|
fHasStat(false)
|
||||||
{
|
{
|
||||||
TRACE("inode created\n");
|
TRACE("inode created\n");
|
||||||
}
|
}
|
||||||
@@ -148,21 +149,55 @@ OverlayInode::InitCheck()
|
|||||||
status_t
|
status_t
|
||||||
OverlayInode::ReadStat(struct stat *stat)
|
OverlayInode::ReadStat(struct stat *stat)
|
||||||
{
|
{
|
||||||
if (fSuperVnode.ops->read_stat == NULL)
|
if (!fHasStat) {
|
||||||
return B_UNSUPPORTED;
|
if (fSuperVnode.ops->read_stat == NULL)
|
||||||
|
return B_UNSUPPORTED;
|
||||||
|
|
||||||
status_t result = fSuperVnode.ops->read_stat(SuperVolume(), &fSuperVnode,
|
status_t result = fSuperVnode.ops->read_stat(SuperVolume(),
|
||||||
stat);
|
&fSuperVnode, &fStat);
|
||||||
if (result != B_OK)
|
if (result != B_OK)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
if (fCurrentNodeLength >= 0) {
|
fHasStat = true;
|
||||||
stat->st_size = fCurrentNodeLength;
|
|
||||||
stat->st_blocks = (stat->st_size + stat->st_blksize - 1)
|
|
||||||
/ stat->st_blksize;
|
|
||||||
stat->st_mtime = fModificationTime;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (stat == NULL)
|
||||||
|
return B_OK;
|
||||||
|
|
||||||
|
memcpy(stat, &fStat, sizeof(struct stat));
|
||||||
|
stat->st_blocks = (stat->st_size + stat->st_blksize - 1) / stat->st_blksize;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
OverlayInode::WriteStat(const struct stat *stat, uint32 statMask)
|
||||||
|
{
|
||||||
|
if (!fHasStat)
|
||||||
|
ReadStat(NULL);
|
||||||
|
|
||||||
|
if (statMask & B_STAT_SIZE)
|
||||||
|
fStat.st_size = stat->st_size;
|
||||||
|
|
||||||
|
if (statMask & B_STAT_MODE)
|
||||||
|
fStat.st_mode = stat->st_mode;
|
||||||
|
if (statMask & B_STAT_UID)
|
||||||
|
fStat.st_uid = stat->st_uid;
|
||||||
|
if (statMask & B_STAT_GID)
|
||||||
|
fStat.st_gid = stat->st_gid;
|
||||||
|
|
||||||
|
if (statMask & B_STAT_MODIFICATION_TIME)
|
||||||
|
fStat.st_mtime = stat->st_mtime;
|
||||||
|
if (statMask & B_STAT_CREATION_TIME)
|
||||||
|
fStat.st_crtime = stat->st_crtime;
|
||||||
|
|
||||||
|
if ((statMask & (B_STAT_MODE | B_STAT_UID | B_STAT_GID)) != 0
|
||||||
|
&& (statMask & B_STAT_MODIFICATION_TIME) == 0) {
|
||||||
|
fStat.st_mtime = time(NULL);
|
||||||
|
statMask |= B_STAT_MODIFICATION_TIME;
|
||||||
|
}
|
||||||
|
|
||||||
|
notify_stat_changed(SuperVolume()->id, fInodeNumber, statMask);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,21 +216,17 @@ OverlayInode::Open(int openMode, void **_cookie)
|
|||||||
struct stat stat;
|
struct stat stat;
|
||||||
status_t result = fSuperVnode.ops->read_stat(SuperVolume(),
|
status_t result = fSuperVnode.ops->read_stat(SuperVolume(),
|
||||||
&fSuperVnode, &stat);
|
&fSuperVnode, &stat);
|
||||||
if (result != B_OK) {
|
if (result != B_OK)
|
||||||
free(cookie);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
|
||||||
|
|
||||||
fOriginalNodeLength = stat.st_size;
|
fOriginalNodeLength = stat.st_size;
|
||||||
fCurrentNodeLength = stat.st_size;
|
|
||||||
fModificationTime = stat.st_mtime;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cookie->open_mode = openMode;
|
cookie->open_mode = openMode;
|
||||||
*_cookie = cookie;
|
*_cookie = cookie;
|
||||||
|
|
||||||
if (openMode & O_TRUNC)
|
if (openMode & O_TRUNC)
|
||||||
fCurrentNodeLength = 0;
|
fStat.st_size = 0;
|
||||||
|
|
||||||
openMode &= ~(O_RDWR | O_WRONLY | O_TRUNC | O_CREAT);
|
openMode &= ~(O_RDWR | O_WRONLY | O_TRUNC | O_CREAT);
|
||||||
status_t result = fSuperVnode.ops->open(SuperVolume(), &fSuperVnode,
|
status_t result = fSuperVnode.ops->open(SuperVolume(), &fSuperVnode,
|
||||||
@@ -232,7 +263,7 @@ OverlayInode::FreeCookie(void *_cookie)
|
|||||||
status_t
|
status_t
|
||||||
OverlayInode::Read(void *_cookie, off_t position, void *buffer, size_t *length)
|
OverlayInode::Read(void *_cookie, off_t position, void *buffer, size_t *length)
|
||||||
{
|
{
|
||||||
if (position >= fCurrentNodeLength) {
|
if (position >= fStat.st_size) {
|
||||||
*length = 0;
|
*length = 0;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -244,11 +275,15 @@ OverlayInode::Read(void *_cookie, off_t position, void *buffer, size_t *length)
|
|||||||
cookie->super_cookie, position, buffer, &readLength);
|
cookie->super_cookie, position, buffer, &readLength);
|
||||||
if (result != B_OK)
|
if (result != B_OK)
|
||||||
return result;
|
return result;
|
||||||
}
|
|
||||||
|
if (readLength < *length)
|
||||||
|
memset((uint8 *)buffer + readLength, 0, *length - readLength);
|
||||||
|
} else
|
||||||
|
memset(buffer, 0, *length);
|
||||||
|
|
||||||
// overlay the read with whatever chunks we have written
|
// overlay the read with whatever chunks we have written
|
||||||
write_buffer *element = fWriteBuffers;
|
write_buffer *element = fWriteBuffers;
|
||||||
*length = MIN(fCurrentNodeLength - position, *length);
|
*length = MIN(fStat.st_size - position, *length);
|
||||||
off_t end = position + *length;
|
off_t end = position + *length;
|
||||||
while (element) {
|
while (element) {
|
||||||
if (element->position > end)
|
if (element->position > end)
|
||||||
@@ -307,7 +342,7 @@ OverlayInode::Write(void *_cookie, off_t position, const void *buffer,
|
|||||||
memcpy(other->buffer + (newPosition - other->position),
|
memcpy(other->buffer + (newPosition - other->position),
|
||||||
buffer, *length);
|
buffer, *length);
|
||||||
|
|
||||||
fModificationTime = time(NULL);
|
fStat.st_mtime = time(NULL);
|
||||||
notify_stat_changed(SuperVolume()->id, fInodeNumber,
|
notify_stat_changed(SuperVolume()->id, fInodeNumber,
|
||||||
B_STAT_MODIFICATION_TIME);
|
B_STAT_MODIFICATION_TIME);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@@ -335,8 +370,8 @@ OverlayInode::Write(void *_cookie, off_t position, const void *buffer,
|
|||||||
|
|
||||||
bool sizeChanged = false;
|
bool sizeChanged = false;
|
||||||
off_t newEnd = newPosition + newLength;
|
off_t newEnd = newPosition + newLength;
|
||||||
if (newEnd > fCurrentNodeLength) {
|
if (newEnd > fStat.st_size) {
|
||||||
fCurrentNodeLength = newEnd;
|
fStat.st_size = newEnd;
|
||||||
sizeChanged = true;
|
sizeChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -354,10 +389,9 @@ OverlayInode::Write(void *_cookie, off_t position, const void *buffer,
|
|||||||
|
|
||||||
memcpy(element->buffer + (position - newPosition), buffer, *length);
|
memcpy(element->buffer + (position - newPosition), buffer, *length);
|
||||||
|
|
||||||
fModificationTime = time(NULL);
|
fStat.st_mtime = time(NULL);
|
||||||
notify_stat_changed(SuperVolume()->id, fInodeNumber,
|
notify_stat_changed(SuperVolume()->id, fInodeNumber,
|
||||||
B_STAT_MODIFICATION_TIME | (sizeChanged ? B_STAT_SIZE : 0));
|
B_STAT_MODIFICATION_TIME | (sizeChanged ? B_STAT_SIZE : 0));
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -613,8 +647,7 @@ static status_t
|
|||||||
overlay_write_stat(fs_volume *volume, fs_vnode *vnode, const struct stat *stat,
|
overlay_write_stat(fs_volume *volume, fs_vnode *vnode, const struct stat *stat,
|
||||||
uint32 statMask)
|
uint32 statMask)
|
||||||
{
|
{
|
||||||
OVERLAY_CALL(write_stat, stat, statMask)
|
return ((OverlayInode *)vnode->private_node)->WriteStat(stat, statMask);
|
||||||
return B_UNSUPPORTED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -974,7 +1007,7 @@ overlay_read_fs_info(fs_volume *volume, struct fs_info *info)
|
|||||||
if (result != B_OK)
|
if (result != B_OK)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
info->flags &= ~(B_FS_IS_READONLY | B_FS_IS_PERSISTENT);
|
info->flags &= ~B_FS_IS_READONLY;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user