* 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:
Oliver Tappe
2009-05-25 18:04:28 +00:00
parent 42c9b01aa6
commit 33203f677e
4 changed files with 41 additions and 18 deletions
@@ -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());
+8 -3
View File
@@ -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;