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; }
static status_t get_new_vnode(fs_volume* volume, ino_t id, VnodeToInode** _vti) { FileSystem* fs = reinterpret_cast<FileSystem*>(volume->private_volume); Inode* inode; VnodeToInode* vti; status_t result = acquire_vnode(volume, id); if (result == B_OK) { ASSERT(get_vnode(volume, id, reinterpret_cast<void**>(_vti)) == B_OK); unremove_vnode(volume, id); // Release after acquire put_vnode(volume, id); vti = *_vti; if (vti->Get() == NULL) { result = fs->GetInode(id, &inode); if (result != B_OK) { put_vnode(volume, id); return result; } vti->Replace(inode); } return B_OK; } return get_vnode(volume, id, reinterpret_cast<void**>(_vti)); }
static status_t nfs4_lookup(fs_volume* volume, fs_vnode* dir, const char* name, ino_t* _id) { VnodeToInode* vti = reinterpret_cast<VnodeToInode*>(dir->private_node); if (!strcmp(name, ".")) { *_id = vti->ID(); void* ptr; return get_vnode(volume, *_id, &ptr); } VnodeToInodeLocker locker(vti); Inode* inode = vti->Get(); if (inode == NULL) return B_ENTRY_NOT_FOUND; TRACE("volume = %p, dir = %" B_PRIi64 ", name = %s", volume, vti->ID(), name); status_t result = inode->LookUp(name, _id); if (result != B_OK) return result; locker.Unlock(); TRACE("*_id = %" B_PRIi64, *_id); // If VTI holds an outdated Inode next operation performed on it will // return either ERR_STALE or ERR_FHEXPIRED. Both of these error codes // will cause FileInfo data to be updated (the former will also cause Inode // object to be recreated). We are taking an optimistic (an lazy) approach // here. The following code just ensures VTI won't be removed too soon. void* ptr; result = get_vnode(volume, *_id, &ptr); if (result == B_OK) unremove_vnode(volume, *_id); return result; }
static status_t nfs4_rename(fs_volume* volume, fs_vnode* fromDir, const char* fromName, fs_vnode* toDir, const char* toName) { VnodeToInode* fromVti = reinterpret_cast<VnodeToInode*>(fromDir->private_node); VnodeToInode* toVti = reinterpret_cast<VnodeToInode*>(toDir->private_node); TRACE("volume = %p, fromDir = %" B_PRIi64 ", toDir = %" B_PRIi64 "," \ " fromName = %s, toName = %s", volume, fromVti->ID(), toVti->ID(), \ fromName, toName); VnodeToInodeLocker _from(fromVti); Inode* fromInode = fromVti->Get(); if (fromInode == NULL) return B_ENTRY_NOT_FOUND; VnodeToInodeLocker _to(toVti); Inode* toInode = toVti->Get(); if (toInode == NULL) return B_ENTRY_NOT_FOUND; ino_t id; ino_t oldID; status_t result = Inode::Rename(fromInode, toInode, fromName, toName, false, &id, &oldID); if (result != B_OK) return result; VnodeToInode* vti; if (oldID != 0) { // we have overriden an inode result = acquire_vnode(volume, oldID); if (result == B_OK) { result = get_vnode(volume, oldID, reinterpret_cast<void**>(&vti)); ASSERT(result == B_OK); if (vti->Unlink(toInode->fInfo.fNames, toName)) remove_vnode(volume, oldID); put_vnode(volume, oldID); put_vnode(volume, oldID); } } result = get_vnode(volume, id, reinterpret_cast<void**>(&vti)); if (result == B_OK) { Inode* child = vti->Get(); if (child == NULL) { put_vnode(volume, id); return B_ENTRY_NOT_FOUND; } unremove_vnode(volume, id); child->fInfo.fNames->RemoveName(fromInode->fInfo.fNames, fromName); child->fInfo.fNames->AddName(toInode->fInfo.fNames, toName); put_vnode(volume, id); } return B_OK; }
// UnremoveVNode status_t Volume::UnremoveVNode(Node *node) { return (fMounted ? unremove_vnode(GetID(), node->GetID()) : B_BAD_VALUE); }
// UnremoveVNode status_t Volume::UnremoveVNode(vnode_id vnid) { return unremove_vnode(fVolumeManager->GetID(), vnid); }