}
static struct ntfs_attr_record *
-ntfs_attr_lookup(struct fs_info *fs, uint32_t type,
- struct ntfs_mft_record **mrec)
+__ntfs_attr_lookup(struct fs_info *fs, uint32_t type,
+ struct ntfs_mft_record **mrec)
{
struct ntfs_mft_record *_mrec = *mrec;
struct ntfs_attr_record *attr;
dprintf("in %s\n", __func__);
- /* sanity check */
if (!_mrec || type == NTFS_AT_END)
goto out;
return NULL;
}
+static inline struct ntfs_attr_record *
+ntfs_attr_lookup(struct fs_info *fs, uint32_t type,
+ struct ntfs_mft_record **mmrec,
+ struct ntfs_mft_record *mrec)
+{
+ struct ntfs_mft_record *_mrec = mrec;
+ struct ntfs_mft_record *other = *mmrec;
+ struct ntfs_attr_record *retval = NULL;
+
+ if (mrec == other)
+ return __ntfs_attr_lookup(fs, type, &other);
+
+ retval = __ntfs_attr_lookup(fs, type, &_mrec);
+ if (!retval) {
+ _mrec = other;
+ retval = __ntfs_attr_lookup(fs, type, &other);
+ if (!retval)
+ other = _mrec;
+ } else if (retval && (_mrec != mrec)) {
+ other = _mrec;
+ }
+
+ return retval;
+}
+
static inline enum dirent_type get_inode_mode(struct ntfs_mft_record *mrec)
{
return mrec->flags & MFT_RECORD_IS_DIRECTORY ? DT_DIR : DT_REG;
struct inode *inode)
{
uint64_t start_blk = 0;
- struct ntfs_mft_record *mrec;
+ struct ntfs_mft_record *mrec, *lmrec;
struct ntfs_attr_record *attr;
enum dirent_type d_type;
uint32_t len;
goto out;
}
+ lmrec = mrec;
+
NTFS_PVT(inode)->mft_no = mft_no;
NTFS_PVT(inode)->seq_no = mrec->seq_no;
d_type = get_inode_mode(mrec);
if (d_type == DT_DIR) { /* directory stuff */
dprintf("Got a directory.\n");
- attr = ntfs_attr_lookup(fs, NTFS_AT_INDEX_ROOT, &mrec);
+ attr = ntfs_attr_lookup(fs, NTFS_AT_INDEX_ROOT, &mrec, lmrec);
if (!attr) {
printf("No attribute found.\n");
goto out;
readdir_state->in_idx_root = true;
} else if (d_type == DT_REG) { /* file stuff */
dprintf("Got a file.\n");
- attr = ntfs_attr_lookup(fs, NTFS_AT_DATA, &mrec);
+ attr = ntfs_attr_lookup(fs, NTFS_AT_DATA, &mrec, lmrec);
if (!attr) {
printf("No attribute found.\n");
goto out;
static struct inode *ntfs_index_lookup(const char *dname, struct inode *dir)
{
struct fs_info *fs = dir->fs;
- struct ntfs_mft_record *mrec;
+ struct ntfs_mft_record *mrec, *lmrec;
block_t blk;
uint64_t blk_offset;
struct ntfs_attr_record *attr;
goto out;
}
- attr = ntfs_attr_lookup(fs, NTFS_AT_INDEX_ROOT, &mrec);
+ lmrec = mrec;
+ attr = ntfs_attr_lookup(fs, NTFS_AT_INDEX_ROOT, &mrec, lmrec);
if (!attr) {
printf("No attribute found.\n");
goto out;
ir = (struct ntfs_idx_root *)((uint8_t *)attr +
attr->data.resident.value_offset);
len = attr->data.resident.value_len;
- /* sanity check */
if ((uint8_t *)ir + len > (uint8_t *)mrec + NTFS_SB(fs)->mft_record_size)
goto index_err;
/* then descend into child node */
- attr = ntfs_attr_lookup(fs, NTFS_AT_INDEX_ALLOCATION, &mrec);
+ attr = ntfs_attr_lookup(fs, NTFS_AT_INDEX_ALLOCATION, &mrec, lmrec);
if (!attr) {
printf("No attribute found.\n");
goto out;
uint32_t ret;
struct fs_info *fs = file->fs;
struct inode *inode = file->inode;
- struct ntfs_mft_record *mrec;
+ struct ntfs_mft_record *mrec, *lmrec;
struct ntfs_attr_record *attr;
char *p;
goto out;
}
- attr = ntfs_attr_lookup(fs, NTFS_AT_DATA, &mrec);
+ lmrec = mrec;
+ attr = ntfs_attr_lookup(fs, NTFS_AT_DATA, &mrec, lmrec);
if (!attr) {
printf("No attribute found.\n");
goto out;
{
struct fs_info *fs = file->fs;
struct inode *inode = file->inode;
- struct ntfs_mft_record *mrec;
+ struct ntfs_mft_record *mrec, *lmrec;
block_t blk;
uint64_t blk_offset;
const uint64_t blk_size = UINT64_C(1) << BLOCK_SHIFT(fs);
goto out;
}
- attr = ntfs_attr_lookup(fs, NTFS_AT_INDEX_ROOT, &mrec);
+ lmrec = mrec;
+ attr = ntfs_attr_lookup(fs, NTFS_AT_INDEX_ROOT, &mrec, lmrec);
if (!attr) {
printf("No attribute found.\n");
goto out;
ir = (struct ntfs_idx_root *)((uint8_t *)attr +
attr->data.resident.value_offset);
len = attr->data.resident.value_len;
- /* sanity check */
if ((uint8_t *)ir + len > (uint8_t *)mrec + NTFS_SB(fs)->mft_record_size)
goto index_err;
if (!(ie->flags & INDEX_ENTRY_NODE))
goto out;
- attr = ntfs_attr_lookup(fs, NTFS_AT_INDEX_ALLOCATION, &mrec);
+ attr = ntfs_attr_lookup(fs, NTFS_AT_INDEX_ALLOCATION, &mrec, lmrec);
if (!attr)
goto out;
static struct inode *ntfs_iget_root(struct fs_info *fs)
{
uint64_t start_blk;
- struct ntfs_mft_record *mrec;
+ struct ntfs_mft_record *mrec, *lmrec;
struct ntfs_attr_record *attr;
struct ntfs_vol_info *vol_info;
struct inode *inode;
goto err_mrec;
}
+ lmrec = mrec;
+
/* Fetch the volume information attribute */
- attr = ntfs_attr_lookup(fs, NTFS_AT_VOL_INFO, &mrec);
+ attr = ntfs_attr_lookup(fs, NTFS_AT_VOL_INFO, &mrec, lmrec);
if (!attr) {
printf("Could not find volume info attribute!\n");
goto err_attr;
if (!read_count)
return -1;
- /* sanity check */
if (!ntfs_check_sb_fields(&ntfs))
return -1;