Skip to content

Commit

Permalink
file: replace magic dir_node number as an _init argument by setter.
Browse files Browse the repository at this point in the history
  • Loading branch information
Gottox committed Jun 2, 2024
1 parent 9755f40 commit ddd204d
Show file tree
Hide file tree
Showing 20 changed files with 224 additions and 130 deletions.
2 changes: 1 addition & 1 deletion examples/list_dir_ll.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ main(int argc, char *argv[]) {
const struct SqshSuperblock *superblock = sqsh_archive_superblock(archive);
uint64_t inode_root_ref = sqsh_superblock_inode_root_ref(superblock);
struct SqshFile *file =
sqsh_open_by_ref2(archive, inode_root_ref, 0, &error_code);
sqsh_open_by_ref(archive, inode_root_ref, &error_code);
if (error_code != 0) {
sqsh_perror(error_code, "sqsh_file_new");
return 1;
Expand Down
2 changes: 1 addition & 1 deletion examples/traverse_dir_ll.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ main(int argc, char *argv[]) {
const struct SqshSuperblock *superblock = sqsh_archive_superblock(archive);
uint64_t inode_root_ref = sqsh_superblock_inode_root_ref(superblock);
struct SqshFile *file =
sqsh_open_by_ref2(archive, inode_root_ref, 0, &error_code);
sqsh_open_by_ref(archive, inode_root_ref, &error_code);
if (error_code != 0) {
sqsh_perror(error_code, "sqsh_file_new");
return 1;
Expand Down
2 changes: 1 addition & 1 deletion fuzzer/simple.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ LLVMFuzzerTestOneInput(char *data, size_t size) {

superblock = sqsh_archive_superblock(archive);
uint64_t inode_ref = sqsh_superblock_inode_root_ref(superblock);
inode = sqsh_open_by_ref2(archive, inode_ref, 0, &rv);
inode = sqsh_open_by_ref(archive, inode_ref, &rv);
if (rv < 0) {
goto out;
}
Expand Down
1 change: 1 addition & 0 deletions include/sqsh_error.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ enum SqshError {
SQSH_ERROR_NO_SUCH_ELEMENT,
SQSH_ERROR_DIRECTORY_RECURSION,
SQSH_ERROR_INODE_PARENT_MISMATCH,
SQSH_ERROR_INODE_PARENT_UNSET,
SQSH_ERROR_NOT_A_SYMLINK,
};

Expand Down
21 changes: 8 additions & 13 deletions include/sqsh_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -285,29 +285,24 @@ sqsh_lopen(struct SqshArchive *archive, const char *path, int *err);
*
* @param archive The sqsh context to use.
* @param inode_ref The inode reference to initialize the context with.
* @param dir_inode The inode reference of the parent directory.
* @param[out] err Pointer to an int where the error code will be stored.
*
* @return a pointer to the sqsh context or NULL if an error occurred.
*/
SQSH_NO_UNUSED struct SqshFile *sqsh_open_by_ref2(
struct SqshArchive *archive, uint64_t inode_ref, uint32_t dir_inode,
int *err);
SQSH_NO_UNUSED struct SqshFile *
sqsh_open_by_ref(struct SqshArchive *archive, uint64_t inode_ref, int *err);

/**
* @deprecated Since 1.4.0. Use sqsh_open_by_ref2() instead.
* @memberof SqshFile
* @brief Initializes a file context in heap
* @brief returns whether the file is an extended structure.
*
* @param archive The sqsh context to use.
* @param inode_ref The inode reference to initialize the context with.
* @param[out] err Pointer to an int where the error code will be stored.
* @param[in] context The file context.
* @param[in] dir_inode The inode of the parent directory.
*
* @return a pointer to the sqsh context or NULL if an error occurred.
* @return int 0 on success, less than 0 on error.
*/
__attribute__((deprecated("Since 1.4.0. Use sqsh_open_by_ref2() instead.")))
SQSH_NO_UNUSED struct SqshFile *
sqsh_open_by_ref(struct SqshArchive *archive, uint64_t inode_ref, int *err);
SQSH_NO_UNUSED int
sqsh__file_set_dir_inode(struct SqshFile *context, uint32_t dir_inode);

/**
* @memberof SqshFile
Expand Down
17 changes: 13 additions & 4 deletions libsqsh/include/sqsh_file_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ struct SqshFile {
struct SqshArchive *archive;
const struct SqshInodeImpl *impl;
enum SqshFileType type;
bool has_dir_inode;
uint32_t dir_inode;
};

Expand All @@ -262,24 +263,32 @@ struct SqshFile {
* @param context The file context to initialize.
* @param sqsh The sqsh context.
* @param inode_ref The inode reference.
* @param dir_inode The inode number of the parent directory.
*
* @return int 0 on success, less than 0 on error.
*/
SQSH_NO_EXPORT SQSH_NO_UNUSED int sqsh__file_init(
struct SqshFile *context, struct SqshArchive *sqsh, uint64_t inode_ref,
uint32_t dir_inode);
struct SqshFile *context, struct SqshArchive *sqsh, uint64_t inode_ref);

/**
* @internal
* @memberof SqshFile
* @brief Retrieves the inode of the parent directory.
*
* @param context The file context.
* @return uint32_t The inode number.
* @return The inode number.
*/
SQSH_NO_EXPORT uint32_t sqsh__file_dir_inode(const struct SqshFile *context);

/**
* @internal
* @memberof SqshFile
* @brief Retrieves if the inode of the parent directory is set.
*
* @param context The file context.
* @return true if the dir_inode is set, false otherwise.
*/
bool sqsh__file_has_dir_inode(const struct SqshFile *context);

/**
* @internal
* @memberof SqshFile
Expand Down
2 changes: 1 addition & 1 deletion libsqsh/src/directory/directory_index_iterator.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ sqsh__directory_index_iterator_init(
int rv;
struct SqshFile *file = &iterator->file;

rv = sqsh__file_init(file, sqsh, inode_ref, /* TODO */ 0);
rv = sqsh__file_init(file, sqsh, inode_ref);
if (rv < 0) {
goto out;
}
Expand Down
9 changes: 7 additions & 2 deletions libsqsh/src/directory/directory_iterator.c
Original file line number Diff line number Diff line change
Expand Up @@ -409,8 +409,13 @@ sqsh_directory_iterator_open_file(
const uint32_t dir_inode = sqsh_file_inode(iterator->file);
struct SqshArchive *archive = iterator->file->archive;

file = sqsh_open_by_ref2(archive, inode_ref, dir_inode, &rv);
if (file == NULL) {
file = sqsh_open_by_ref(archive, inode_ref, &rv);
if (rv < 0) {
goto out;
}

rv = sqsh__file_set_dir_inode(file, dir_inode);
if (rv < 0) {
goto out;
}

Expand Down
109 changes: 56 additions & 53 deletions libsqsh/src/file/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
* @file file.c
*/

#include <assert.h>
#include <sqsh_file_private.h>

#include <cextras/memory.h>
Expand Down Expand Up @@ -135,48 +136,10 @@ inode_load(struct SqshFile *context) {
return rv;
}

static int
check_file_consistency(struct SqshFile *file) {
const uint32_t inode = sqsh_file_inode(file);
const uint32_t dir_inode = file->dir_inode;

// TODO: The checks are currently disabled when dir_inode is 0. This is
// because we want to keep the API stable and there is no way to retrieve
// the dir inode when opening a file by sqsh_open_by_ref. Remove this early
// return when v2 of libsqsh is released.
if (dir_inode == 0) {
return 0;
}

if (inode == dir_inode) {
return -SQSH_ERROR_INODE_PARENT_MISMATCH;
}

if (sqsh_file_type(file) != SQSH_FILE_TYPE_DIRECTORY) {
return 0;
}
/* directory specific checks */

const uint32_t parent_inode = sqsh_file_directory_parent_inode(file);
if (parent_inode != dir_inode) {
return -SQSH_ERROR_INODE_PARENT_MISMATCH;
}

if (sqsh__file_dir_inode(file) == 0) {
const struct SqshSuperblock *superblock =
sqsh_archive_superblock(file->archive);
if (file->inode_ref != sqsh_superblock_inode_root_ref(superblock)) {
return -SQSH_ERROR_INODE_PARENT_MISMATCH;
}
}

return 0;
}

int
sqsh__file_init(
struct SqshFile *inode, struct SqshArchive *archive, uint64_t inode_ref,
uint32_t dir_inode) {
struct SqshFile *inode, struct SqshArchive *archive,
uint64_t inode_ref) {
const uint64_t outer_offset = sqsh_address_ref_outer_offset(inode_ref);
const uint16_t inner_offset = sqsh_address_ref_inner_offset(inode_ref);
uint64_t address_outer;
Expand Down Expand Up @@ -214,8 +177,6 @@ sqsh__file_init(
goto out;
}

inode->dir_inode = dir_inode;

rv = sqsh_archive_inode_map(archive, &inode_map);
if (rv < 0) {
goto out;
Expand All @@ -226,9 +187,12 @@ sqsh__file_init(
goto out;
}

rv = check_file_consistency(inode);
if (rv < 0) {
goto out;
if (sqsh_file_type(inode) == SQSH_FILE_TYPE_DIRECTORY) {
uint32_t parent_inode = sqsh_file_directory_parent_inode(inode);
rv = sqsh__file_set_dir_inode(inode, parent_inode);
if (rv < 0) {
goto out;
}
}

out:
Expand All @@ -240,19 +204,44 @@ sqsh__file_init(

struct SqshFile *
sqsh_open_by_ref(struct SqshArchive *archive, uint64_t inode_ref, int *err) {
return sqsh_open_by_ref2(archive, inode_ref, 0, err);
SQSH_NEW_IMPL(sqsh__file_init, struct SqshFile, archive, inode_ref);
}

struct SqshFile *
sqsh_open_by_ref2(
struct SqshArchive *archive, uint64_t inode_ref, uint32_t dir_inode,
int *err) {
SQSH_NEW_IMPL(
sqsh__file_init, struct SqshFile, archive, inode_ref, dir_inode);
int
sqsh__file_set_dir_inode(struct SqshFile *file, uint32_t dir_inode) {
if (sqsh_file_inode(file) == dir_inode) {
return -SQSH_ERROR_INODE_PARENT_MISMATCH;
}

if (sqsh_file_type(file) == SQSH_FILE_TYPE_DIRECTORY) {
const uint32_t parent_inode = sqsh_file_directory_parent_inode(file);
if (parent_inode != dir_inode) {
return -SQSH_ERROR_INODE_PARENT_MISMATCH;
}

if (dir_inode == 0) {
const struct SqshSuperblock *superblock =
sqsh_archive_superblock(file->archive);
if (file->inode_ref != sqsh_superblock_inode_root_ref(superblock)) {
return -SQSH_ERROR_INODE_PARENT_MISMATCH;
}
}
}

file->dir_inode = dir_inode;
file->has_dir_inode = true;
return 0;
}

bool
sqsh__file_has_dir_inode(const struct SqshFile *context) {
return context->has_dir_inode;
}

uint32_t
sqsh__file_dir_inode(const struct SqshFile *context) {
assert(sqsh__file_has_dir_inode(context));

return context->dir_inode;
}

Expand Down Expand Up @@ -376,6 +365,10 @@ symlink_resolve(struct SqshFile *context, bool follow_symlinks) {
return -SQSH_ERROR_NOT_A_SYMLINK;
}

if (sqsh__file_has_dir_inode(context) == false) {
return -SQSH_ERROR_INODE_PARENT_UNSET;
}

struct SqshPathResolver resolver = {0};
rv = sqsh__path_resolver_init(&resolver, context->archive);
if (rv < 0) {
Expand All @@ -399,7 +392,11 @@ symlink_resolve(struct SqshFile *context, bool follow_symlinks) {
const uint64_t inode_ref = sqsh_path_resolver_inode_ref(&resolver);
const uint32_t dir_inode = sqsh_path_resolver_dir_inode(&resolver);
sqsh__file_cleanup(context);
rv = sqsh__file_init(context, context->archive, inode_ref, dir_inode);
rv = sqsh__file_init(context, context->archive, inode_ref);
if (rv < 0) {
goto out;
}
rv = sqsh__file_set_dir_inode(context, dir_inode);
if (rv < 0) {
goto out;
}
Expand Down Expand Up @@ -512,6 +509,12 @@ open_file(
goto out;
}

const uint32_t dir_inode = sqsh_path_resolver_dir_inode(&resolver);
rv = sqsh__file_set_dir_inode(inode, dir_inode);
if (rv < 0) {
goto out;
}

out:
if (err != NULL) {
*err = rv;
Expand Down
29 changes: 26 additions & 3 deletions libsqsh/src/tree/path_resolver.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ sqsh__path_resolver_to_ref(
int rv = 0;
rv = sqsh__file_cleanup(&resolver->cwd);

rv = sqsh__file_init(&resolver->cwd, resolver->archive, inode_ref, 0);
rv = sqsh__file_init(&resolver->cwd, resolver->archive, inode_ref);
if (rv < 0) {
goto out;
}
Expand Down Expand Up @@ -311,9 +311,28 @@ sqsh_path_resolver_dir_inode(const struct SqshPathResolver *resolver) {
struct SqshFile *
sqsh_path_resolver_open_file(
const struct SqshPathResolver *resolver, int *err) {
int rv = 0;
struct SqshFile *file = NULL;
uint32_t dir_inode = sqsh_path_resolver_dir_inode(resolver);
uint64_t inode_ref = resolver->current_inode_ref;
return sqsh_open_by_ref2(resolver->archive, inode_ref, dir_inode, err);
file = sqsh_open_by_ref(resolver->archive, inode_ref, &rv);
if (rv < 0) {
goto out;
}
rv = sqsh__file_set_dir_inode(file, dir_inode);
if (rv < 0) {
goto out;
}

out:
if (rv < 0) {
sqsh__file_cleanup(file);
file = NULL;
}
if (err != NULL) {
*err = rv;
}
return file;
}

enum SqshFileType
Expand Down Expand Up @@ -343,7 +362,11 @@ sqsh__path_resolver_follow_symlink(struct SqshPathResolver *resolver) {
}

struct SqshFile file = {0};
rv = sqsh__file_init(&file, resolver->archive, inode_ref, dir_inode);
rv = sqsh__file_init(&file, resolver->archive, inode_ref);
if (rv < 0) {
goto out;
}
rv = sqsh__file_set_dir_inode(&file, dir_inode);
if (rv < 0) {
goto out;
}
Expand Down
Loading

0 comments on commit ddd204d

Please sign in to comment.