diff --git a/src/add-ons/kernel/file_systems/bfs/Inode.cpp b/src/add-ons/kernel/file_systems/bfs/Inode.cpp index ef7f7d130f..5a2b4206e6 100644 --- a/src/add-ons/kernel/file_systems/bfs/Inode.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Inode.cpp @@ -254,6 +254,8 @@ Inode::RemoveIterator(AttributeIterator *iterator) status_t Inode::MakeSpaceForSmallData(Transaction *transaction, const char *name, int32 bytes) { + ASSERT(fSmallDataLock.IsLocked()); + while (bytes > 0) { small_data *item = Node()->small_data_start, *max = NULL; int32 index = 0, maxIndex = 0; @@ -315,6 +317,8 @@ Inode::MakeSpaceForSmallData(Transaction *transaction, const char *name, int32 b status_t Inode::RemoveSmallData(small_data *item, int32 index) { + ASSERT(fSmallDataLock.IsLocked()); + small_data *next = item->Next(); if (!next->IsLast(Node())) { // find the last attribute @@ -524,12 +528,14 @@ Inode::AddSmallData(Transaction *transaction, const char *name, uint32 type, */ status_t -Inode::GetNextSmallData(small_data **smallData) const +Inode::GetNextSmallData(small_data **_smallData) const { if (!Node()) RETURN_ERROR(B_ERROR); - small_data *data = *smallData; + ASSERT(fSmallDataLock.IsLocked()); + + small_data *data = *_smallData; // begin from the start? if (data == NULL) @@ -541,7 +547,7 @@ Inode::GetNextSmallData(small_data **smallData) const if (data->IsLast(Node())) return B_ENTRY_NOT_FOUND; - *smallData = data; + *_smallData = data; return B_OK; } @@ -555,6 +561,8 @@ Inode::GetNextSmallData(small_data **smallData) const small_data * Inode::FindSmallData(const char *name) const { + ASSERT(fSmallDataLock.IsLocked()); + small_data *smallData = NULL; while (GetNextSmallData(&smallData) == B_OK) { if (!strcmp(smallData->Name(), name)) @@ -564,10 +572,15 @@ Inode::FindSmallData(const char *name) const } +/** Returns a pointer to the node's name if present in the small data + * section, NULL otherwise. + * You need to hold the fSmallDataLock when you call this method + */ + const char * Inode::Name() const { - SimpleLocker locker(fSmallDataLock); + ASSERT(fSmallDataLock.IsLocked()); small_data *smallData = NULL; while (GetNextSmallData(&smallData) == B_OK) { @@ -578,6 +591,24 @@ Inode::Name() const } +/** Copies the node's name into the provided buffer. + * The buffer must be B_FILE_NAME_LENGTH bytes large. + */ + +status_t +Inode::GetName(char *buffer) const +{ + SimpleLocker locker(fSmallDataLock); + + const char *name = Name(); + if (name == NULL) + return B_ENTRY_NOT_FOUND; + + strlcpy(buffer, name, B_FILE_NAME_LENGTH); + return B_OK; +} + + /** Changes or set the name of a file: in the inode small_data section only, it * doesn't change it in the parent directory's b+tree. * Note that you need to write back the inode yourself after having called diff --git a/src/add-ons/kernel/file_systems/bfs/Inode.h b/src/add-ons/kernel/file_systems/bfs/Inode.h index d0639076b7..673733cdd6 100644 --- a/src/add-ons/kernel/file_systems/bfs/Inode.h +++ b/src/add-ons/kernel/file_systems/bfs/Inode.h @@ -167,13 +167,15 @@ class Inode : public CachedBlock { status_t CheckPermissions(int accessMode) const; // small_data access methods - status_t MakeSpaceForSmallData(Transaction *transaction,const char *name, int32 length); - status_t RemoveSmallData(Transaction *transaction,const char *name); - status_t AddSmallData(Transaction *transaction,const char *name,uint32 type,const uint8 *data,size_t length,bool force = false); - status_t GetNextSmallData(small_data **smallData) const; + status_t MakeSpaceForSmallData(Transaction *transaction, const char *name, int32 length); + status_t RemoveSmallData(Transaction *transaction, const char *name); + status_t AddSmallData(Transaction *transaction, const char *name, uint32 type, + const uint8 *data, size_t length, bool force = false); + status_t GetNextSmallData(small_data **_smallData) const; small_data *FindSmallData(const char *name) const; const char *Name() const; - status_t SetName(Transaction *transaction,const char *name); + status_t GetName(char *buffer) const; + status_t SetName(Transaction *transaction, const char *name); // high-level attribute methods status_t ReadAttribute(const char *name, int32 type, off_t pos, uint8 *buffer, size_t *_length); @@ -181,31 +183,33 @@ class Inode : public CachedBlock { status_t RemoveAttribute(Transaction *transaction, const char *name); // attribute methods - status_t GetAttribute(const char *name,Inode **attribute); + status_t GetAttribute(const char *name, Inode **attribute); void ReleaseAttribute(Inode *attribute); - status_t CreateAttribute(Transaction *transaction,const char *name,uint32 type,Inode **attribute); + status_t CreateAttribute(Transaction *transaction, const char *name, uint32 type, Inode **attribute); // for directories only: status_t GetTree(BPlusTree **); bool IsEmpty(); // manipulating the data stream - status_t FindBlockRun(off_t pos,block_run &run,off_t &offset); + status_t FindBlockRun(off_t pos, block_run &run, off_t &offset); - status_t ReadAt(off_t pos,uint8 *buffer,size_t *length); - status_t WriteAt(Transaction *transaction,off_t pos,const uint8 *buffer,size_t *length); - status_t FillGapWithZeros(off_t oldSize,off_t newSize); + status_t ReadAt(off_t pos, uint8 *buffer, size_t *length); + status_t WriteAt(Transaction *transaction, off_t pos, const uint8 *buffer, size_t *length); + status_t FillGapWithZeros(off_t oldSize, off_t newSize); - status_t SetFileSize(Transaction *transaction,off_t size); - status_t Append(Transaction *transaction,off_t bytes); + status_t SetFileSize(Transaction *transaction, off_t size); + status_t Append(Transaction *transaction, off_t bytes); status_t Trim(Transaction *transaction); status_t Free(Transaction *transaction); status_t Sync(); // create/remove inodes - status_t Remove(Transaction *transaction,const char *name,off_t *_id = NULL,bool isDirectory = false); - static status_t Create(Transaction *transaction,Inode *parent,const char *name,int32 mode,int omode,uint32 type,off_t *_id = NULL,Inode **_inode = NULL); + status_t Remove(Transaction *transaction, const char *name, off_t *_id = NULL, + bool isDirectory = false); + static status_t Create(Transaction *transaction, Inode *parent, const char *name, + int32 mode, int omode, uint32 type, off_t *_id = NULL, Inode **_inode = NULL); // index maintaining helper void UpdateOldSize() { fOldSize = Size(); }