* Somehow I forgot to update the parent directory's time stamps on file
creation, removal, and name changes... git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32157 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1311,6 +1311,18 @@ Inode::IsEmpty()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
Inode::ContainerContentsChanged(Transaction& transaction)
|
||||||
|
{
|
||||||
|
ASSERT(!InLastModifiedIndex());
|
||||||
|
|
||||||
|
Node().last_modified_time = Node().status_change_time
|
||||||
|
= HOST_ENDIAN_TO_BFS_INT64(bfs_inode::ToInode(real_time_clock_usecs()));
|
||||||
|
|
||||||
|
return WriteBack(transaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - data stream
|
// #pragma mark - data stream
|
||||||
|
|
||||||
|
|
||||||
@@ -2397,6 +2409,8 @@ Inode::Remove(Transaction& transaction, const char* name, ino_t* _id,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
ContainerContentsChanged(transaction);
|
||||||
|
|
||||||
// update the inode, so that no one will ever doubt it's deleted :-)
|
// update the inode, so that no one will ever doubt it's deleted :-)
|
||||||
inode->Node().flags |= HOST_ENDIAN_TO_BFS_INT32(INODE_DELETED);
|
inode->Node().flags |= HOST_ENDIAN_TO_BFS_INT32(INODE_DELETED);
|
||||||
inode->Node().flags &= ~HOST_ENDIAN_TO_BFS_INT32(INODE_IN_USE);
|
inode->Node().flags &= ~HOST_ENDIAN_TO_BFS_INT32(INODE_IN_USE);
|
||||||
@@ -2447,7 +2461,7 @@ Inode::Create(Transaction& transaction, Inode* parent, const char* name,
|
|||||||
Volume* volume = transaction.GetVolume();
|
Volume* volume = transaction.GetVolume();
|
||||||
BPlusTree* tree = NULL;
|
BPlusTree* tree = NULL;
|
||||||
|
|
||||||
if (parent && (mode & S_ATTR_DIR) == 0 && parent->IsContainer()) {
|
if (parent != NULL && (mode & S_ATTR_DIR) == 0 && parent->IsContainer()) {
|
||||||
// check if the file already exists in the directory
|
// check if the file already exists in the directory
|
||||||
if (parent->GetTree(&tree) != B_OK)
|
if (parent->GetTree(&tree) != B_OK)
|
||||||
RETURN_ERROR(B_BAD_VALUE);
|
RETURN_ERROR(B_BAD_VALUE);
|
||||||
@@ -2479,7 +2493,7 @@ Inode::Create(Transaction& transaction, Inode* parent, const char* name,
|
|||||||
Vnode vnode(volume, offset);
|
Vnode vnode(volume, offset);
|
||||||
Inode* inode;
|
Inode* inode;
|
||||||
status_t status = vnode.Get(&inode);
|
status_t status = vnode.Get(&inode);
|
||||||
if (status < B_OK) {
|
if (status != B_OK) {
|
||||||
REPORT_ERROR(status);
|
REPORT_ERROR(status);
|
||||||
return B_ENTRY_NOT_FOUND;
|
return B_ENTRY_NOT_FOUND;
|
||||||
}
|
}
|
||||||
@@ -2492,7 +2506,7 @@ Inode::Create(Transaction& transaction, Inode* parent, const char* name,
|
|||||||
if (inode->CheckPermissions(open_mode_to_access(openMode)) != B_OK)
|
if (inode->CheckPermissions(open_mode_to_access(openMode)) != B_OK)
|
||||||
return B_NOT_ALLOWED;
|
return B_NOT_ALLOWED;
|
||||||
|
|
||||||
if (openMode & O_TRUNC) {
|
if ((openMode & O_TRUNC) != 0) {
|
||||||
// we need write access in order to truncate the file
|
// we need write access in order to truncate the file
|
||||||
status = inode->CheckPermissions(W_OK);
|
status = inode->CheckPermissions(W_OK);
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
@@ -2523,7 +2537,7 @@ Inode::Create(Transaction& transaction, Inode* parent, const char* name,
|
|||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
} else if (parent && (mode & S_ATTR_DIR) == 0)
|
} else if (parent != NULL && (mode & S_ATTR_DIR) == 0)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
status_t status;
|
status_t status;
|
||||||
@@ -2567,23 +2581,23 @@ Inode::Create(Transaction& transaction, Inode* parent, const char* name,
|
|||||||
// only add the name to regular files, directories, or symlinks
|
// only add the name to regular files, directories, or symlinks
|
||||||
// don't add it to attributes, or indices
|
// don't add it to attributes, or indices
|
||||||
if (tree && inode->IsRegularNode()
|
if (tree && inode->IsRegularNode()
|
||||||
&& inode->SetName(transaction, name) < B_OK)
|
&& inode->SetName(transaction, name) != B_OK)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
// Initialize b+tree if it's a directory (and add "." & ".." if it's
|
// Initialize b+tree if it's a directory (and add "." & ".." if it's
|
||||||
// a standard directory for files - not for attributes or indices)
|
// a standard directory for files - not for attributes or indices)
|
||||||
if (inode->IsContainer()) {
|
if (inode->IsContainer()) {
|
||||||
status = allocator.CreateTree();
|
status = allocator.CreateTree();
|
||||||
if (status < B_OK)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a link to the inode from the parent, depending on its type
|
// Add a link to the inode from the parent, depending on its type
|
||||||
// (the vnode is not published yet, so it is safe to make the inode
|
// (the vnode is not published yet, so it is safe to make the inode
|
||||||
// accessable to the file system here)
|
// accessable to the file system here)
|
||||||
if (tree) {
|
if (tree != NULL) {
|
||||||
status = tree->Insert(transaction, name, inode->ID());
|
status = tree->Insert(transaction, name, inode->ID());
|
||||||
} else if (parent && (mode & S_ATTR_DIR) != 0) {
|
} else if (parent != NULL && (mode & S_ATTR_DIR) != 0) {
|
||||||
parent->Attributes() = run;
|
parent->Attributes() = run;
|
||||||
status = parent->WriteBack(transaction);
|
status = parent->WriteBack(transaction);
|
||||||
}
|
}
|
||||||
@@ -2592,7 +2606,7 @@ Inode::Create(Transaction& transaction, Inode* parent, const char* name,
|
|||||||
// two cases above; the root node or the indices root node must
|
// two cases above; the root node or the indices root node must
|
||||||
// handle this case on their own (or other cases where "parent" is
|
// handle this case on their own (or other cases where "parent" is
|
||||||
// NULL)
|
// NULL)
|
||||||
if (status < B_OK)
|
if (status != B_OK)
|
||||||
RETURN_ERROR(status);
|
RETURN_ERROR(status);
|
||||||
|
|
||||||
// Update the main indices (name, size & last_modified)
|
// Update the main indices (name, size & last_modified)
|
||||||
@@ -2603,7 +2617,7 @@ Inode::Create(Transaction& transaction, Inode* parent, const char* name,
|
|||||||
// the name index only contains regular files
|
// the name index only contains regular files
|
||||||
// (but not the root node where name == NULL)
|
// (but not the root node where name == NULL)
|
||||||
status = index.InsertName(transaction, name, inode);
|
status = index.InsertName(transaction, name, inode);
|
||||||
if (status < B_OK && status != B_BAD_INDEX) {
|
if (status != B_OK && status != B_BAD_INDEX) {
|
||||||
// We have to remove the node from the parent at this point,
|
// We have to remove the node from the parent at this point,
|
||||||
// because the InodeAllocator destructor can't handle this
|
// because the InodeAllocator destructor can't handle this
|
||||||
// case (and if it fails, we can't do anything about it...)
|
// case (and if it fails, we can't do anything about it...)
|
||||||
@@ -2616,6 +2630,9 @@ Inode::Create(Transaction& transaction, Inode* parent, const char* name,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (parent != NULL && parent->IsContainer())
|
||||||
|
parent->ContainerContentsChanged(transaction);
|
||||||
|
|
||||||
inode->UpdateOldLastModified();
|
inode->UpdateOldLastModified();
|
||||||
|
|
||||||
// The "size" & "last_modified" indices don't contain directories.
|
// The "size" & "last_modified" indices don't contain directories.
|
||||||
@@ -2652,30 +2669,6 @@ Inode::Create(Transaction& transaction, Inode* parent, const char* name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! Checks whether or not this node should be part of the name index */
|
|
||||||
bool
|
|
||||||
Inode::InNameIndex() const
|
|
||||||
{
|
|
||||||
return IsRegularNode();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*! Checks whether or not this node should be part of the size index */
|
|
||||||
bool
|
|
||||||
Inode::InSizeIndex() const
|
|
||||||
{
|
|
||||||
return IsFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*! Checks whether or not this node should be part of the last modified index */
|
|
||||||
bool
|
|
||||||
Inode::InLastModifiedIndex() const
|
|
||||||
{
|
|
||||||
return IsFile() || IsSymLink();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - AttributeIterator
|
// #pragma mark - AttributeIterator
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -121,6 +121,7 @@ public:
|
|||||||
// for directories only:
|
// for directories only:
|
||||||
status_t GetTree(BPlusTree** _tree);
|
status_t GetTree(BPlusTree** _tree);
|
||||||
bool IsEmpty();
|
bool IsEmpty();
|
||||||
|
status_t ContainerContentsChanged(Transaction& transaction);
|
||||||
|
|
||||||
// manipulating the data stream
|
// manipulating the data stream
|
||||||
status_t FindBlockRun(off_t pos, block_run& run,
|
status_t FindBlockRun(off_t pos, block_run& run,
|
||||||
@@ -241,6 +242,31 @@ private:
|
|||||||
SinglyLinkedList<AttributeIterator> fIterators;
|
SinglyLinkedList<AttributeIterator> fIterators;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*! Checks whether or not this node should be part of the name index */
|
||||||
|
inline bool
|
||||||
|
Inode::InNameIndex() const
|
||||||
|
{
|
||||||
|
return IsRegularNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! Checks whether or not this node should be part of the size index */
|
||||||
|
inline bool
|
||||||
|
Inode::InSizeIndex() const
|
||||||
|
{
|
||||||
|
return IsFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! Checks whether or not this node should be part of the last modified index */
|
||||||
|
inline bool
|
||||||
|
Inode::InLastModifiedIndex() const
|
||||||
|
{
|
||||||
|
return IsFile() || IsSymLink();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#if _KERNEL_MODE && KDEBUG
|
#if _KERNEL_MODE && KDEBUG
|
||||||
# define ASSERT_READ_LOCKED_INODE(inode) inode->AssertReadLocked()
|
# define ASSERT_READ_LOCKED_INODE(inode) inode->AssertReadLocked()
|
||||||
# define ASSERT_WRITE_LOCKED_INODE(inode) inode->AssertWriteLocked()
|
# define ASSERT_WRITE_LOCKED_INODE(inode) inode->AssertWriteLocked()
|
||||||
@@ -249,6 +275,7 @@ private:
|
|||||||
# define ASSERT_WRITE_LOCKED_INODE(inode)
|
# define ASSERT_WRITE_LOCKED_INODE(inode)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
class InodeReadLocker {
|
class InodeReadLocker {
|
||||||
public:
|
public:
|
||||||
InodeReadLocker(Inode* inode)
|
InodeReadLocker(Inode* inode)
|
||||||
|
|||||||
@@ -1149,7 +1149,7 @@ bfs_rename(fs_volume* _volume, fs_vnode* _oldDir, const char* oldName,
|
|||||||
status = newTree->Insert(transaction, (const uint8*)newName,
|
status = newTree->Insert(transaction, (const uint8*)newName,
|
||||||
strlen(newName), id);
|
strlen(newName), id);
|
||||||
}
|
}
|
||||||
if (status < B_OK)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
inode->WriteLockInTransaction(transaction);
|
inode->WriteLockInTransaction(transaction);
|
||||||
@@ -1186,6 +1186,12 @@ bfs_rename(fs_volume* _volume, fs_vnode* _oldDir, const char* oldName,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (newDirectory != oldDirectory) {
|
||||||
|
oldDirectory->ContainerContentsChanged(transaction);
|
||||||
|
newDirectory->ContainerContentsChanged(transaction);
|
||||||
|
} else
|
||||||
|
newDirectory->ContainerContentsChanged(transaction);
|
||||||
|
|
||||||
if (status == B_OK)
|
if (status == B_OK)
|
||||||
status = inode->WriteBack(transaction);
|
status = inode->WriteBack(transaction);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user