static status_t udf_lookup(fs_volume *_volume, fs_vnode *_directory, const char *file, ino_t *vnodeID) { TRACE(("udf_lookup: _directory = %p, filename = %s\n", _directory, file)); Volume *volume = (Volume *)_volume->private_volume; Icb *dir = (Icb *)_directory->private_node; Icb *node = NULL; status_t status = B_OK; if (strcmp(file, ".") == 0) { TRACE(("udf_lookup: file = ./\n")); *vnodeID = dir->Id(); status = get_vnode(volume->FSVolume(), *vnodeID, (void **)&node); if (status != B_OK) return B_ENTRY_NOT_FOUND; } else { status = dir->Find(file, vnodeID); if (status != B_OK) return status; Icb *icb; status = get_vnode(volume->FSVolume(), *vnodeID, (void **)&icb); if (status != B_OK) return B_ENTRY_NOT_FOUND; } TRACE(("udf_lookup: vnodeId = %Ld found!\n", *vnodeID)); return B_OK; }
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 btrfs_lookup(fs_volume* _volume, fs_vnode* _directory, const char* name, ino_t* _vnodeID) { TRACE("btrfs_lookup: name address: %p (%s)\n", name, 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; status = DirectoryIterator(directory).Lookup(name, strlen(name), _vnodeID); if (status != B_OK) return status; return get_vnode(volume->FSVolume(), *_vnodeID, NULL); }
static status_t ext2_create_dir(fs_volume* _volume, fs_vnode* _directory, const char* name, int mode) { TRACE("ext2_create_dir()\n"); Volume* volume = (Volume*)_volume->private_volume; Inode* directory = (Inode*)_directory->private_node; if (volume->IsReadOnly()) return B_READ_ONLY_DEVICE; if (!directory->IsDirectory()) return B_BAD_TYPE; status_t status = directory->CheckPermissions(W_OK); if (status != B_OK) return status; TRACE("ext2_create_dir(): Starting transaction\n"); Transaction transaction(volume->GetJournal()); ino_t id; status = Inode::Create(transaction, directory, name, S_DIRECTORY | (mode & S_IUMSK), 0, EXT2_TYPE_DIRECTORY, NULL, &id); if (status != B_OK) return status; put_vnode(volume->FSVolume(), id); entry_cache_add(volume->ID(), directory->ID(), name, id); status = transaction.Done(); if (status != B_OK) { entry_cache_remove(volume->ID(), directory->ID(), name); return status; } notify_entry_created(volume->ID(), directory->ID(), name, id); TRACE("ext2_create_dir(): Done\n"); return B_OK; }
static status_t ext2_create_symlink(fs_volume* _volume, fs_vnode* _directory, const char* name, const char* path, int mode) { TRACE("ext2_create_symlink()\n"); Volume* volume = (Volume*)_volume->private_volume; Inode* directory = (Inode*)_directory->private_node; if (volume->IsReadOnly()) return B_READ_ONLY_DEVICE; if (!directory->IsDirectory()) return B_BAD_TYPE; status_t status = directory->CheckPermissions(W_OK); if (status != B_OK) return status; TRACE("ext2_create_symlink(): Starting transaction\n"); Transaction transaction(volume->GetJournal()); Inode* link; ino_t id; status = Inode::Create(transaction, directory, name, S_SYMLINK | 0777, 0, (uint8)EXT2_TYPE_SYMLINK, NULL, &id, &link); if (status != B_OK) return status; // TODO: We have to prepare the link before publishing? size_t length = strlen(path); TRACE("ext2_create_symlink(): Path (%s) length: %d\n", path, (int)length); if (length < EXT2_SHORT_SYMLINK_LENGTH) { strcpy(link->Node().symlink, path); link->Node().SetSize((uint32)length); TRACE("ext2_create_symlink(): Publishing vnode\n"); publish_vnode(volume->FSVolume(), id, link, &gExt2VnodeOps, link->Mode(), 0); put_vnode(volume->FSVolume(), id); } else { TRACE("ext2_create_symlink(): Publishing vnode\n"); publish_vnode(volume->FSVolume(), id, link, &gExt2VnodeOps, link->Mode(), 0); put_vnode(volume->FSVolume(), id); if (!link->HasFileCache()) { status = link->CreateFileCache(); if (status != B_OK) return status; } size_t written = length; status = link->WriteAt(transaction, 0, (const uint8*)path, &written); if (status == B_OK && written != length) status = B_IO_ERROR; } if (status == B_OK) status = link->WriteBack(transaction); entry_cache_add(volume->ID(), directory->ID(), name, id); status = transaction.Done(); if (status != B_OK) { entry_cache_remove(volume->ID(), directory->ID(), name); return status; } notify_entry_created(volume->ID(), directory->ID(), name, id); TRACE("ext2_create_symlink(): Done\n"); return status; }