Skip to content

Commit

Permalink
Modify the inode_dir_ctx API to detach alloc and init
Browse files Browse the repository at this point in the history
This commit changes the inode_dir_ctx_* API so that allocation and
initialization are done in separate places.  This means that we can reuse
buffers more easily.

We use this fix to improve inode_get_idx_by_path (ie, path resolution):
instead of one buffer per directory in the path, we now use only one buffer
per path.
  • Loading branch information
gerard committed Jan 19, 2013
1 parent c45f405 commit 679406e
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 12 deletions.
23 changes: 14 additions & 9 deletions inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,14 @@ static void dir_ctx_update(struct ext4_inode *inode, uint32_t lblock, struct ino
ctx->lblock = lblock;
}

struct inode_dir_ctx *inode_dir_ctx_get(struct ext4_inode *inode)
struct inode_dir_ctx *inode_dir_ctx_get(void)
{
struct inode_dir_ctx *ret = malloc(sizeof(struct inode_dir_ctx) + BLOCK_SIZE);
dir_ctx_update(inode, 0, ret);
return malloc(sizeof(struct inode_dir_ctx) + BLOCK_SIZE);
}

return ret;
void inode_dir_ctx_reset(struct inode_dir_ctx *ctx, struct ext4_inode *inode)
{
dir_ctx_update(inode, 0, ctx);
}

void inode_dir_ctx_put(struct inode_dir_ctx *ctx)
Expand Down Expand Up @@ -154,7 +156,8 @@ static const char *skip_trailing_backslash(const char *path)

uint32_t inode_get_idx_by_path(const char *path)
{
uint32_t inode_idx;
struct inode_dir_ctx *dctx = inode_dir_ctx_get();
uint32_t inode_idx = 0;
struct ext4_inode inode;

/* Paths from fuse are always absolute */
Expand All @@ -174,10 +177,10 @@ uint32_t inode_get_idx_by_path(const char *path)
path = skip_trailing_backslash(path);
uint8_t path_len = get_path_token_len(path);

if (path_len == 0) return inode_idx;
if (path_len == 0) break;
inode_get_by_number(inode_idx, &inode);

struct inode_dir_ctx *dctx = inode_dir_ctx_get(&inode);
inode_dir_ctx_reset(dctx, &inode);
while ((dentry = inode_dentry_get(&inode, offset, dctx))) {
offset += dentry->rec_len;

Expand All @@ -193,12 +196,14 @@ uint32_t inode_get_idx_by_path(const char *path)
}
break;
}
inode_dir_ctx_put(dctx);

/* Couldn't find the entry at all */
if (dentry == NULL) return 0;
if (dentry == NULL) {
break;
}
} while((path = strchr(path, '/')));

inode_dir_ctx_put(dctx);
return inode_idx;
}

Expand Down
3 changes: 2 additions & 1 deletion inode.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ static inline uint64_t inode_get_size(struct ext4_inode *inode)

uint64_t inode_get_data_pblock(struct ext4_inode *inode, uint32_t lblock, uint32_t *extent_len);

struct inode_dir_ctx *inode_dir_ctx_get();
struct inode_dir_ctx *inode_dir_ctx_get(void);
void inode_dir_ctx_put(struct inode_dir_ctx *);
void inode_dir_ctx_reset(struct inode_dir_ctx *ctx, struct ext4_inode *inode);
struct ext4_dir_entry_2 *inode_dentry_get(struct ext4_inode *inode, off_t offset, struct inode_dir_ctx *ctx);

int inode_get_by_number(uint32_t n, struct ext4_inode *inode);
Expand Down
4 changes: 2 additions & 2 deletions op_readdir.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ int op_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
UNUSED(fi);
char name_buf[EXT4_NAME_LEN];
struct ext4_dir_entry_2 *dentry = NULL;
struct inode_dir_ctx *dctx = NULL;
struct ext4_inode inode;

/* We can use inode_get_by_number, but first we need to implement opendir */
Expand All @@ -41,7 +40,8 @@ int op_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
return ret;
}

dctx = inode_dir_ctx_get(&inode);
struct inode_dir_ctx *dctx = inode_dir_ctx_get();
inode_dir_ctx_reset(dctx, &inode);
while ((dentry = inode_dentry_get(&inode, offset, dctx))) {
offset += dentry->rec_len;

Expand Down

0 comments on commit 679406e

Please sign in to comment.