diff --git a/src/add-ons/kernel/file_systems/layers/attribute_overlay/attribute_overlay.cpp b/src/add-ons/kernel/file_systems/layers/attribute_overlay/attribute_overlay.cpp index 4f524021b7..b4d17873c8 100644 --- a/src/add-ons/kernel/file_systems/layers/attribute_overlay/attribute_overlay.cpp +++ b/src/add-ons/kernel/file_systems/layers/attribute_overlay/attribute_overlay.cpp @@ -74,6 +74,7 @@ public: status_t GetAttributeFile(AttributeFile **attributeFile); status_t WriteAttributeFile(); + status_t RemoveAttributeFile(); private: OverlayVolume * fVolume; @@ -97,6 +98,8 @@ public: status_t CreateEmpty(); status_t WriteAttributeFile(fs_volume *overlay, fs_volume *volume, fs_vnode *vnode); + status_t RemoveAttributeFile(fs_volume *overlay, + fs_volume *volume, fs_vnode *vnode); status_t ReadAttributeDir(struct dirent *dirent, size_t bufferSize, uint32 *numEntries, @@ -274,6 +277,21 @@ OverlayInode::WriteAttributeFile() } +status_t +OverlayInode::RemoveAttributeFile() +{ + if (fAttributeFile == NULL) + return B_NO_INIT; + + status_t result = fAttributeFile->InitCheck(); + if (result != B_OK) + return result; + + return fAttributeFile->RemoveAttributeFile(Volume(), SuperVolume(), + &fSuperVnode); +} + + // #pragma mark AttributeFile @@ -643,6 +661,51 @@ close_and_put: } +status_t +AttributeFile::RemoveAttributeFile(fs_volume *overlay, fs_volume *volume, + fs_vnode *vnode) +{ + if (fAttributeDirInode == 0 || fAttributeFileInode == 0) { + // there is no backing file at all yet + return B_OK; + } + + char nameBuffer[B_FILE_NAME_LENGTH]; + nameBuffer[sizeof(nameBuffer) - 1] = 0; + status_t result = vnode->ops->get_vnode_name(volume, vnode, nameBuffer, + sizeof(nameBuffer) - 1); + if (result != B_OK) { + TRACE_ALWAYS("failed to get vnode name: %s\n", strerror(result)); + return result; + } + + OverlayInode *overlayInode = NULL; + result = get_vnode(overlay, fAttributeDirInode, (void **)&overlayInode); + if (result != B_OK) { + TRACE_ALWAYS("getting attribute directory vnode failed: %s\n", + strerror(result)); + return result; + } + + fs_vnode attributeDir = *overlayInode->SuperVnode(); + if (attributeDir.ops->unlink == NULL) { + TRACE_ALWAYS("cannot remove attribute file, unlink hook missing\n"); + put_vnode(volume, fAttributeDirInode); + return B_UNSUPPORTED; + } + + result = attributeDir.ops->unlink(volume, &attributeDir, nameBuffer); + if (result != B_OK) { + TRACE_ALWAYS("failed to unlink attribute file: %s\n", strerror(result)); + put_vnode(volume, fAttributeDirInode); + return result; + } + + put_vnode(volume, fAttributeDirInode); + return B_OK; +} + + uint32 AttributeFile::CountAttributes() {