# HG changeset patch # User Paul Boddie # Date 1641335273 -3600 # Node ID ded81f25f1aae24d7f01f88f83b2d0e10a8ea1f4 # Parent 4bbc322d2b94df24828ec2c40e722c17e3b2412e Added unlinking and removal functionality. diff -r 4bbc322d2b94 -r ded81f25f1aa libe2access/include/e2access/image.h --- a/libe2access/include/e2access/image.h Tue Jan 04 19:22:01 2022 +0100 +++ b/libe2access/include/e2access/image.h Tue Jan 04 23:27:53 2022 +0100 @@ -67,6 +67,14 @@ errcode_t image_stat_inode(ext2_filsys fs, ext2_ino_t ino, struct stat *st); +errcode_t image_remove_by_inode(ext2_filsys fs, ext2_ino_t ino); + +errcode_t image_unlink_by_name(ext2_filsys fs, ext2_ino_t ino_parent, + const char *basename); + +errcode_t image_unlink_by_inode(ext2_filsys fs, ext2_ino_t ino_parent, + ext2_ino_t ino); + int _image_isdir(ext2_filsys fs, ext2_ino_t ino); int image_isdir(ext2_filsys fs, const char *name); diff -r 4bbc322d2b94 -r ded81f25f1aa libe2access/lib/src/image.c --- a/libe2access/lib/src/image.c Tue Jan 04 19:22:01 2022 +0100 +++ b/libe2access/lib/src/image.c Tue Jan 04 23:27:53 2022 +0100 @@ -195,7 +195,6 @@ void *), void *data) { - const char *path_orig = path; char *buf; ext2_ino_t ino; errcode_t retval; @@ -344,6 +343,70 @@ return 0; } +/* Remove an inode. */ + +errcode_t image_remove_by_inode(ext2_filsys fs, ext2_ino_t ino) +{ + struct ext2_inode_large inode; + errcode_t err = ext2fs_read_inode_full(fs, ino, (struct ext2_inode *) &inode, + sizeof(inode)); + + /* Handle invalid inodes, ignore unreferenced inodes. */ + + if (err) + return err; + + if (!inode.i_links_count) + return 0; + + /* Decrement the reference count. With no more references to the inode, + remove its resources. */ + + inode.i_links_count--; + + if (!inode.i_links_count) + { + err = ext2fs_free_ext_attr(fs, ino, &inode); + + if (!err) + { + /* Deallocate blocks, if appropriate. ~0ULL as the end represents + truncation. */ + + if (ext2fs_inode_has_valid_blocks2(fs, (struct ext2_inode *) &inode)) + { + err = ext2fs_punch(fs, ino, (struct ext2_inode *) &inode, NULL, + 0, ~0ULL); + + /* Update allocation statistics. */ + + if (!err) + ext2fs_inode_alloc_stats2(fs, ino, -1, + LINUX_S_ISDIR(inode.i_mode)); + } + } + } + + return ext2fs_write_inode_full(fs, ino, (struct ext2_inode *) &inode, + sizeof(inode)); +} + +/* Unlink a directory entry by name. */ + +errcode_t image_unlink_by_name(ext2_filsys fs, ext2_ino_t ino_parent, + const char *basename) +{ + return ext2fs_unlink(fs, ino_parent, basename, 0, 0); +} + +/* Unlink a directory entry by inode number. */ + +errcode_t image_unlink_by_inode(ext2_filsys fs, ext2_ino_t ino_parent, + ext2_ino_t ino) +{ + return ext2fs_unlink(fs, ino_parent, 0, ino, 0); +} + /* Test object types in the filesystem image. */ int _image_isdir(ext2_filsys fs, ext2_ino_t ino)