12a73e4c5SPawel Dziepak /* 22a73e4c5SPawel Dziepak * Copyright 2012 Haiku, Inc. All rights reserved. 32a73e4c5SPawel Dziepak * Distributed under the terms of the MIT License. 42a73e4c5SPawel Dziepak * 52a73e4c5SPawel Dziepak * Authors: 62a73e4c5SPawel Dziepak * Paweł Dziepak, pdziepak@quarnos.org 72a73e4c5SPawel Dziepak */ 82a73e4c5SPawel Dziepak 92a73e4c5SPawel Dziepak 102a73e4c5SPawel Dziepak #include "Inode.h" 112a73e4c5SPawel Dziepak 122a73e4c5SPawel Dziepak #include <dirent.h> 132a73e4c5SPawel Dziepak #include <string.h> 142a73e4c5SPawel Dziepak 15b2cea80cSPawel Dziepak #include "IdMap.h" 162a73e4c5SPawel Dziepak #include "Request.h" 172a73e4c5SPawel Dziepak #include "RootInode.h" 182a73e4c5SPawel Dziepak 192a73e4c5SPawel Dziepak 202a73e4c5SPawel Dziepak status_t 21b352cbf6SPawel Dziepak Inode::CreateDir(const char* name, int mode, ino_t* id) 222a73e4c5SPawel Dziepak { 23b352cbf6SPawel Dziepak return CreateObject(name, NULL, mode, NF4DIR, id); 242a73e4c5SPawel Dziepak } 252a73e4c5SPawel Dziepak 262a73e4c5SPawel Dziepak 272a73e4c5SPawel Dziepak status_t 282a73e4c5SPawel Dziepak Inode::OpenDir(OpenDirCookie* cookie) 292a73e4c5SPawel Dziepak { 301e67a2cdSPawel Dziepak ASSERT(cookie != NULL); 311e67a2cdSPawel Dziepak 322a73e4c5SPawel Dziepak if (fType != NF4DIR) 332a73e4c5SPawel Dziepak return B_NOT_A_DIRECTORY; 342a73e4c5SPawel Dziepak 350dbff361SPawel Dziepak status_t result = Access(R_OK); 362a73e4c5SPawel Dziepak if (result != B_OK) 372a73e4c5SPawel Dziepak return result; 382a73e4c5SPawel Dziepak 3900a8558cSPawel Dziepak cookie->fFileSystem = fFileSystem; 406b9a91ebSPawel Dziepak cookie->fSpecial = 0; 4109dbdd36SPawel Dziepak cookie->fSnapshot = NULL; 4209dbdd36SPawel Dziepak cookie->fCurrent = NULL; 4309dbdd36SPawel Dziepak cookie->fEOF = false; 44f7c35cf4SPawel Dziepak cookie->fAttrDir = false; 45f7c35cf4SPawel Dziepak 46f7c35cf4SPawel Dziepak return B_OK; 47f7c35cf4SPawel Dziepak } 48f7c35cf4SPawel Dziepak 49f7c35cf4SPawel Dziepak 50f7c35cf4SPawel Dziepak status_t 51f7c35cf4SPawel Dziepak Inode::OpenAttrDir(OpenDirCookie* cookie) 52f7c35cf4SPawel Dziepak { 531e67a2cdSPawel Dziepak ASSERT(cookie != NULL); 541e67a2cdSPawel Dziepak 55f7c35cf4SPawel Dziepak cookie->fFileSystem = fFileSystem; 56f7c35cf4SPawel Dziepak cookie->fSpecial = 0; 57f7c35cf4SPawel Dziepak cookie->fSnapshot = NULL; 58f7c35cf4SPawel Dziepak cookie->fCurrent = NULL; 59f7c35cf4SPawel Dziepak cookie->fEOF = false; 60f7c35cf4SPawel Dziepak cookie->fAttrDir = true; 61f7c35cf4SPawel Dziepak 6220d1b02eSPawel Dziepak return LoadAttrDirHandle(); 6320d1b02eSPawel Dziepak } 6420d1b02eSPawel Dziepak 6520d1b02eSPawel Dziepak 6620d1b02eSPawel Dziepak status_t 6720d1b02eSPawel Dziepak Inode::LoadAttrDirHandle() 6820d1b02eSPawel Dziepak { 6970472e11SPawel Dziepak if (fInfo.fAttrDir.fSize != 0) 7070472e11SPawel Dziepak return B_OK; 71a5ae9b47SPawel Dziepak 72f7c35cf4SPawel Dziepak FileHandle handle; 7370472e11SPawel Dziepak status_t result; 74060a4636SPawel Dziepak 75060a4636SPawel Dziepak if (fFileSystem->NamedAttrs()) { 76060a4636SPawel Dziepak result = NFS4Inode::OpenAttrDir(&handle); 77060a4636SPawel Dziepak if (result == B_OK) { 78060a4636SPawel Dziepak fInfo.fAttrDir = handle; 79060a4636SPawel Dziepak return B_OK; 80060a4636SPawel Dziepak } 81060a4636SPawel Dziepak 82060a4636SPawel Dziepak if (result != B_UNSUPPORTED) 83060a4636SPawel Dziepak return result; 84060a4636SPawel Dziepak 85060a4636SPawel Dziepak fFileSystem->SetNamedAttrs(false); 86060a4636SPawel Dziepak } 87060a4636SPawel Dziepak 88060a4636SPawel Dziepak if (!fFileSystem->GetConfiguration().fEmulateNamedAttrs) 89060a4636SPawel Dziepak return B_UNSUPPORTED; 90060a4636SPawel Dziepak 9170472e11SPawel Dziepak char* attrDir 92da950cb2SPawel Dziepak = reinterpret_cast<char*>(malloc(strlen(Name()) + 32)); 9370472e11SPawel Dziepak if (attrDir == NULL) 9470472e11SPawel Dziepak return B_NO_MEMORY; 9570472e11SPawel Dziepak strcpy(attrDir, "."); 96da950cb2SPawel Dziepak strcat(attrDir, Name()); 9770472e11SPawel Dziepak strcat(attrDir, "-haiku-attrs"); 98f7c35cf4SPawel Dziepak 9970472e11SPawel Dziepak result = NFS4Inode::LookUp(attrDir, NULL, NULL, &handle, true); 10070472e11SPawel Dziepak if (result == B_ENTRY_NOT_FOUND) { 10170472e11SPawel Dziepak ChangeInfo change; 10270472e11SPawel Dziepak struct stat st; 10370472e11SPawel Dziepak Stat(&st); 10470472e11SPawel Dziepak st.st_mode |= S_IXUSR | S_IXGRP | S_IXOTH; 10570472e11SPawel Dziepak result = NFS4Inode::CreateObject(attrDir, NULL, st.st_mode, NF4DIR, 10670472e11SPawel Dziepak &change, NULL, &handle, true); 10770472e11SPawel Dziepak } 10870472e11SPawel Dziepak 10970472e11SPawel Dziepak free(attrDir); 110a5ae9b47SPawel Dziepak 111f7c35cf4SPawel Dziepak if (result != B_OK) 112f7c35cf4SPawel Dziepak return result; 113f7c35cf4SPawel Dziepak 114f7c35cf4SPawel Dziepak fInfo.fAttrDir = handle; 1152a73e4c5SPawel Dziepak return B_OK; 1162a73e4c5SPawel Dziepak } 1172a73e4c5SPawel Dziepak 1182a73e4c5SPawel Dziepak 1192a73e4c5SPawel Dziepak status_t 1200dbff361SPawel Dziepak Inode::FillDirEntry(struct dirent* de, ino_t id, const char* name, uint32 pos, 1212a73e4c5SPawel Dziepak uint32 size) 1222a73e4c5SPawel Dziepak { 1231e67a2cdSPawel Dziepak ASSERT(de != NULL); 1241e67a2cdSPawel Dziepak ASSERT(name != NULL); 1251e67a2cdSPawel Dziepak 126*eed5b716SPawel Dziepak uint32 nameSize = strlen(name) + 1; 1272a73e4c5SPawel Dziepak const uint32 entSize = sizeof(struct dirent); 1282a73e4c5SPawel Dziepak 1292a73e4c5SPawel Dziepak if (pos + entSize + nameSize > size) 1302a73e4c5SPawel Dziepak return B_BUFFER_OVERFLOW; 1312a73e4c5SPawel Dziepak 13200a8558cSPawel Dziepak de->d_dev = fFileSystem->DevId(); 1332a73e4c5SPawel Dziepak de->d_ino = id; 1342a73e4c5SPawel Dziepak de->d_reclen = entSize + nameSize; 1352a73e4c5SPawel Dziepak if (de->d_reclen % 8 != 0) 1362a73e4c5SPawel Dziepak de->d_reclen += 8 - de->d_reclen % 8; 1372a73e4c5SPawel Dziepak 1382a73e4c5SPawel Dziepak strcpy(de->d_name, name); 1392a73e4c5SPawel Dziepak 1402a73e4c5SPawel Dziepak return B_OK; 1412a73e4c5SPawel Dziepak } 1422a73e4c5SPawel Dziepak 1432a73e4c5SPawel Dziepak 1442a73e4c5SPawel Dziepak status_t 1450dbff361SPawel Dziepak Inode::ReadDirUp(struct dirent* de, uint32 pos, uint32 size) 1462a73e4c5SPawel Dziepak { 1471e67a2cdSPawel Dziepak ASSERT(de != NULL); 1481e67a2cdSPawel Dziepak 1492a73e4c5SPawel Dziepak do { 15000a8558cSPawel Dziepak RPC::Server* serv = fFileSystem->Server(); 151060a4636SPawel Dziepak Request request(serv, fFileSystem); 1522a73e4c5SPawel Dziepak RequestBuilder& req = request.Builder(); 1532a73e4c5SPawel Dziepak 154a28e8732SPawel Dziepak req.PutFH(fInfo.fHandle); 1552a73e4c5SPawel Dziepak req.LookUpUp(); 1562a73e4c5SPawel Dziepak req.GetFH(); 1572a73e4c5SPawel Dziepak 15800a8558cSPawel Dziepak if (fFileSystem->IsAttrSupported(FATTR4_FILEID)) { 1592a73e4c5SPawel Dziepak Attribute attr[] = { FATTR4_FILEID }; 1602a73e4c5SPawel Dziepak req.GetAttr(attr, sizeof(attr) / sizeof(Attribute)); 1612a73e4c5SPawel Dziepak } 1622a73e4c5SPawel Dziepak 1632a73e4c5SPawel Dziepak status_t result = request.Send(); 1642a73e4c5SPawel Dziepak if (result != B_OK) 1652a73e4c5SPawel Dziepak return result; 1662a73e4c5SPawel Dziepak 1672a73e4c5SPawel Dziepak ReplyInterpreter& reply = request.Reply(); 1682a73e4c5SPawel Dziepak 1690dbff361SPawel Dziepak if (HandleErrors(reply.NFS4Error(), serv)) 1702a73e4c5SPawel Dziepak continue; 1712a73e4c5SPawel Dziepak 1722a73e4c5SPawel Dziepak reply.PutFH(); 1732a73e4c5SPawel Dziepak result = reply.LookUpUp(); 1742a73e4c5SPawel Dziepak if (result != B_OK) 1752a73e4c5SPawel Dziepak return result; 1762a73e4c5SPawel Dziepak 17700a8558cSPawel Dziepak FileHandle fh; 1782a73e4c5SPawel Dziepak reply.GetFH(&fh); 1792a73e4c5SPawel Dziepak 1802a73e4c5SPawel Dziepak uint64 fileId; 18100a8558cSPawel Dziepak if (fFileSystem->IsAttrSupported(FATTR4_FILEID)) { 1822a73e4c5SPawel Dziepak AttrValue* values; 1832a73e4c5SPawel Dziepak uint32 count; 1842a73e4c5SPawel Dziepak reply.GetAttr(&values, &count); 1852a73e4c5SPawel Dziepak if (result != B_OK) 1862a73e4c5SPawel Dziepak return result; 1872a73e4c5SPawel Dziepak 1882a73e4c5SPawel Dziepak fileId = values[0].fData.fValue64; 1892a73e4c5SPawel Dziepak delete[] values; 1902a73e4c5SPawel Dziepak } else 19100a8558cSPawel Dziepak fileId = fFileSystem->AllocFileId(); 1922a73e4c5SPawel Dziepak 1930dbff361SPawel Dziepak return FillDirEntry(de, FileIdToInoT(fileId), "..", pos, size); 1942a73e4c5SPawel Dziepak } while (true); 1952a73e4c5SPawel Dziepak } 1962a73e4c5SPawel Dziepak 19709dbdd36SPawel Dziepak 19870472e11SPawel Dziepak static char* 19970472e11SPawel Dziepak FileToAttrName(const char* path) 20070472e11SPawel Dziepak { 2011e67a2cdSPawel Dziepak ASSERT(path != NULL); 2021e67a2cdSPawel Dziepak 20370472e11SPawel Dziepak char* name = strdup(path); 20470472e11SPawel Dziepak if (name == NULL) 20570472e11SPawel Dziepak return NULL; 20670472e11SPawel Dziepak 20770472e11SPawel Dziepak char* current = strpbrk(name, "#$"); 20870472e11SPawel Dziepak while (current != NULL) { 20970472e11SPawel Dziepak switch (*current) { 21070472e11SPawel Dziepak case '#': 21170472e11SPawel Dziepak *current = '/'; 21270472e11SPawel Dziepak break; 21370472e11SPawel Dziepak case '$': 21470472e11SPawel Dziepak *current = ':'; 21570472e11SPawel Dziepak break; 21670472e11SPawel Dziepak } 21770472e11SPawel Dziepak current = strpbrk(name, "#$"); 21870472e11SPawel Dziepak } 21970472e11SPawel Dziepak 22070472e11SPawel Dziepak return name; 22170472e11SPawel Dziepak } 22270472e11SPawel Dziepak 22370472e11SPawel Dziepak 2242a73e4c5SPawel Dziepak status_t 2250dbff361SPawel Dziepak Inode::GetDirSnapshot(DirectoryCacheSnapshot** _snapshot, 2262314d073SPawel Dziepak OpenDirCookie* cookie, uint64* _change, bool attribute) 2272a73e4c5SPawel Dziepak { 2281e67a2cdSPawel Dziepak ASSERT(_snapshot != NULL); 2291e67a2cdSPawel Dziepak 23009dbdd36SPawel Dziepak DirectoryCacheSnapshot* snapshot = new DirectoryCacheSnapshot; 23109dbdd36SPawel Dziepak if (snapshot == NULL) 23209dbdd36SPawel Dziepak return B_NO_MEMORY; 23309dbdd36SPawel Dziepak 23409dbdd36SPawel Dziepak uint64 change = 0; 23509dbdd36SPawel Dziepak uint64 dirCookie = 0; 23609dbdd36SPawel Dziepak uint64 dirCookieVerf = 0; 2372a73e4c5SPawel Dziepak bool eof = false; 2382a73e4c5SPawel Dziepak 23909dbdd36SPawel Dziepak while (!eof) { 24009dbdd36SPawel Dziepak uint32 count; 24109dbdd36SPawel Dziepak DirEntry* dirents; 2422a73e4c5SPawel Dziepak 2430dbff361SPawel Dziepak status_t result = ReadDirOnce(&dirents, &count, cookie, &eof, &change, 2442314d073SPawel Dziepak &dirCookie, &dirCookieVerf, attribute); 24509dbdd36SPawel Dziepak if (result != B_OK) { 24609dbdd36SPawel Dziepak delete snapshot; 24709dbdd36SPawel Dziepak return result; 24809dbdd36SPawel Dziepak } 24909dbdd36SPawel Dziepak 25009dbdd36SPawel Dziepak uint32 i; 25109dbdd36SPawel Dziepak for (i = 0; i < count; i++) { 25209dbdd36SPawel Dziepak 25309dbdd36SPawel Dziepak // FATTR4_FSID is mandatory 25409dbdd36SPawel Dziepak void* data = dirents[i].fAttrs[0].fData.fPointer; 25509dbdd36SPawel Dziepak FileSystemId* fsid = reinterpret_cast<FileSystemId*>(data); 25609dbdd36SPawel Dziepak if (*fsid != fFileSystem->FsId()) 25709dbdd36SPawel Dziepak continue; 25809dbdd36SPawel Dziepak 25970472e11SPawel Dziepak if (strstr(dirents[i].fName, "-haiku-attrs") != NULL) 26070472e11SPawel Dziepak continue; 26170472e11SPawel Dziepak 26209dbdd36SPawel Dziepak ino_t id; 2632314d073SPawel Dziepak if (!attribute) { 26409dbdd36SPawel Dziepak if (dirents[i].fAttrCount == 2) 2650dbff361SPawel Dziepak id = FileIdToInoT(dirents[i].fAttrs[1].fData.fValue64); 26609dbdd36SPawel Dziepak else 2670dbff361SPawel Dziepak id = FileIdToInoT(fFileSystem->AllocFileId()); 268f7c35cf4SPawel Dziepak } else 269f7c35cf4SPawel Dziepak id = 0; 27009dbdd36SPawel Dziepak 27170472e11SPawel Dziepak const char* name = dirents[i].fName; 27270472e11SPawel Dziepak if (attribute) 27370472e11SPawel Dziepak name = FileToAttrName(name); 27470472e11SPawel Dziepak if (name == NULL) { 27570472e11SPawel Dziepak delete snapshot; 27670472e11SPawel Dziepak delete[] dirents; 27770472e11SPawel Dziepak return B_NO_MEMORY; 27870472e11SPawel Dziepak } 27970472e11SPawel Dziepak 28070472e11SPawel Dziepak NameCacheEntry* entry = new NameCacheEntry(name, id); 28170472e11SPawel Dziepak if (attribute) 28270472e11SPawel Dziepak free(const_cast<char*>(name)); 28370472e11SPawel Dziepak 28409dbdd36SPawel Dziepak if (entry == NULL || entry->fName == NULL) { 285*eed5b716SPawel Dziepak if (entry != NULL) 28609dbdd36SPawel Dziepak delete entry; 28709dbdd36SPawel Dziepak delete snapshot; 28809dbdd36SPawel Dziepak delete[] dirents; 28909dbdd36SPawel Dziepak return B_NO_MEMORY; 29009dbdd36SPawel Dziepak } 29109dbdd36SPawel Dziepak snapshot->fEntries.Add(entry); 29209dbdd36SPawel Dziepak } 29309dbdd36SPawel Dziepak 29409dbdd36SPawel Dziepak delete[] dirents; 29509dbdd36SPawel Dziepak } 29609dbdd36SPawel Dziepak 29709dbdd36SPawel Dziepak *_snapshot = snapshot; 29809dbdd36SPawel Dziepak *_change = change; 29909dbdd36SPawel Dziepak 30009dbdd36SPawel Dziepak return B_OK; 30109dbdd36SPawel Dziepak } 30209dbdd36SPawel Dziepak 3032a73e4c5SPawel Dziepak 30409dbdd36SPawel Dziepak status_t 30509dbdd36SPawel Dziepak Inode::ReadDir(void* _buffer, uint32 size, uint32* _count, 30609dbdd36SPawel Dziepak OpenDirCookie* cookie) 30709dbdd36SPawel Dziepak { 3081e67a2cdSPawel Dziepak ASSERT(_buffer != NULL); 3091e67a2cdSPawel Dziepak ASSERT(_count != NULL); 3101e67a2cdSPawel Dziepak ASSERT(cookie != NULL); 3111e67a2cdSPawel Dziepak 31209dbdd36SPawel Dziepak if (cookie->fEOF) { 31309dbdd36SPawel Dziepak *_count = 0; 31409dbdd36SPawel Dziepak return B_OK; 31509dbdd36SPawel Dziepak } 3162a73e4c5SPawel Dziepak 31709dbdd36SPawel Dziepak status_t result; 318f7c35cf4SPawel Dziepak DirectoryCache* cache = cookie->fAttrDir ? fAttrCache : fCache; 31909dbdd36SPawel Dziepak if (cookie->fSnapshot == NULL) { 32009dbdd36SPawel Dziepak fFileSystem->Revalidator().Lock(); 321cae470f9SPawel Dziepak cache->Lock(); 322cae470f9SPawel Dziepak if (!cache->Valid()) 323cae470f9SPawel Dziepak cache->Reset(); 324cae470f9SPawel Dziepak else 325f7c35cf4SPawel Dziepak fFileSystem->Revalidator().RemoveDirectory(cache); 32609dbdd36SPawel Dziepak 327*eed5b716SPawel Dziepak DirectoryCacheSnapshot* snapshot = cache->GetSnapshot(); 328*eed5b716SPawel Dziepak if (snapshot == NULL) { 32909dbdd36SPawel Dziepak uint64 change; 330*eed5b716SPawel Dziepak result = GetDirSnapshot(&snapshot, cookie, &change, 3312314d073SPawel Dziepak cookie->fAttrDir); 33209dbdd36SPawel Dziepak if (result != B_OK) { 333f7c35cf4SPawel Dziepak cache->Unlock(); 33409dbdd36SPawel Dziepak fFileSystem->Revalidator().Unlock(); 3352a73e4c5SPawel Dziepak return result; 33609dbdd36SPawel Dziepak } 337f7c35cf4SPawel Dziepak cache->ValidateChangeInfo(change); 338*eed5b716SPawel Dziepak cache->SetSnapshot(snapshot); 33909dbdd36SPawel Dziepak } 340*eed5b716SPawel Dziepak cookie->fSnapshot = new DirectoryCacheSnapshot(*snapshot); 341f7c35cf4SPawel Dziepak fFileSystem->Revalidator().AddDirectory(cache); 342f7c35cf4SPawel Dziepak cache->Unlock(); 34309dbdd36SPawel Dziepak fFileSystem->Revalidator().Unlock(); 34409dbdd36SPawel Dziepak } 3452a73e4c5SPawel Dziepak 34609dbdd36SPawel Dziepak char* buffer = reinterpret_cast<char*>(_buffer); 34709dbdd36SPawel Dziepak uint32 pos = 0; 3486b9a91ebSPawel Dziepak uint32 i = 0; 3496b9a91ebSPawel Dziepak bool overflow = false; 3506b9a91ebSPawel Dziepak 351f7c35cf4SPawel Dziepak if (cookie->fSpecial == 0 && i < *_count && !cookie->fAttrDir) { 3526b9a91ebSPawel Dziepak struct dirent* de = reinterpret_cast<dirent*>(buffer + pos); 3536b9a91ebSPawel Dziepak 3546b9a91ebSPawel Dziepak status_t result; 3550dbff361SPawel Dziepak result = FillDirEntry(de, fInfo.fFileId, ".", pos, size); 3566b9a91ebSPawel Dziepak 3576b9a91ebSPawel Dziepak if (result == B_BUFFER_OVERFLOW) 3586b9a91ebSPawel Dziepak overflow = true; 3596b9a91ebSPawel Dziepak else if (result == B_OK) { 3606b9a91ebSPawel Dziepak pos += de->d_reclen; 3616b9a91ebSPawel Dziepak i++; 3626b9a91ebSPawel Dziepak cookie->fSpecial++; 3636b9a91ebSPawel Dziepak } else 3646b9a91ebSPawel Dziepak return result; 3656b9a91ebSPawel Dziepak } 3666b9a91ebSPawel Dziepak 367f7c35cf4SPawel Dziepak if (cookie->fSpecial == 1 && i < *_count && !cookie->fAttrDir) { 3686b9a91ebSPawel Dziepak struct dirent* de = reinterpret_cast<dirent*>(buffer + pos); 3696b9a91ebSPawel Dziepak 3706b9a91ebSPawel Dziepak status_t result; 3710dbff361SPawel Dziepak result = ReadDirUp(de, pos, size); 3728afd81baSPawel Dziepak if (result == B_ENTRY_NOT_FOUND) { 3730dbff361SPawel Dziepak result = FillDirEntry(de, FileIdToInoT(fInfo.fFileId), "..", pos, 3740dbff361SPawel Dziepak size); 3750dbff361SPawel Dziepak } 3766b9a91ebSPawel Dziepak 3776b9a91ebSPawel Dziepak if (result == B_BUFFER_OVERFLOW) 3786b9a91ebSPawel Dziepak overflow = true; 3796b9a91ebSPawel Dziepak else if (result == B_OK) { 3806b9a91ebSPawel Dziepak pos += de->d_reclen; 3816b9a91ebSPawel Dziepak i++; 3826b9a91ebSPawel Dziepak cookie->fSpecial++; 3836b9a91ebSPawel Dziepak } else 3846b9a91ebSPawel Dziepak return result; 3856b9a91ebSPawel Dziepak } 38609dbdd36SPawel Dziepak 38709dbdd36SPawel Dziepak MutexLocker _(cookie->fSnapshot->fLock); 3886b9a91ebSPawel Dziepak for (; !overflow && i < *_count; i++) { 3892a73e4c5SPawel Dziepak struct dirent* de = reinterpret_cast<dirent*>(buffer + pos); 390*eed5b716SPawel Dziepak NameCacheEntry* temp = cookie->fCurrent; 3912a73e4c5SPawel Dziepak 39209dbdd36SPawel Dziepak if (cookie->fCurrent == NULL) 39309dbdd36SPawel Dziepak cookie->fCurrent = cookie->fSnapshot->fEntries.Head(); 39409dbdd36SPawel Dziepak else { 39509dbdd36SPawel Dziepak cookie->fCurrent 39609dbdd36SPawel Dziepak = cookie->fSnapshot->fEntries.GetNext(cookie->fCurrent); 39709dbdd36SPawel Dziepak } 3982a73e4c5SPawel Dziepak 39909dbdd36SPawel Dziepak if (cookie->fCurrent == NULL) { 40009dbdd36SPawel Dziepak cookie->fEOF = true; 40109dbdd36SPawel Dziepak break; 40209dbdd36SPawel Dziepak } 4032a73e4c5SPawel Dziepak 4040dbff361SPawel Dziepak if (FillDirEntry(de, cookie->fCurrent->fNode, cookie->fCurrent->fName, 40509dbdd36SPawel Dziepak pos, size) == B_BUFFER_OVERFLOW) { 406*eed5b716SPawel Dziepak cookie->fCurrent = temp; 4072a73e4c5SPawel Dziepak overflow = true; 4082a73e4c5SPawel Dziepak break; 4092a73e4c5SPawel Dziepak } 4102a73e4c5SPawel Dziepak 4112a73e4c5SPawel Dziepak pos += de->d_reclen; 4122a73e4c5SPawel Dziepak } 4132a73e4c5SPawel Dziepak 41409dbdd36SPawel Dziepak if (i == 0 && overflow) 4152a73e4c5SPawel Dziepak return B_BUFFER_OVERFLOW; 4162a73e4c5SPawel Dziepak 41709dbdd36SPawel Dziepak *_count = i; 4182a73e4c5SPawel Dziepak 4192a73e4c5SPawel Dziepak return B_OK; 4202a73e4c5SPawel Dziepak } 4212a73e4c5SPawel Dziepak 422