// reiserfs_rewind_dir static status_t reiserfs_rewind_dir(fs_volume *fs, fs_vnode *_node, void *cookie) { TOUCH(fs); // FUNCTION_START(); VNode *node = (VNode*)_node->private_node; FUNCTION(("node: (%Ld: %lu, %lu)\n", node->GetID(), node->GetDirID(), node->GetObjectID())); TOUCH(node); DirectoryCookie *iterator = (DirectoryCookie*)cookie; status_t error = iterator->Rewind(); // no need to Resume() if (error == B_OK) error = iterator->Suspend(); RETURN_ERROR(error); }
// reiserfs_open_dir static status_t reiserfs_open_dir(fs_volume *fs, fs_vnode *_node, void **cookie) { // FUNCTION_START(); Volume *volume = (Volume*)fs->private_volume; VNode *node = (VNode*)_node->private_node; FUNCTION(("node: (%Ld: %lu, %lu)\n", node->GetID(), node->GetDirID(), node->GetObjectID())); status_t error = (node->IsDir() ? B_OK : B_NOT_A_DIRECTORY); if (error == B_OK) { DirectoryCookie *iterator = new(nothrow) DirectoryCookie( volume->GetTree(), node->GetDirID(), node->GetObjectID()); if (iterator) { error = iterator->Suspend(); if (error == B_OK) *cookie = iterator; else delete iterator; } else error = B_NO_MEMORY; } FUNCTION_END(); RETURN_ERROR(error); }
// reiserfs_read_dir static status_t reiserfs_read_dir(fs_volume *fs, fs_vnode *_node, void *cookie, struct dirent *buffer, size_t bufferSize, uint32 *count) { // FUNCTION_START(); Volume *volume = (Volume*)fs->private_volume; VNode *node = (VNode*)_node->private_node; FUNCTION(("node: (%Ld: %lu, %lu)\n", node->GetID(), node->GetDirID(), node->GetObjectID())); DirectoryCookie *iterator = (DirectoryCookie*)cookie; status_t error = iterator->Resume(); if (error == B_OK) { // read one entry DirItem item; int32 index = 0; DirEntry *entry = NULL; bool done = false; while (error == B_OK && !done && (error = iterator->GetNext(&item, &index, &entry)) == B_OK) { uint32 dirID = entry->GetDirID(); uint32 objectID = entry->GetObjectID(); // skip hidden entries and entries the user specified to be hidden if (entry->IsHidden() || volume->IsNegativeEntry(dirID, objectID)) continue; // skip entry, if we can't get the stat data, or it is neither a // file, a dir nor a symlink and the user desired to hide those. StatData statData; StatItem statItem; if (volume->GetTree()->FindStatItem(dirID, objectID, &statItem) != B_OK || statItem.GetStatData(&statData) != B_OK || (statData.IsEsoteric() && volume->GetHideEsoteric())) { continue; } if (error == B_OK) { // get the name size_t nameLen = 0; const char *name = item.EntryNameAt(index, &nameLen); if (!name || nameLen == 0) // bad data: skip it gracefully continue; // fill in the entry name -- checks whether the // entry fits into the buffer error = set_dirent_name(buffer, bufferSize, name, nameLen); if (error == B_OK) { // fill in the other data buffer->d_dev = volume->GetID(); buffer->d_ino = VNode::GetIDFor(dirID, objectID); *count = 1; PRINT(("Successfully read entry: dir: (%Ld: %ld, %ld), name: `%s', " "id: (%Ld, %ld, %ld), reclen: %hu\n", node->GetID(), node->GetDirID(), node->GetObjectID(), buffer->d_name, buffer->d_ino, dirID, objectID, buffer->d_reclen)); if (!strcmp("..", buffer->d_name)) iterator->SetEncounteredDotDot(true); done = true; } } } if (error == B_ENTRY_NOT_FOUND) { if (iterator->EncounteredDotDot()) { error = B_OK; *count = 0; } else { // this is necessary for the root directory // it usually has no ".." entry, so we simulate one // get the name const char *name = ".."; size_t nameLen = strlen(name); // fill in the entry name -- checks whether the // entry fits into the buffer error = set_dirent_name(buffer, bufferSize, name, nameLen); if (error == B_OK) { // fill in the other data buffer->d_dev = volume->GetID(); buffer->d_ino = node->GetID(); // < That's not correct! *count = 1; PRINT(("faking `..' entry: dir: (%Ld: %ld, %ld), name: `%s', " "id: (%Ld, %ld, %ld), reclen: %hu\n", node->GetID(), node->GetDirID(), node->GetObjectID(), buffer->d_name, buffer->d_ino, node->GetDirID(), node->GetObjectID(), buffer->d_reclen)); iterator->SetEncounteredDotDot(true); } } } iterator->Suspend(); } PRINT(("returning %ld entries\n", *count)); RETURN_ERROR(error); }