static status_t nfs4_remove_dir(fs_volume* volume, fs_vnode* parent, const char* name) { VnodeToInode* vti = reinterpret_cast<VnodeToInode*>(parent->private_node); TRACE("volume = %p, parent = %" B_PRIi64 ", name = %s", volume, vti->ID(), name); VnodeToInodeLocker _(vti); Inode* inode = vti->Get(); if (inode == NULL) return B_ENTRY_NOT_FOUND; ino_t id; status_t result = inode->Remove(name, NF4DIR, &id); if (result != B_OK) return result; result = acquire_vnode(volume, id); if (result == B_OK) { result = get_vnode(volume, id, reinterpret_cast<void**>(&vti)); ASSERT(result == B_OK); if (vti->Unlink(inode->fInfo.fNames, name)) remove_vnode(volume, id); put_vnode(volume, id); put_vnode(volume, id); } return B_OK; }
Inode *InodeFactory::allocInode(FsMaker *fs, TARINO pino, int ftype) { Inode *inode; TARINO ino = InodeFactory::inodeNum; TARBLK blkno; TARBLK oldblkno; SpaceManager *sp = fs->getDinodeManager(); oldblkno = sp->getblkno(); sp->allocBlock(fs, &blkno); if (oldblkno == TARBLK_NONE) { tarfs_dext de; de.de_off = ino; de.de_blkno = blkno; de.de_nblks = sp->getbulks(); InodeFactory::freeInode->insBlock(fs, &de); } if (ftype == TARFS_IFDIR) { Dir *dir = new Dir(ino, pino, blkno); dir->dirInit(fs); inode = dir; } else { inode = new Inode(ino, pino, blkno, ftype); } if (inode) { inode->setDirty(); InodeFactory::inodeNum++; } else { fs->rollback(); } return inode; }
static status_t ext2_lookup(fs_volume* _volume, fs_vnode* _directory, const char* name, ino_t* _vnodeID) { TRACE("ext2_lookup: name address: %p\n", name); TRACE("ext2_lookup: name: %s\n", name); Volume* volume = (Volume*)_volume->private_volume; Inode* directory = (Inode*)_directory->private_node; // check access permissions status_t status = directory->CheckPermissions(X_OK); if (status < B_OK) return status; HTree htree(volume, directory); DirectoryIterator* iterator; status = htree.Lookup(name, &iterator); if (status != B_OK) return status; ObjectDeleter<DirectoryIterator> iteratorDeleter(iterator); status = iterator->FindEntry(name, _vnodeID); if (status != B_OK) return status; return get_vnode(volume->FSVolume(), *_vnodeID, NULL); }
static status_t ext2_get_file_map(fs_volume* _volume, fs_vnode* _node, off_t offset, size_t size, struct file_io_vec* vecs, size_t* _count) { TRACE("ext2_get_file_map()\n"); Volume* volume = (Volume*)_volume->private_volume; Inode* inode = (Inode*)_node->private_node; size_t index = 0, max = *_count; while (true) { fsblock_t block; uint32 count = 1; status_t status = inode->FindBlock(offset, block, &count); if (status != B_OK) return status; if (block > volume->NumBlocks()) { panic("ext2_get_file_map() found block %" B_PRIu64 " for offset %" B_PRIdOFF "\n", block, offset); } off_t blockOffset = block << volume->BlockShift(); uint32 blockLength = volume->BlockSize() * count; if (index > 0 && (vecs[index - 1].offset == blockOffset - vecs[index - 1].length || (vecs[index - 1].offset == -1 && block == 0))) { vecs[index - 1].length += blockLength; } else { if (index >= max) { // we're out of file_io_vecs; let's bail out *_count = index; return B_BUFFER_OVERFLOW; } // 'block' is 0 for sparse blocks if (block != 0) vecs[index].offset = blockOffset; else vecs[index].offset = -1; vecs[index].length = blockLength; index++; } offset += blockLength; if (offset >= inode->Size() || size <= blockLength) { // We're done! *_count = index; TRACE("ext2_get_file_map for inode %" B_PRIdINO "\n", inode->ID()); return B_OK; } size -= blockLength; } // can never get here return B_ERROR; }
static status_t ext2_get_vnode(fs_volume* _volume, ino_t id, fs_vnode* _node, int* _type, uint32* _flags, bool reenter) { Volume* volume = (Volume*)_volume->private_volume; if (id < 2 || id > volume->NumInodes()) { ERROR("invalid inode id %" B_PRIdINO " requested!\n", id); return B_BAD_VALUE; } Inode* inode = new(std::nothrow) Inode(volume, id); if (inode == NULL) return B_NO_MEMORY; status_t status = inode->InitCheck(); if (status != B_OK) delete inode; if (status == B_OK) { _node->private_node = inode; _node->ops = &gExt2VnodeOps; *_type = inode->Mode(); *_flags = 0; } else ERROR("get_vnode: InitCheck() failed. Error: %s\n", strerror(status)); return status; }
static status_t ext2_read_attr_dir(fs_volume* _volume, fs_vnode* _node, void* _cookie, struct dirent* dirent, size_t bufferSize, uint32* _num) { Inode* inode = (Inode*)_node->private_node; int32 index = *(int32 *)_cookie; Attribute attribute(inode); TRACE("%s()\n", __FUNCTION__); size_t length = bufferSize; status_t status = attribute.Find(index); if (status == B_ENTRY_NOT_FOUND) { *_num = 0; return B_OK; } else if (status != B_OK) return status; status = attribute.GetName(dirent->d_name, &length); if (status != B_OK) return B_OK; Volume* volume = (Volume*)_volume->private_volume; dirent->d_dev = volume->ID(); dirent->d_ino = inode->ID(); dirent->d_reclen = sizeof(struct dirent) + length; *_num = 1; *(int32*)_cookie = index + 1; return B_OK; }
static status_t ext2_read_stat(fs_volume* _volume, fs_vnode* _node, struct stat* stat) { Inode* inode = (Inode*)_node->private_node; const ext2_inode& node = inode->Node(); stat->st_dev = inode->GetVolume()->ID(); stat->st_ino = inode->ID(); stat->st_nlink = node.NumLinks(); stat->st_blksize = EXT2_IO_SIZE; stat->st_uid = node.UserID(); stat->st_gid = node.GroupID(); stat->st_mode = node.Mode(); stat->st_type = 0; inode->GetAccessTime(&stat->st_atim); inode->GetModificationTime(&stat->st_mtim); inode->GetChangeTime(&stat->st_ctim); inode->GetCreationTime(&stat->st_crtim); stat->st_size = inode->Size(); stat->st_blocks = (inode->Size() + 511) / 512; return B_OK; }
static status_t fifo_write(fs_volume* _volume, fs_vnode* _node, void* _cookie, off_t /*pos*/, const void* buffer, size_t* _length) { file_cookie* cookie = (file_cookie*)_cookie; Inode* inode = (Inode*)_node->private_node; TRACE("fifo_write(vnode = %p, cookie = %p, length = %lu)\n", _node, cookie, *_length); MutexLocker locker(inode->RequestLock()); if ((cookie->open_mode & O_RWMASK) != O_WRONLY) return B_NOT_ALLOWED; size_t length = *_length; if (length == 0) return B_OK; // copy data into ring buffer status_t status = inode->WriteDataToBuffer(buffer, &length, (cookie->open_mode & O_NONBLOCK) != 0, is_called_via_syscall()); if (length > 0) status = B_OK; *_length = length; return status; }
static status_t nfs4_open_dir(fs_volume* volume, fs_vnode* vnode, void** _cookie) { FileSystem* fs = reinterpret_cast<FileSystem*>(volume->private_volume); OpenDirCookie* cookie = new(std::nothrow) OpenDirCookie(fs); if (cookie == NULL) return B_NO_MEMORY; *_cookie = cookie; VnodeToInode* vti = reinterpret_cast<VnodeToInode*>(vnode->private_node); TRACE("volume = %p, vnode = %" B_PRIi64, volume, vti->ID()); VnodeToInodeLocker _(vti); Inode* inode = vti->Get(); if (inode == NULL) return B_ENTRY_NOT_FOUND; status_t result = inode->OpenDir(cookie); if (result != B_OK) delete cookie; TRACE("*cookie = %p", *_cookie); return result; }
void collectFiles(Disk &disk,Directory *directory) { if (directory == NULL) return; directory->Rewind(); char name[B_FILE_NAME_LENGTH]; block_run run; while (directory->GetNextEntry(name,&run) >= B_OK) { if (!strcmp(name,".") || !strcmp(name,"..")) continue; gHashtable.Put(run); if (++gCount % 50 == 0) printf(" %7Ld%s1A\n",gCount,gEscape); Inode *inode = Inode::Factory(&disk,run); if (inode != NULL) { if (inode->IsDirectory()) collectFiles(disk,static_cast<Directory *>(inode)); delete inode; } else printf(" Directory \"%s\" (%ld, %d) points to corrupt inode \"%s\" (%ld, %d)\n", directory->Name(),directory->BlockRun().allocation_group,directory->BlockRun().start, name,run.allocation_group,run.start); } }
static status_t btrfs_read_link(fs_volume *_volume, fs_vnode *_node, char *buffer, size_t *_bufferSize) { Inode* inode = (Inode*)_node->private_node; return inode->ReadAt(0, (uint8*)buffer, _bufferSize); }
static status_t nfs4_open(fs_volume* volume, fs_vnode* vnode, int openMode, void** _cookie) { VnodeToInode* vti = reinterpret_cast<VnodeToInode*>(vnode->private_node); TRACE("volume = %p, vnode = %" B_PRIi64 ", openMode = %d", volume, vti->ID(), openMode); VnodeToInodeLocker _(vti); Inode* inode = vti->Get(); if (inode == NULL) return B_ENTRY_NOT_FOUND; if (inode->Type() == S_IFDIR || inode->Type() == S_IFLNK) { *_cookie = NULL; return B_OK; } FileSystem* fs = reinterpret_cast<FileSystem*>(volume->private_volume); OpenFileCookie* cookie = new OpenFileCookie(fs); if (cookie == NULL) return B_NO_MEMORY; *_cookie = cookie; status_t result = inode->Open(openMode, cookie); if (result != B_OK) delete cookie; TRACE("*cookie = %p", *_cookie); return result; }
static status_t btrfs_io(fs_volume* _volume, fs_vnode* _node, void* _cookie, io_request* request) { Volume* volume = (Volume*)_volume->private_volume; Inode* inode = (Inode*)_node->private_node; #ifndef BTRFS_SHELL if (io_request_is_write(request) && volume->IsReadOnly()) { notify_io_request(request, B_READ_ONLY_DEVICE); return B_READ_ONLY_DEVICE; } #endif if (inode->FileCache() == NULL) { #ifndef BTRFS_SHELL notify_io_request(request, B_BAD_VALUE); #endif return B_BAD_VALUE; } // We lock the node here and will unlock it in the "finished" hook. rw_lock_read_lock(inode->Lock()); return do_iterative_fd_io(volume->Device(), request, iterative_io_get_vecs_hook, iterative_io_finished_hook, inode); }
static status_t nfs4_get_vnode(fs_volume* volume, ino_t id, fs_vnode* vnode, int* _type, uint32* _flags, bool reenter) { FileSystem* fs = reinterpret_cast<FileSystem*>(volume->private_volume); TRACE("volume = %p, id = %" B_PRIi64, volume, id); VnodeToInode* vnodeToInode = new VnodeToInode(id, fs); if (vnodeToInode == NULL) return B_NO_MEMORY; Inode* inode; status_t result = fs->GetInode(id, &inode); if (result != B_OK) { delete vnodeToInode; return result; } vnodeToInode->Replace(inode); vnode->ops = &gNFSv4VnodeOps; vnode->private_node = vnodeToInode; *_type = inode->Type(); *_flags = 0; return B_OK; }
static status_t nfs4_create_dir(fs_volume* volume, fs_vnode* parent, const char* name, int mode) { VnodeToInode* vti = reinterpret_cast<VnodeToInode*>(parent->private_node); TRACE("volume = %p, parent = %" B_PRIi64 ", mode = %d", volume, vti->ID(), mode); VnodeToInodeLocker _(vti); Inode* inode = vti->Get(); if (inode == NULL) return B_ENTRY_NOT_FOUND; ino_t id; status_t result = inode->CreateDir(name, mode, &id); if (result != B_OK) return result; result = get_vnode(volume, id, reinterpret_cast<void**>(&vti)); if (result == B_OK) { unremove_vnode(volume, id); vti->Clear(); put_vnode(volume, id); } return B_OK; }
//! btrfs_io() callback hook static status_t iterative_io_finished_hook(void* cookie, io_request* request, status_t status, bool partialTransfer, size_t bytesTransferred) { Inode* inode = (Inode*)cookie; rw_lock_read_unlock(inode->Lock()); return B_OK; }
Inode::Inode(const Inode& orig) { this->address = orig.getAddress(); this->type = orig.getType(); for (int i = 0; i < MAX_ADDRESS_COUNT; i++) { this->dataaddress[i] = orig.getDataAddress(i); } this->filesize = orig.getFileSize(); }
//! btrfs_io() callback hook static status_t iterative_io_get_vecs_hook(void* cookie, io_request* request, off_t offset, size_t size, struct file_io_vec* vecs, size_t* _count) { Inode* inode = (Inode*)cookie; return file_map_translate(inode->Map(), offset, size, vecs, _count, inode->GetVolume()->BlockSize()); }
Inode *InodeFactory::allocInode(FsMaker *fs, TARINO pino, File *file) { Inode *inode = InodeFactory::allocInode(fs, pino, file->getFtype()); if (inode) { inode->setFile(file); if (file->getFtype() == TARFS_IFREG) { InodeFactory::totalDataSize += file->getBlocks(); } } return inode; }
static status_t ext2_unlink(fs_volume* _volume, fs_vnode* _directory, const char* name) { TRACE("ext2_unlink()\n"); if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) return B_NOT_ALLOWED; Volume* volume = (Volume*)_volume->private_volume; Inode* directory = (Inode*)_directory->private_node; status_t status = directory->CheckPermissions(W_OK); if (status != B_OK) return status; TRACE("ext2_unlink(): Starting transaction\n"); Transaction transaction(volume->GetJournal()); directory->WriteLockInTransaction(transaction); TRACE("ext2_unlink(): Looking up for directory entry\n"); HTree htree(volume, directory); DirectoryIterator* directoryIterator; status = htree.Lookup(name, &directoryIterator); if (status != B_OK) return status; ino_t id; status = directoryIterator->FindEntry(name, &id); if (status != B_OK) return status; Vnode vnode(volume, id); Inode* inode; status = vnode.Get(&inode); if (status != B_OK) return status; inode->WriteLockInTransaction(transaction); status = inode->Unlink(transaction); if (status != B_OK) return status; status = directoryIterator->RemoveEntry(transaction); if (status != B_OK) return status; entry_cache_remove(volume->ID(), directory->ID(), name); status = transaction.Done(); if (status != B_OK) entry_cache_add(volume->ID(), directory->ID(), name, id); else notify_entry_removed(volume->ID(), directory->ID(), name, id); return status; }
Inode *InodeFactory::getInode(FsIO *fsio, TARINO ino, TARINO pino) { Inode *inode; TARBLK blkno; InodeFactory::freeInode->getBlock(fsio, ino, &blkno); inode = new Inode(ino, pino, blkno, fsio); if (inode && inode->isDir()) { delete inode; inode = new Dir(ino, pino, blkno, fsio); } return inode; }
static status_t nfs4_remove_attr(fs_volume* volume, fs_vnode* vnode, const char* name) { VnodeToInode* vti = reinterpret_cast<VnodeToInode*>(vnode->private_node); VnodeToInodeLocker _(vti); Inode* inode = vti->Get(); if (inode == NULL) return B_ENTRY_NOT_FOUND; return inode->Remove(name, NF4NAMEDATTR, NULL); }
static status_t btrfs_free_cookie(fs_volume* _volume, fs_vnode* _node, void* _cookie) { file_cookie* cookie = (file_cookie*)_cookie; Volume* volume = (Volume*)_volume->private_volume; Inode* inode = (Inode*)_node->private_node; if (inode->Size() != cookie->last_size) notify_stat_changed(volume->ID(), inode->ID(), B_STAT_SIZE); delete cookie; return B_OK; }
static status_t fifo_set_flags(fs_volume* _volume, fs_vnode* _node, void* _cookie, int flags) { Inode* inode = (Inode*)_node->private_node; file_cookie* cookie = (file_cookie*)_cookie; TRACE("fifo_set_flags(vnode = %p, flags = %x)\n", _vnode, flags); MutexLocker locker(inode->RequestLock()); cookie->open_mode = (cookie->open_mode & ~(O_APPEND | O_NONBLOCK)) | flags; return B_OK; }
static status_t btrfs_read(fs_volume* _volume, fs_vnode* _node, void* _cookie, off_t pos, void* buffer, size_t* _length) { Inode* inode = (Inode*)_node->private_node; if (!inode->IsFile()) { *_length = 0; return inode->IsDirectory() ? B_IS_A_DIRECTORY : B_BAD_VALUE; } return inode->ReadAt(pos, (uint8*)buffer, _length); }
static status_t nfs4_fsync(fs_volume* volume, fs_vnode* vnode) { VnodeToInode* vti = reinterpret_cast<VnodeToInode*>(vnode->private_node); TRACE("volume = %p, vnode = %" B_PRIi64, volume, vti->ID()); VnodeToInodeLocker _(vti); Inode* inode = vti->Get(); if (inode == NULL) return B_ENTRY_NOT_FOUND; return inode->SyncAndCommit(); }
static status_t nfs4_access(fs_volume* volume, fs_vnode* vnode, int mode) { VnodeToInode* vti = reinterpret_cast<VnodeToInode*>(vnode->private_node); TRACE("volume = %p, vnode = %" B_PRIi64 ", mode = %d", volume, vti->ID(), mode); VnodeToInodeLocker _(vti); Inode* inode = vti->Get(); if (inode == NULL) return B_ENTRY_NOT_FOUND; return inode->Access(mode); }
static status_t nfs4_read_symlink(fs_volume* volume, fs_vnode* link, char* buffer, size_t* _bufferSize) { VnodeToInode* vti = reinterpret_cast<VnodeToInode*>(link->private_node); TRACE("volume = %p, link = %" B_PRIi64, volume, vti->ID()); VnodeToInodeLocker _(vti); Inode* inode = vti->Get(); if (inode == NULL) return B_ENTRY_NOT_FOUND; return inode->ReadLink(buffer, _bufferSize); }
static status_t nfs4_write_attr(fs_volume* volume, fs_vnode* vnode, void* _cookie, off_t pos, const void* buffer, size_t* length) { VnodeToInode* vti = reinterpret_cast<VnodeToInode*>(vnode->private_node); OpenAttrCookie* cookie = reinterpret_cast<OpenAttrCookie*>(_cookie); VnodeToInodeLocker _(vti); Inode* inode = vti->Get(); if (inode == NULL) return B_ENTRY_NOT_FOUND; return inode->WriteDirect(cookie, pos, buffer, length); }
static status_t nfs4_write_attr_stat(fs_volume* volume, fs_vnode* vnode, void* _cookie, const struct stat* stat, int statMask) { VnodeToInode* vti = reinterpret_cast<VnodeToInode*>(vnode->private_node); OpenAttrCookie* cookie = reinterpret_cast<OpenAttrCookie*>(_cookie); VnodeToInodeLocker _(vti); Inode* inode = vti->Get(); if (inode == NULL) return B_ENTRY_NOT_FOUND; return inode->WriteStat(stat, statMask, cookie); }