aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaulo Alcantara <pcacjr@gmail.com>2011-09-20 02:45:19 +0000
committerPaulo Alcantara <pcacjr@gmail.com>2011-09-20 02:45:19 +0000
commitd2240176af6ac239216b160611ed74d481095a4b (patch)
tree58b7a8dc685ac3d409f168b74f2f846ab3f7ab88
parent7e6065d5d1d8346683abf2f894d59c703fa60d87 (diff)
downloadsyslinux-d2240176af6ac239216b160611ed74d481095a4b.tar.gz
syslinux-d2240176af6ac239216b160611ed74d481095a4b.tar.xz
syslinux-d2240176af6ac239216b160611ed74d481095a4b.zip
ntfs: keep a state structure for ntfs_readdir() callers
Latetly, we kept a state information within the inode structure, that was actually a mistake. Now, a ntfs_readdir_state structure is allocated to keep a state that'll help on listing directory entries from sucessive ntfs_readdir() calls. Signed-off-by: Paulo Alcantara <pcacjr@gmail.com>
-rw-r--r--core/fs/ntfs/ntfs.c49
-rw-r--r--core/fs/ntfs/ntfs.h17
2 files changed, 45 insertions, 21 deletions
diff --git a/core/fs/ntfs/ntfs.c b/core/fs/ntfs/ntfs.c
index 1dc89e3b..9a0408d4 100644
--- a/core/fs/ntfs/ntfs.c
+++ b/core/fs/ntfs/ntfs.c
@@ -35,6 +35,8 @@
#include "ntfs.h"
#include "runlist.h"
+static struct ntfs_readdir_state *readdir_state;
+
/*** Function declarations */
static f_mft_record_lookup ntfs_mft_record_lookup_3_0;
static f_mft_record_lookup ntfs_mft_record_lookup_3_1;
@@ -474,7 +476,20 @@ static int index_inode_setup(struct fs_info *fs, unsigned long mft_no,
goto out;
}
- NTFS_PVT(inode)->in_idx_root = true;
+ /* check if we have a previous allocated state structure */
+ if (readdir_state) {
+ free(readdir_state);
+ readdir_state = NULL;
+ }
+
+ /* allocate our state structure */
+ readdir_state = malloc(sizeof *readdir_state);
+ if (!readdir_state)
+ malloc_error("ntfs_readdir_state structure");
+
+ readdir_state->mft_no = mft_no;
+ /* obviously, the ntfs_readdir() caller will start from INDEX root */
+ readdir_state->in_idx_root = true;
} else if (d_type == DT_REG) { /* file stuff */
dprintf("Got a file.\n");
attr = ntfs_attr_lookup(NTFS_AT_DATA, mrec);
@@ -886,20 +901,20 @@ static int ntfs_readdir(struct file *file, struct dirent *dirent)
if ((uint8_t *)ir + len > (uint8_t *)mrec + NTFS_SB(fs)->mft_record_size)
goto index_err;
- if (!file->offset && NTFS_PVT(inode)->in_idx_root) {
+ if (!file->offset && readdir_state->in_idx_root) {
file->offset = (uint32_t)((uint8_t *)&ir->index +
ir->index.entries_offset);
}
idx_root_next_entry:
- if (NTFS_PVT(inode)->in_idx_root) {
+ if (readdir_state->in_idx_root) {
ie = (struct ntfs_idx_entry *)(uint8_t *)file->offset;
if (ie->flags & INDEX_ENTRY_END) {
file->offset = 0;
- NTFS_PVT(inode)->in_idx_root = false;
- NTFS_PVT(inode)->idx_blks_count = 1;
- NTFS_PVT(inode)->entries_count = 0;
- NTFS_PVT(inode)->last_vcn = 0;
+ readdir_state->in_idx_root = false;
+ readdir_state->idx_blks_count = 1;
+ readdir_state->entries_count = 0;
+ readdir_state->last_vcn = 0;
goto descend_into_child_node;
}
@@ -928,7 +943,7 @@ descend_into_child_node:
next_run:
stream = mapping_chunk_init(attr, &chunk, &offset);
- count = NTFS_PVT(inode)->idx_blks_count;
+ count = readdir_state->idx_blks_count;
while (count--) {
err = parse_data_run(stream, &offset, attr_len, &chunk);
if (err) {
@@ -943,15 +958,15 @@ next_run:
}
if (chunk.flags & MAP_UNALLOCATED) {
- NTFS_PVT(inode)->idx_blks_count++;
+ readdir_state->idx_blks_count++;
goto next_run;
}
next_vcn:
- vcn = NTFS_PVT(inode)->last_vcn;
+ vcn = readdir_state->last_vcn;
if (vcn >= chunk.len) {
- NTFS_PVT(inode)->last_vcn = 0;
- NTFS_PVT(inode)->idx_blks_count++;
+ readdir_state->last_vcn = 0;
+ readdir_state->idx_blks_count++;
goto next_run;
}
@@ -978,7 +993,7 @@ next_vcn:
idx_block_next_entry:
ie = (struct ntfs_idx_entry *)((uint8_t *)&iblk->index +
iblk->index.entries_offset);
- count = NTFS_PVT(inode)->entries_count;
+ count = readdir_state->entries_count;
for ( ; count--; ie = (struct ntfs_idx_entry *)((uint8_t *)ie + ie->len)) {
/* bounds checks */
if ((uint8_t *)ie < (uint8_t *)iblk || (uint8_t *)ie +
@@ -991,14 +1006,14 @@ idx_block_next_entry:
/* last entry cannot contain a key */
if (ie->flags & INDEX_ENTRY_END) {
/* go to the next VCN */
- NTFS_PVT(inode)->last_vcn += (blk_size / (1 <<
+ readdir_state->last_vcn += (blk_size / (1 <<
NTFS_SB(fs)->clust_byte_shift));
- NTFS_PVT(inode)->entries_count = 0;
+ readdir_state->entries_count = 0;
goto next_vcn;
}
}
- NTFS_PVT(inode)->entries_count++;
+ readdir_state->entries_count++;
len = ntfs_cvt_filename(filename, ie);
if (!is_filename_printable(filename))
goto idx_block_next_entry;
@@ -1006,7 +1021,7 @@ idx_block_next_entry:
goto done;
out:
- NTFS_PVT(inode)->in_idx_root = true;
+ readdir_state->in_idx_root = true;
free(mrec);
diff --git a/core/fs/ntfs/ntfs.h b/core/fs/ntfs/ntfs.h
index cd8b9984..6620a27d 100644
--- a/core/fs/ntfs/ntfs.h
+++ b/core/fs/ntfs/ntfs.h
@@ -83,10 +83,6 @@ struct ntfs_inode {
uint16_t seq_no; /* Sequence number of the mft record */
uint32_t type; /* Attribute type of this inode */
uint8_t non_resident;
- bool in_idx_root;
- uint32_t idx_blks_count;
- uint32_t entries_count;
- int64_t last_vcn;
union { /* Non-resident $DATA attribute */
struct { /* Used only if non_resident flags isn't set */
uint32_t offset; /* Data offset */
@@ -101,6 +97,19 @@ struct ntfs_inode {
sector_t here; /* Sector corresponding to offset */
};
+/* This is structure is used to keep a state for ntfs_readdir() callers.
+ * As NTFS stores directory entries in a complex way, this is structure
+ * ends up saving a state required to find out where we must start from
+ * for the next ntfs_readdir() call.
+ */
+struct ntfs_readdir_state {
+ unsigned long mft_no; /* MFT record number */
+ bool in_idx_root; /* It's true if we're still in the INDEX root */
+ uint32_t idx_blks_count; /* Number of read INDX blocks */
+ uint32_t entries_count; /* Number of read INDEX entries */
+ int64_t last_vcn; /* Last VCN of the INDX block */
+};
+
enum {
MAP_UNSPEC,
MAP_START = 1 << 0,