* Cleanup of how the time is converted between bfs_inode and the outside world:
there is now a couple of conversion functions, and I changed the type from bigtime_t to int64, as it's not what a bigtime_t would usually contain, but some shift magic in order to make duplicate index entries less likely. * We now correctly fill in the timespec in struct stat as good as possible; the 12 of the 16 possible bits are used for the nano second value. The lower 8 bits are used to avoid the duplicate index entries. Only if the nano second time is 0, the lower 12 bits are used to achieve that. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31057 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -117,12 +117,15 @@ dump_inode(const bfs_inode* inode)
|
|||||||
kprintf(" gid = %u\n", (unsigned)inode->GroupID());
|
kprintf(" gid = %u\n", (unsigned)inode->GroupID());
|
||||||
kprintf(" mode = %08x\n", (int)inode->Mode());
|
kprintf(" mode = %08x\n", (int)inode->Mode());
|
||||||
kprintf(" flags = %08x\n", (int)inode->Flags());
|
kprintf(" flags = %08x\n", (int)inode->Flags());
|
||||||
kprintf(" create_time = %Ld (%Ld)\n", inode->CreateTime(),
|
kprintf(" create_time = %llx (%ld.%u)\n", inode->CreateTime(),
|
||||||
inode->CreateTime() >> INODE_TIME_SHIFT);
|
bfs_inode::ToSecs(inode->CreateTime()),
|
||||||
kprintf(" last_modified_time = %Ld (%Ld)\n", inode->LastModifiedTime(),
|
(unsigned)bfs_inode::ToUsecs(inode->CreateTime()));
|
||||||
inode->LastModifiedTime() >> INODE_TIME_SHIFT);
|
kprintf(" last_modified_time = %llx (%ld.%u)\n", inode->LastModifiedTime(),
|
||||||
kprintf(" status_change_time = %Ld (%Ld)\n", inode->StatusChangeTime(),
|
bfs_inode::ToSecs(inode->LastModifiedTime()),
|
||||||
inode->StatusChangeTime() >> INODE_TIME_SHIFT);
|
(unsigned)bfs_inode::ToUsecs(inode->LastModifiedTime()));
|
||||||
|
kprintf(" status_change_time = %llx (%ld.%u)\n", inode->StatusChangeTime(),
|
||||||
|
bfs_inode::ToSecs(inode->StatusChangeTime()),
|
||||||
|
(unsigned)bfs_inode::ToUsecs(inode->StatusChangeTime()));
|
||||||
dump_block_run( " parent = ", inode->parent);
|
dump_block_run( " parent = ", inode->parent);
|
||||||
dump_block_run( " attributes = ", inode->attributes);
|
dump_block_run( " attributes = ", inode->attributes);
|
||||||
kprintf(" type = %u\n", (unsigned)inode->Type());
|
kprintf(" type = %u\n", (unsigned)inode->Type());
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2001-2008, Axel Dörfler, [email protected].
|
* Copyright 2001-2009, Axel Dörfler, [email protected].
|
||||||
* This file may be used under the terms of the MIT License.
|
* This file may be used under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -390,9 +390,7 @@ Index::UpdateLastModified(Transaction &transaction, Inode* inode,
|
|||||||
|
|
||||||
bigtime_t oldModified = inode->OldLastModified();
|
bigtime_t oldModified = inode->OldLastModified();
|
||||||
if (modified == -1)
|
if (modified == -1)
|
||||||
modified = (bigtime_t)time(NULL) << INODE_TIME_SHIFT;
|
modified = bfs_inode::ToInode(real_time_clock_usecs());
|
||||||
modified &= ~INODE_TIME_MASK;
|
|
||||||
modified |= fVolume->GetUniqueID() & INODE_TIME_MASK;
|
|
||||||
|
|
||||||
status_t status = Update(transaction, "last_modified", B_INT64_TYPE,
|
status_t status = Update(transaction, "last_modified", B_INT64_TYPE,
|
||||||
(uint8*)&oldModified, sizeof(int64), (uint8*)&modified,
|
(uint8*)&oldModified, sizeof(int64), (uint8*)&modified,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2001-2008, Axel Dörfler, [email protected].
|
* Copyright 2001-2009, Axel Dörfler, [email protected].
|
||||||
* This file may be used under the terms of the MIT License.
|
* This file may be used under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -389,13 +389,8 @@ Inode::Inode(Volume* volume, Transaction& transaction, ino_t id, mode_t mode,
|
|||||||
Node().mode = HOST_ENDIAN_TO_BFS_INT32(mode);
|
Node().mode = HOST_ENDIAN_TO_BFS_INT32(mode);
|
||||||
Node().flags = HOST_ENDIAN_TO_BFS_INT32(INODE_IN_USE);
|
Node().flags = HOST_ENDIAN_TO_BFS_INT32(INODE_IN_USE);
|
||||||
|
|
||||||
Node().create_time = HOST_ENDIAN_TO_BFS_INT64((bigtime_t)time(NULL)
|
Node().create_time = Node().last_modified_time = Node().status_change_time
|
||||||
<< INODE_TIME_SHIFT);
|
= HOST_ENDIAN_TO_BFS_INT64(bfs_inode::ToInode(real_time_clock_usecs()));
|
||||||
Node().last_modified_time = HOST_ENDIAN_TO_BFS_INT64(Node().create_time
|
|
||||||
| (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());
|
Node().inode_size = HOST_ENDIAN_TO_BFS_INT32(volume->InodeSize());
|
||||||
|
|
||||||
@@ -1468,8 +1463,8 @@ Inode::WriteAt(Transaction& transaction, off_t pos, const uint8* buffer,
|
|||||||
// update the last modification time in memory, it will be written
|
// update the last modification time in memory, it will be written
|
||||||
// back to the inode, and the index when the file is closed
|
// back to the inode, and the index when the file is closed
|
||||||
// TODO: should update the internal last modified time only at this point!
|
// TODO: should update the internal last modified time only at this point!
|
||||||
Node().last_modified_time = HOST_ENDIAN_TO_BFS_INT64((bigtime_t)time(NULL)
|
Node().last_modified_time
|
||||||
<< INODE_TIME_SHIFT);
|
= HOST_ENDIAN_TO_BFS_INT64(bfs_inode::ToInode(real_time_clock_usecs()));
|
||||||
|
|
||||||
// TODO: support INODE_LOGGED!
|
// TODO: support INODE_LOGGED!
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2001-2008, Axel Dörfler, axeld@pinc-software.de.
|
* Copyright 2001-2009, Axel Dörfler, axeld@pinc-software.de.
|
||||||
* This file may be used under the terms of the MIT License.
|
* This file may be used under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -279,7 +279,6 @@ Volume::Volume(fs_volume* volume)
|
|||||||
fRootNode(NULL),
|
fRootNode(NULL),
|
||||||
fIndicesNode(NULL),
|
fIndicesNode(NULL),
|
||||||
fDirtyCachedBlocks(0),
|
fDirtyCachedBlocks(0),
|
||||||
fUniqueID(0),
|
|
||||||
fFlags(0),
|
fFlags(0),
|
||||||
fCheckingThread(-1)
|
fCheckingThread(-1)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -126,8 +126,6 @@ public:
|
|||||||
|
|
||||||
void* BlockCache() { return fBlockCache; }
|
void* BlockCache() { return fBlockCache; }
|
||||||
|
|
||||||
uint32 GetUniqueID();
|
|
||||||
|
|
||||||
static status_t CheckSuperBlock(const uint8* data,
|
static status_t CheckSuperBlock(const uint8* data,
|
||||||
uint32* _offset = NULL);
|
uint32* _offset = NULL);
|
||||||
static status_t Identify(int fd, disk_super_block* superBlock);
|
static status_t Identify(int fd, disk_super_block* superBlock);
|
||||||
@@ -155,7 +153,6 @@ protected:
|
|||||||
mutex fQueryLock;
|
mutex fQueryLock;
|
||||||
SinglyLinkedList<Query> fQueries;
|
SinglyLinkedList<Query> fQueries;
|
||||||
|
|
||||||
int32 fUniqueID;
|
|
||||||
uint32 fFlags;
|
uint32 fFlags;
|
||||||
|
|
||||||
void* fBlockCache;
|
void* fBlockCache;
|
||||||
@@ -226,10 +223,4 @@ Volume::GetJournal(off_t /*refBlock*/) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline uint32
|
|
||||||
Volume::GetUniqueID()
|
|
||||||
{
|
|
||||||
return atomic_add(&fUniqueID, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // VOLUME_H
|
#endif // VOLUME_H
|
||||||
|
|||||||
@@ -28,7 +28,8 @@ struct block_run {
|
|||||||
uint16 start;
|
uint16 start;
|
||||||
uint16 length;
|
uint16 length;
|
||||||
|
|
||||||
int32 AllocationGroup() const { return BFS_ENDIAN_TO_HOST_INT32(allocation_group); }
|
int32 AllocationGroup() const
|
||||||
|
{ return BFS_ENDIAN_TO_HOST_INT32(allocation_group); }
|
||||||
uint16 Start() const { return BFS_ENDIAN_TO_HOST_INT16(start); }
|
uint16 Start() const { return BFS_ENDIAN_TO_HOST_INT16(start); }
|
||||||
uint16 Length() const { return BFS_ENDIAN_TO_HOST_INT16(length); }
|
uint16 Length() const { return BFS_ENDIAN_TO_HOST_INT16(length); }
|
||||||
|
|
||||||
@@ -87,9 +88,11 @@ struct disk_super_block {
|
|||||||
off_t NumBlocks() const { return BFS_ENDIAN_TO_HOST_INT64(num_blocks); }
|
off_t NumBlocks() const { return BFS_ENDIAN_TO_HOST_INT64(num_blocks); }
|
||||||
off_t UsedBlocks() const { return BFS_ENDIAN_TO_HOST_INT64(used_blocks); }
|
off_t UsedBlocks() const { return BFS_ENDIAN_TO_HOST_INT64(used_blocks); }
|
||||||
int32 InodeSize() const { return BFS_ENDIAN_TO_HOST_INT32(inode_size); }
|
int32 InodeSize() const { return BFS_ENDIAN_TO_HOST_INT32(inode_size); }
|
||||||
int32 BlocksPerAllocationGroup() const { return BFS_ENDIAN_TO_HOST_INT32(blocks_per_ag); }
|
int32 BlocksPerAllocationGroup() const
|
||||||
|
{ return BFS_ENDIAN_TO_HOST_INT32(blocks_per_ag); }
|
||||||
int32 AllocationGroups() const { return BFS_ENDIAN_TO_HOST_INT32(num_ags); }
|
int32 AllocationGroups() const { return BFS_ENDIAN_TO_HOST_INT32(num_ags); }
|
||||||
int32 AllocationGroupShift() const { return BFS_ENDIAN_TO_HOST_INT32(ag_shift); }
|
int32 AllocationGroupShift() const
|
||||||
|
{ return BFS_ENDIAN_TO_HOST_INT32(ag_shift); }
|
||||||
int32 Flags() const { return BFS_ENDIAN_TO_HOST_INT32(flags); }
|
int32 Flags() const { return BFS_ENDIAN_TO_HOST_INT32(flags); }
|
||||||
off_t LogStart() const { return BFS_ENDIAN_TO_HOST_INT64(log_start); }
|
off_t LogStart() const { return BFS_ENDIAN_TO_HOST_INT64(log_start); }
|
||||||
off_t LogEnd() const { return BFS_ENDIAN_TO_HOST_INT64(log_end); }
|
off_t LogEnd() const { return BFS_ENDIAN_TO_HOST_INT64(log_end); }
|
||||||
@@ -121,10 +124,14 @@ struct data_stream {
|
|||||||
off_t max_double_indirect_range;
|
off_t max_double_indirect_range;
|
||||||
off_t size;
|
off_t size;
|
||||||
|
|
||||||
off_t MaxDirectRange() const { return BFS_ENDIAN_TO_HOST_INT64(max_direct_range); }
|
off_t MaxDirectRange() const
|
||||||
off_t MaxIndirectRange() const { return BFS_ENDIAN_TO_HOST_INT64(max_indirect_range); }
|
{ return BFS_ENDIAN_TO_HOST_INT64(max_direct_range); }
|
||||||
off_t MaxDoubleIndirectRange() const { return BFS_ENDIAN_TO_HOST_INT64(max_double_indirect_range); }
|
off_t MaxIndirectRange() const
|
||||||
off_t Size() const { return BFS_ENDIAN_TO_HOST_INT64(size); }
|
{ return BFS_ENDIAN_TO_HOST_INT64(max_indirect_range); }
|
||||||
|
off_t MaxDoubleIndirectRange() const
|
||||||
|
{ return BFS_ENDIAN_TO_HOST_INT64(max_double_indirect_range); }
|
||||||
|
off_t Size() const
|
||||||
|
{ return BFS_ENDIAN_TO_HOST_INT64(size); }
|
||||||
} _PACKED;
|
} _PACKED;
|
||||||
|
|
||||||
// This defines the size of the indirect and double indirect
|
// This defines the size of the indirect and double indirect
|
||||||
@@ -168,6 +175,13 @@ class Volume;
|
|||||||
#define SHORT_SYMLINK_NAME_LENGTH 144
|
#define SHORT_SYMLINK_NAME_LENGTH 144
|
||||||
// length incl. terminating '\0'
|
// length incl. terminating '\0'
|
||||||
|
|
||||||
|
#define INODE_MAGIC1 0x3bbe0ad9
|
||||||
|
#define INODE_FILE_NAME_LENGTH 256
|
||||||
|
#define INODE_TIME_SHIFT 16
|
||||||
|
#define INODE_TIME_MASK 0xffff
|
||||||
|
|
||||||
|
inline uint32 unique_from_nsec(uint32 time);
|
||||||
|
|
||||||
struct bfs_inode {
|
struct bfs_inode {
|
||||||
int32 magic1;
|
int32 magic1;
|
||||||
inode_addr inode_num;
|
inode_addr inode_num;
|
||||||
@@ -175,8 +189,8 @@ struct bfs_inode {
|
|||||||
int32 gid;
|
int32 gid;
|
||||||
int32 mode; // see sys/stat.h
|
int32 mode; // see sys/stat.h
|
||||||
int32 flags;
|
int32 flags;
|
||||||
bigtime_t create_time;
|
int64 create_time;
|
||||||
bigtime_t last_modified_time;
|
int64 last_modified_time;
|
||||||
inode_addr parent;
|
inode_addr parent;
|
||||||
inode_addr attributes;
|
inode_addr attributes;
|
||||||
uint32 type; // attribute type
|
uint32 type; // attribute type
|
||||||
@@ -201,22 +215,29 @@ struct bfs_inode {
|
|||||||
int32 Flags() const { return BFS_ENDIAN_TO_HOST_INT32(flags); }
|
int32 Flags() const { return BFS_ENDIAN_TO_HOST_INT32(flags); }
|
||||||
int32 Type() const { return BFS_ENDIAN_TO_HOST_INT32(type); }
|
int32 Type() const { return BFS_ENDIAN_TO_HOST_INT32(type); }
|
||||||
int32 InodeSize() const { return BFS_ENDIAN_TO_HOST_INT32(inode_size); }
|
int32 InodeSize() const { return BFS_ENDIAN_TO_HOST_INT32(inode_size); }
|
||||||
bigtime_t LastModifiedTime() const {
|
int64 LastModifiedTime() const
|
||||||
return BFS_ENDIAN_TO_HOST_INT64(last_modified_time); }
|
{ return BFS_ENDIAN_TO_HOST_INT64(last_modified_time); }
|
||||||
bigtime_t CreateTime() const {
|
int64 CreateTime() const
|
||||||
return BFS_ENDIAN_TO_HOST_INT64(create_time); }
|
{ return BFS_ENDIAN_TO_HOST_INT64(create_time); }
|
||||||
small_data *SmallDataStart() { return small_data_start; }
|
int64 StatusChangeTime() const
|
||||||
bigtime_t StatusChangeTime() const {
|
{ return BFS_ENDIAN_TO_HOST_INT64(status_change_time); }
|
||||||
return BFS_ENDIAN_TO_HOST_INT64(status_change_time); }
|
small_data* SmallDataStart() { return small_data_start; }
|
||||||
|
|
||||||
status_t InitCheck(Volume *volume);
|
status_t InitCheck(Volume *volume);
|
||||||
// defined in Inode.cpp
|
// defined in Inode.cpp
|
||||||
} _PACKED;
|
|
||||||
|
|
||||||
#define INODE_MAGIC1 0x3bbe0ad9
|
static int64 ToInode(bigtime_t time)
|
||||||
#define INODE_TIME_SHIFT 16
|
{ return ((time / 1000000) << INODE_TIME_SHIFT)
|
||||||
#define INODE_TIME_MASK 0xffff
|
+ unique_from_nsec((time % 1000000) * 1000); }
|
||||||
#define INODE_FILE_NAME_LENGTH 256
|
static int64 ToInode(const timespec& tv)
|
||||||
|
{ return ((int64)tv.tv_sec << INODE_TIME_SHIFT)
|
||||||
|
+ unique_from_nsec(tv.tv_nsec); }
|
||||||
|
|
||||||
|
static time_t ToSecs(bigtime_t time)
|
||||||
|
{ return time >> INODE_TIME_SHIFT; }
|
||||||
|
static uint32 ToUsecs(bigtime_t time)
|
||||||
|
{ return (time & INODE_TIME_MASK) << 14; }
|
||||||
|
} _PACKED;
|
||||||
|
|
||||||
enum inode_flags {
|
enum inode_flags {
|
||||||
INODE_IN_USE = 0x00000001, // always set
|
INODE_IN_USE = 0x00000001, // always set
|
||||||
@@ -235,6 +256,7 @@ enum inode_flags {
|
|||||||
INODE_DONT_FREE_SPACE = 0x00080000
|
INODE_DONT_FREE_SPACE = 0x00080000
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//**************************************
|
//**************************************
|
||||||
|
|
||||||
struct file_cookie {
|
struct file_cookie {
|
||||||
@@ -252,6 +274,24 @@ struct file_cookie {
|
|||||||
//**************************************
|
//**************************************
|
||||||
|
|
||||||
|
|
||||||
|
/*! Converts the nano seconds given to the internal 16 bit resolution that
|
||||||
|
BFS uses. If \a time is zero, 12 bits will get a monotonically increasing
|
||||||
|
number. For all other values, only the lower 4 bits are changed this way.
|
||||||
|
|
||||||
|
This is done to decrease the number of duplicate time values, which speeds
|
||||||
|
up the way BFS handles the time indices.
|
||||||
|
*/
|
||||||
|
inline uint32
|
||||||
|
unique_from_nsec(uint32 time)
|
||||||
|
{
|
||||||
|
static vint32 number;
|
||||||
|
if (time != 0)
|
||||||
|
return ((time >> 14) & INODE_TIME_MASK) | (++number & 0xf);
|
||||||
|
|
||||||
|
return ++number & 0xfff;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline int32
|
inline int32
|
||||||
divide_roundup(int32 num,int32 divisor)
|
divide_roundup(int32 num,int32 divisor)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2001-2008, Axel Dörfler, axeld@pinc-software.de.
|
* Copyright 2001-2009, Axel Dörfler, axeld@pinc-software.de.
|
||||||
* This file may be used under the terms of the MIT License.
|
* This file may be used under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -31,6 +31,34 @@ struct identify_cookie {
|
|||||||
extern void fill_stat_buffer(Inode* inode, struct stat& stat);
|
extern void fill_stat_buffer(Inode* inode, struct stat& stat);
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
fill_stat_time(const bfs_inode& node, struct stat& stat)
|
||||||
|
{
|
||||||
|
stat.st_atim.tv_sec = real_time_clock();
|
||||||
|
stat.st_atim.tv_nsec = real_time_clock_usecs() % 1000000;
|
||||||
|
|
||||||
|
stat.st_mtim.tv_sec = bfs_inode::ToSecs(node.LastModifiedTime());
|
||||||
|
stat.st_mtim.tv_nsec = bfs_inode::ToUsecs(node.LastModifiedTime());
|
||||||
|
stat.st_crtim.tv_sec = bfs_inode::ToSecs(node.CreateTime());
|
||||||
|
stat.st_crtim.tv_nsec = bfs_inode::ToUsecs(node.CreateTime());
|
||||||
|
|
||||||
|
// 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 changeTime = node.StatusChangeTime();
|
||||||
|
if (((uint64)changeTime & 0xFFFF00000000FFFFULL) != 0 || changeTime == 0)
|
||||||
|
stat.st_ctim = stat.st_mtim;
|
||||||
|
else {
|
||||||
|
stat.st_ctim.tv_sec = bfs_inode::ToSecs(changeTime);
|
||||||
|
stat.st_ctim.tv_nsec = bfs_inode::ToUsecs(changeTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
fill_stat_buffer(Inode* inode, struct stat& stat)
|
fill_stat_buffer(Inode* inode, struct stat& stat)
|
||||||
{
|
{
|
||||||
@@ -46,22 +74,7 @@ fill_stat_buffer(Inode* inode, struct stat& stat)
|
|||||||
stat.st_mode = node.Mode();
|
stat.st_mode = node.Mode();
|
||||||
stat.st_type = node.Type();
|
stat.st_type = node.Type();
|
||||||
|
|
||||||
stat.st_atime = time(NULL);
|
fill_stat_time(node, stat);
|
||||||
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) {
|
if (inode->IsSymLink() && (inode->Flags() & INODE_LONG_SYMLINK) == 0) {
|
||||||
// symlinks report the size of the link here
|
// symlinks report the size of the link here
|
||||||
@@ -786,7 +799,8 @@ bfs_write_stat(fs_volume* _volume, fs_vnode* _node, const struct stat* stat,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((mask & B_STAT_MODE) != 0) {
|
if ((mask & B_STAT_MODE) != 0) {
|
||||||
PRINT(("original mode = %ld, stat->st_mode = %d\n", node.Mode(), stat->st_mode));
|
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)
|
node.mode = HOST_ENDIAN_TO_BFS_INT32((node.Mode() & ~S_IUMSK)
|
||||||
| (stat->st_mode & S_IUMSK));
|
| (stat->st_mode & S_IUMSK));
|
||||||
updateTime = true;
|
updateTime = true;
|
||||||
@@ -804,27 +818,27 @@ bfs_write_stat(fs_volume* _volume, fs_vnode* _node, const struct stat* stat,
|
|||||||
if ((mask & B_STAT_MODIFICATION_TIME) != 0) {
|
if ((mask & B_STAT_MODIFICATION_TIME) != 0) {
|
||||||
if (!inode->InLastModifiedIndex()) {
|
if (!inode->InLastModifiedIndex()) {
|
||||||
// directory modification times are not part of the index
|
// directory modification times are not part of the index
|
||||||
node.last_modified_time = HOST_ENDIAN_TO_BFS_INT64(
|
node.last_modified_time
|
||||||
(bigtime_t)stat->st_mtime << INODE_TIME_SHIFT);
|
= HOST_ENDIAN_TO_BFS_INT64(bfs_inode::ToInode(stat->st_mtim));
|
||||||
} else if (!inode->IsDeleted()) {
|
} else if (!inode->IsDeleted()) {
|
||||||
// Index::UpdateLastModified() will set the new time in the inode
|
// Index::UpdateLastModified() will set the new time in the inode
|
||||||
Index index(volume);
|
Index index(volume);
|
||||||
index.UpdateLastModified(transaction, inode,
|
index.UpdateLastModified(transaction, inode,
|
||||||
(bigtime_t)stat->st_mtime << INODE_TIME_SHIFT);
|
bfs_inode::ToInode(stat->st_mtim));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((mask & B_STAT_CREATION_TIME) != 0) {
|
if ((mask & B_STAT_CREATION_TIME) != 0) {
|
||||||
node.create_time = HOST_ENDIAN_TO_BFS_INT64(
|
node.create_time
|
||||||
(bigtime_t)stat->st_crtime << INODE_TIME_SHIFT);
|
= HOST_ENDIAN_TO_BFS_INT64(bfs_inode::ToInode(stat->st_crtim));
|
||||||
}
|
}
|
||||||
if ((mask & B_STAT_CHANGE_TIME) != 0 || updateTime) {
|
if ((mask & B_STAT_CHANGE_TIME) != 0 || updateTime) {
|
||||||
bigtime_t newTime;
|
bigtime_t newTime;
|
||||||
if ((mask & B_STAT_CHANGE_TIME) == 0)
|
if ((mask & B_STAT_CHANGE_TIME) == 0)
|
||||||
newTime = (bigtime_t)time(NULL);
|
newTime = bfs_inode::ToInode(real_time_clock_usecs());
|
||||||
else
|
else
|
||||||
newTime = (bigtime_t)stat->st_ctime;
|
newTime = bfs_inode::ToInode(stat->st_ctim);
|
||||||
node.status_change_time
|
|
||||||
= HOST_ENDIAN_TO_BFS_INT64(newTime << INODE_TIME_SHIFT);
|
node.status_change_time = HOST_ENDIAN_TO_BFS_INT64(newTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
status = inode->WriteBack(transaction);
|
status = inode->WriteBack(transaction);
|
||||||
@@ -841,7 +855,8 @@ status_t
|
|||||||
bfs_create(fs_volume* _volume, fs_vnode* _directory, const char* name,
|
bfs_create(fs_volume* _volume, fs_vnode* _directory, const char* name,
|
||||||
int openMode, int mode, void** _cookie, ino_t* _vnodeID)
|
int openMode, int mode, void** _cookie, ino_t* _vnodeID)
|
||||||
{
|
{
|
||||||
FUNCTION_START(("name = \"%s\", perms = %d, openMode = %d\n", name, mode, openMode));
|
FUNCTION_START(("name = \"%s\", perms = %d, openMode = %d\n", name, mode,
|
||||||
|
openMode));
|
||||||
|
|
||||||
Volume* volume = (Volume*)_volume->private_volume;
|
Volume* volume = (Volume*)_volume->private_volume;
|
||||||
Inode* directory = (Inode*)_directory->private_node;
|
Inode* directory = (Inode*)_directory->private_node;
|
||||||
@@ -2037,19 +2052,18 @@ bfs_stat_index(fs_volume* _volume, const char* name, struct stat* stat)
|
|||||||
bfs_inode& node = index.Node()->Node();
|
bfs_inode& node = index.Node()->Node();
|
||||||
|
|
||||||
stat->st_type = index.Type();
|
stat->st_type = index.Type();
|
||||||
stat->st_size = node.data.Size();
|
|
||||||
stat->st_mode = node.Mode();
|
stat->st_mode = node.Mode();
|
||||||
|
|
||||||
|
stat->st_size = node.data.Size();
|
||||||
|
stat->st_blocks = index.Node()->AllocatedSize() / 512;
|
||||||
|
|
||||||
stat->st_nlink = 1;
|
stat->st_nlink = 1;
|
||||||
stat->st_blksize = 65536;
|
stat->st_blksize = 65536;
|
||||||
|
|
||||||
stat->st_uid = node.UserID();
|
stat->st_uid = node.UserID();
|
||||||
stat->st_gid = node.GroupID();
|
stat->st_gid = node.GroupID();
|
||||||
|
|
||||||
stat->st_atime = time(NULL);
|
fill_stat_time(node, *stat);
|
||||||
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;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user