-
Notifications
You must be signed in to change notification settings - Fork 110
/
op_readdir.c
64 lines (51 loc) · 1.71 KB
/
op_readdir.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/*
* Copyright (c) 2010, Gerard Lledó Vives, [email protected]
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. See README and COPYING for
* more details.
*/
#include <string.h>
#include <fuse.h>
#include "common.h"
#include "inode.h"
#include "logging.h"
static char *get_printable_name(char *s, struct ext4_dir_entry_2 *entry)
{
memcpy(s, entry->name, entry->name_len);
s[entry->name_len] = 0;
return s;
}
int op_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
off_t offset, struct fuse_file_info *fi)
{
DEBUG("readdir");
UNUSED(fi);
char name_buf[EXT4_NAME_LEN];
struct ext4_dir_entry_2 *dentry = NULL;
struct ext4_inode inode;
/* We can use inode_get_by_number, but first we need to implement opendir */
int ret = inode_get_by_path(path, &inode);
if (ret < 0) {
return ret;
}
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;
if (!dentry->inode) {
/* It seems that is possible to have a dummy entry like this at the
* begining of a block of dentries. Looks like skipping is the
* reasonable thing to do. */
continue;
}
/* Providing offset to the filler function seems slower... */
get_printable_name(name_buf, dentry);
if (name_buf[0]) {
if (filler(buf, name_buf, NULL, offset) != 0) break;
}
}
inode_dir_ctx_put(dctx);
return 0;
}