* added support for ctime to BFS by grabbing two of the pad-fields
* added TODO about a sanity check that should perhaps be dropped I checked this change with both a haiku-BFS partition and one from R5 git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30852 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -121,6 +121,8 @@ dump_inode(const bfs_inode* inode)
|
||||
inode->CreateTime() >> INODE_TIME_SHIFT);
|
||||
kprintf(" last_modified_time = %Ld (%Ld)\n", inode->LastModifiedTime(),
|
||||
inode->LastModifiedTime() >> INODE_TIME_SHIFT);
|
||||
kprintf(" status_change_time = %Ld (%Ld)\n", inode->StatusChangeTime(),
|
||||
inode->StatusChangeTime() >> INODE_TIME_SHIFT);
|
||||
dump_block_run( " parent = ", inode->parent);
|
||||
dump_block_run( " attributes = ", inode->attributes);
|
||||
kprintf(" type = %u\n", (unsigned)inode->Type());
|
||||
|
||||
@@ -395,6 +395,7 @@ Inode::Inode(Volume* volume, Transaction& transaction, ino_t id, mode_t mode,
|
||||
| (volume->GetUniqueID() & INODE_TIME_MASK));
|
||||
// we use Volume::GetUniqueID() to avoid having too many duplicates
|
||||
// in the last_modified index
|
||||
Node().status_change_time = HOST_ENDIAN_TO_BFS_INT64(Node().create_time);
|
||||
|
||||
Node().inode_size = HOST_ENDIAN_TO_BFS_INT32(volume->InodeSize());
|
||||
|
||||
|
||||
@@ -188,7 +188,8 @@ struct bfs_inode {
|
||||
data_stream data;
|
||||
char short_symlink[SHORT_SYMLINK_NAME_LENGTH];
|
||||
};
|
||||
int32 pad[4];
|
||||
bigtime_t status_change_time;
|
||||
int32 pad[2];
|
||||
// we use this member as a doubly linked list link
|
||||
|
||||
small_data small_data_start[0];
|
||||
@@ -200,9 +201,13 @@ struct bfs_inode {
|
||||
int32 Flags() const { return BFS_ENDIAN_TO_HOST_INT32(flags); }
|
||||
int32 Type() const { return BFS_ENDIAN_TO_HOST_INT32(type); }
|
||||
int32 InodeSize() const { return BFS_ENDIAN_TO_HOST_INT32(inode_size); }
|
||||
bigtime_t LastModifiedTime() const { return BFS_ENDIAN_TO_HOST_INT64(last_modified_time); }
|
||||
bigtime_t CreateTime() const { return BFS_ENDIAN_TO_HOST_INT64(create_time); }
|
||||
bigtime_t LastModifiedTime() const {
|
||||
return BFS_ENDIAN_TO_HOST_INT64(last_modified_time); }
|
||||
bigtime_t CreateTime() const {
|
||||
return BFS_ENDIAN_TO_HOST_INT64(create_time); }
|
||||
small_data *SmallDataStart() { return small_data_start; }
|
||||
bigtime_t StatusChangeTime() const {
|
||||
return BFS_ENDIAN_TO_HOST_INT64(status_change_time); }
|
||||
|
||||
status_t InitCheck(Volume *volume);
|
||||
// defined in Inode.cpp
|
||||
|
||||
@@ -47,9 +47,22 @@ fill_stat_buffer(Inode* inode, struct stat& stat)
|
||||
stat.st_type = node.Type();
|
||||
|
||||
stat.st_atime = time(NULL);
|
||||
stat.st_mtime = stat.st_ctime = (time_t)(node.LastModifiedTime() >> INODE_TIME_SHIFT);
|
||||
stat.st_mtime = (time_t)(node.LastModifiedTime() >> INODE_TIME_SHIFT);
|
||||
stat.st_crtime = (time_t)(node.CreateTime() >> INODE_TIME_SHIFT);
|
||||
|
||||
// if on-disk ctime is invalid (pointer value from previous [ab]use of
|
||||
// the first 4 bytes) or 0, fall back to mtime:
|
||||
// N.B.: This has the drawback that explicitly setting a ctime of 0
|
||||
// will not work, but I suppose no one will do that, since ctime
|
||||
// is usually just set to the current time whenever something happens
|
||||
// to the inode.
|
||||
// TODO: find out if this sanity check should be dropped!
|
||||
bigtime_t ctime = node.StatusChangeTime();
|
||||
if (((uint64)ctime & 0xFFFF00000000FFFFULL) != 0 || ctime == 0)
|
||||
stat.st_ctime = stat.st_mtime;
|
||||
else
|
||||
stat.st_ctime = (time_t)(ctime >> INODE_TIME_SHIFT);
|
||||
|
||||
if (inode->IsSymLink() && (inode->Flags() & INODE_LONG_SYMLINK) == 0) {
|
||||
// symlinks report the size of the link here
|
||||
stat.st_size = strlen(node.short_symlink);
|
||||
@@ -772,9 +785,6 @@ bfs_write_stat(fs_volume* _volume, fs_vnode* _node, const struct stat* stat,
|
||||
}
|
||||
}
|
||||
|
||||
// Note, the following changes (mode/uid/gid) would update st_ctime;
|
||||
// since we don't have that, we'll use st_mtime instead.
|
||||
|
||||
if ((mask & B_STAT_MODE) != 0) {
|
||||
PRINT(("original mode = %ld, stat->st_mode = %d\n", node.Mode(), stat->st_mode));
|
||||
node.mode = HOST_ENDIAN_TO_BFS_INT32((node.Mode() & ~S_IUMSK)
|
||||
@@ -791,26 +801,31 @@ bfs_write_stat(fs_volume* _volume, fs_vnode* _node, const struct stat* stat,
|
||||
updateTime = true;
|
||||
}
|
||||
|
||||
if ((mask & B_STAT_MODIFICATION_TIME) != 0 || updateTime) {
|
||||
bigtime_t newTime;
|
||||
if ((mask & B_STAT_MODIFICATION_TIME) == 0)
|
||||
newTime = (bigtime_t)time(NULL) << INODE_TIME_SHIFT;
|
||||
else
|
||||
newTime = (bigtime_t)stat->st_mtime << INODE_TIME_SHIFT;
|
||||
|
||||
if ((mask & B_STAT_MODIFICATION_TIME) != 0) {
|
||||
if (!inode->InLastModifiedIndex()) {
|
||||
// directory modification times are not part of the index
|
||||
node.last_modified_time = HOST_ENDIAN_TO_BFS_INT64(newTime);
|
||||
node.last_modified_time = HOST_ENDIAN_TO_BFS_INT64(
|
||||
(bigtime_t)stat->st_mtime << INODE_TIME_SHIFT);
|
||||
} else if (!inode->IsDeleted()) {
|
||||
// Index::UpdateLastModified() will set the new time in the inode
|
||||
Index index(volume);
|
||||
index.UpdateLastModified(transaction, inode, newTime);
|
||||
index.UpdateLastModified(transaction, inode,
|
||||
(bigtime_t)stat->st_mtime << INODE_TIME_SHIFT);
|
||||
}
|
||||
}
|
||||
if ((mask & B_STAT_CREATION_TIME) != 0) {
|
||||
node.create_time = HOST_ENDIAN_TO_BFS_INT64(
|
||||
(bigtime_t)stat->st_crtime << INODE_TIME_SHIFT);
|
||||
}
|
||||
if ((mask & B_STAT_CHANGE_TIME) != 0 || updateTime) {
|
||||
bigtime_t newTime;
|
||||
if ((mask & B_STAT_CHANGE_TIME) == 0)
|
||||
newTime = (bigtime_t)time(NULL);
|
||||
else
|
||||
newTime = (bigtime_t)stat->st_ctime;
|
||||
node.status_change_time
|
||||
= HOST_ENDIAN_TO_BFS_INT64(newTime << INODE_TIME_SHIFT);
|
||||
}
|
||||
|
||||
status = inode->WriteBack(transaction);
|
||||
if (status == B_OK)
|
||||
@@ -2032,8 +2047,8 @@ bfs_stat_index(fs_volume* _volume, const char* name, struct stat* stat)
|
||||
stat->st_gid = node.GroupID();
|
||||
|
||||
stat->st_atime = time(NULL);
|
||||
stat->st_mtime = stat->st_ctime
|
||||
= (time_t)(node.LastModifiedTime() >> INODE_TIME_SHIFT);
|
||||
stat->st_mtime = (time_t)(node.LastModifiedTime() >> INODE_TIME_SHIFT);
|
||||
stat->st_ctime = (time_t)(node.StatusChangeTime() >> INODE_TIME_SHIFT);
|
||||
stat->st_crtime = (time_t)(node.CreateTime() >> INODE_TIME_SHIFT);
|
||||
|
||||
return B_OK;
|
||||
|
||||
Reference in New Issue
Block a user