static int do_ext2fs_rmdir()

in fs/extfs/extfs.cpp [323:368]


static int do_ext2fs_rmdir(ext2_filsys fs, const char *path) {
    ext2_ino_t ino;
    errcode_t ret = 0;
    struct rd_struct rds;

    DEFER(LOG_DEBUG("rmdir ", VALUE(path), VALUE(ino), VALUE(ret)));
    ino = string_to_inode(fs, path, 0, true);
    if (ino == 0) {
        return -(ret = ENOENT);
    }

    rds.parent = 0;
    rds.empty = 1;

    ret = ext2fs_dir_iterate2(fs, ino, 0, 0, rmdir_proc, &rds);
    if (ret) return parse_extfs_error(fs, ino, ret);

    if (rds.empty == 0) {
        return -(ret = ENOTEMPTY);
    }

    ret = unlink_file_by_name(fs, path);
    if (ret) return ret;
    /* Directories have to be "removed" twice. */
    ret = remove_inode(fs, ino);
    if (ret) return ret;
    ret = remove_inode(fs, ino);
    if (ret) return ret;

    if (rds.parent) {
        struct ext2_inode_large inode;
        memset(&inode, 0, sizeof(inode));
        ret = ext2fs_read_inode_full(fs, rds.parent, (struct ext2_inode *)&inode, sizeof(inode));
        if (ret) return parse_extfs_error(fs, rds.parent, ret);

        if (inode.i_links_count > 1)
            inode.i_links_count--;
        // update_mtime
        ret = update_xtime(fs, rds.parent, (struct ext2_inode *)&inode, EXT_CTIME | EXT_MTIME);
        if (ret) return ret;
        ret = ext2fs_write_inode_full(fs, rds.parent, (struct ext2_inode *)&inode, sizeof(inode));
        if (ret) return parse_extfs_error(fs, rds.parent, ret);
    }

    return 0;
}