From: Paulo Alcantara Date: Mon, 6 Feb 2012 03:43:55 +0000 (-0300) Subject: ntfs: keep looking for attributes with the latest found MFT record X-Git-Tag: syslinux-4.06-pre2~5 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6762b798cc1c917859ca417184bfbd80bdbaeb41;p=platform%2Fupstream%2Fsyslinux.git ntfs: keep looking for attributes with the latest found MFT record Once ntfs_attr_lookup() is called, it may change the MFT record passed as parameter so that the next calls that need the latest found MFT record don't have it anymore. So the __ntfs_attr_lookup() variant will provide support to the ntfs_attr_lookup() function handling both old and new MFT records. Signed-off-by: Paulo Alcantara --- diff --git a/core/fs/ntfs/ntfs.c b/core/fs/ntfs/ntfs.c index a90bc4c..75690fe 100644 --- a/core/fs/ntfs/ntfs.c +++ b/core/fs/ntfs/ntfs.c @@ -533,8 +533,8 @@ found: } 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; @@ -542,7 +542,6 @@ ntfs_attr_lookup(struct fs_info *fs, uint32_t type, dprintf("in %s\n", __func__); - /* sanity check */ if (!_mrec || type == NTFS_AT_END) goto out; @@ -589,6 +588,31 @@ 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; @@ -598,7 +622,7 @@ static int index_inode_setup(struct fs_info *fs, unsigned long mft_no, 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; @@ -617,6 +641,8 @@ static int index_inode_setup(struct fs_info *fs, unsigned long mft_no, goto out; } + lmrec = mrec; + NTFS_PVT(inode)->mft_no = mft_no; NTFS_PVT(inode)->seq_no = mrec->seq_no; @@ -626,7 +652,7 @@ static int index_inode_setup(struct fs_info *fs, unsigned long mft_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; @@ -658,7 +684,7 @@ static int index_inode_setup(struct fs_info *fs, unsigned long mft_no, 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; @@ -720,7 +746,7 @@ 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; @@ -748,7 +774,8 @@ static struct inode *ntfs_index_lookup(const char *dname, struct inode *dir) 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; @@ -757,7 +784,6 @@ static struct inode *ntfs_index_lookup(const char *dname, struct inode *dir) 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; @@ -790,7 +816,7 @@ static struct inode *ntfs_index_lookup(const char *dname, struct inode *dir) /* 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; @@ -971,7 +997,7 @@ static uint32_t ntfs_getfssec(struct file *file, char *buf, int sectors, 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; @@ -991,7 +1017,8 @@ static uint32_t ntfs_getfssec(struct file *file, char *buf, int sectors, 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; @@ -1024,7 +1051,7 @@ static int ntfs_readdir(struct file *file, struct dirent *dirent) { 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); @@ -1052,7 +1079,8 @@ static int ntfs_readdir(struct file *file, struct dirent *dirent) 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; @@ -1061,7 +1089,6 @@ static int ntfs_readdir(struct file *file, struct dirent *dirent) 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; @@ -1094,7 +1121,7 @@ descend_into_child_node: 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; @@ -1228,7 +1255,7 @@ static inline struct inode *ntfs_iget(const char *dname, struct inode *parent) 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; @@ -1244,8 +1271,10 @@ static struct inode *ntfs_iget_root(struct fs_info *fs) 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; @@ -1302,7 +1331,6 @@ static int ntfs_fs_init(struct fs_info *fs) if (!read_count) return -1; - /* sanity check */ if (!ntfs_check_sb_fields(&ntfs)) return -1;