| .. | .. |
|---|
| 33 | 33 | { |
|---|
| 34 | 34 | int i; |
|---|
| 35 | 35 | struct exfat_entry_set_cache *es; |
|---|
| 36 | + unsigned int uni_len = 0, len; |
|---|
| 36 | 37 | |
|---|
| 37 | 38 | es = exfat_get_dentry_set(sb, p_dir, entry, ES_ALL_ENTRIES); |
|---|
| 38 | 39 | if (!es) |
|---|
| .. | .. |
|---|
| 51 | 52 | if (exfat_get_entry_type(ep) != TYPE_EXTEND) |
|---|
| 52 | 53 | break; |
|---|
| 53 | 54 | |
|---|
| 54 | | - exfat_extract_uni_name(ep, uniname); |
|---|
| 55 | + len = exfat_extract_uni_name(ep, uniname); |
|---|
| 56 | + uni_len += len; |
|---|
| 57 | + if (len != EXFAT_FILE_NAME_LEN || uni_len >= MAX_NAME_LENGTH) |
|---|
| 58 | + break; |
|---|
| 55 | 59 | uniname += EXFAT_FILE_NAME_LEN; |
|---|
| 56 | 60 | } |
|---|
| 57 | 61 | |
|---|
| .. | .. |
|---|
| 102 | 106 | clu.dir = ei->hint_bmap.clu; |
|---|
| 103 | 107 | } |
|---|
| 104 | 108 | |
|---|
| 105 | | - while (clu_offset > 0) { |
|---|
| 109 | + while (clu_offset > 0 && clu.dir != EXFAT_EOF_CLUSTER) { |
|---|
| 106 | 110 | if (exfat_get_next_cluster(sb, &(clu.dir))) |
|---|
| 107 | 111 | return -EIO; |
|---|
| 108 | 112 | |
|---|
| .. | .. |
|---|
| 148 | 152 | 0); |
|---|
| 149 | 153 | |
|---|
| 150 | 154 | *uni_name.name = 0x0; |
|---|
| 151 | | - exfat_get_uniname_from_ext_entry(sb, &dir, dentry, |
|---|
| 155 | + exfat_get_uniname_from_ext_entry(sb, &clu, i, |
|---|
| 152 | 156 | uni_name.name); |
|---|
| 153 | 157 | exfat_utf16_to_nls(sb, &uni_name, |
|---|
| 154 | 158 | dir_entry->namebuf.lfn, |
|---|
| .. | .. |
|---|
| 210 | 214 | exfat_init_namebuf(nb); |
|---|
| 211 | 215 | } |
|---|
| 212 | 216 | |
|---|
| 213 | | -/* skip iterating emit_dots when dir is empty */ |
|---|
| 217 | +/* |
|---|
| 218 | + * Before calling dir_emit*(), sbi->s_lock should be released |
|---|
| 219 | + * because page fault can occur in dir_emit*(). |
|---|
| 220 | + */ |
|---|
| 214 | 221 | #define ITER_POS_FILLED_DOTS (2) |
|---|
| 215 | 222 | static int exfat_iterate(struct file *filp, struct dir_context *ctx) |
|---|
| 216 | 223 | { |
|---|
| .. | .. |
|---|
| 225 | 232 | int err = 0, fake_offset = 0; |
|---|
| 226 | 233 | |
|---|
| 227 | 234 | exfat_init_namebuf(nb); |
|---|
| 228 | | - mutex_lock(&EXFAT_SB(sb)->s_lock); |
|---|
| 229 | 235 | |
|---|
| 230 | 236 | cpos = ctx->pos; |
|---|
| 231 | 237 | if (!dir_emit_dots(filp, ctx)) |
|---|
| 232 | | - goto unlock; |
|---|
| 238 | + goto out; |
|---|
| 233 | 239 | |
|---|
| 234 | 240 | if (ctx->pos == ITER_POS_FILLED_DOTS) { |
|---|
| 235 | 241 | cpos = 0; |
|---|
| 236 | 242 | fake_offset = 1; |
|---|
| 237 | 243 | } |
|---|
| 238 | 244 | |
|---|
| 239 | | - if (cpos & (DENTRY_SIZE - 1)) { |
|---|
| 240 | | - err = -ENOENT; |
|---|
| 241 | | - goto unlock; |
|---|
| 242 | | - } |
|---|
| 245 | + cpos = round_up(cpos, DENTRY_SIZE); |
|---|
| 243 | 246 | |
|---|
| 244 | 247 | /* name buffer should be allocated before use */ |
|---|
| 245 | 248 | err = exfat_alloc_namebuf(nb); |
|---|
| 246 | 249 | if (err) |
|---|
| 247 | | - goto unlock; |
|---|
| 250 | + goto out; |
|---|
| 248 | 251 | get_new: |
|---|
| 252 | + mutex_lock(&EXFAT_SB(sb)->s_lock); |
|---|
| 253 | + |
|---|
| 249 | 254 | if (ei->flags == ALLOC_NO_FAT_CHAIN && cpos >= i_size_read(inode)) |
|---|
| 250 | 255 | goto end_of_dir; |
|---|
| 251 | 256 | |
|---|
| 252 | 257 | err = exfat_readdir(inode, &cpos, &de); |
|---|
| 253 | 258 | if (err) { |
|---|
| 254 | 259 | /* |
|---|
| 255 | | - * At least we tried to read a sector. Move cpos to next sector |
|---|
| 256 | | - * position (should be aligned). |
|---|
| 260 | + * At least we tried to read a sector. |
|---|
| 261 | + * Move cpos to next sector position (should be aligned). |
|---|
| 257 | 262 | */ |
|---|
| 258 | 263 | if (err == -EIO) { |
|---|
| 259 | 264 | cpos += 1 << (sb->s_blocksize_bits); |
|---|
| .. | .. |
|---|
| 276 | 281 | inum = iunique(sb, EXFAT_ROOT_INO); |
|---|
| 277 | 282 | } |
|---|
| 278 | 283 | |
|---|
| 279 | | - /* |
|---|
| 280 | | - * Before calling dir_emit(), sb_lock should be released. |
|---|
| 281 | | - * Because page fault can occur in dir_emit() when the size |
|---|
| 282 | | - * of buffer given from user is larger than one page size. |
|---|
| 283 | | - */ |
|---|
| 284 | 284 | mutex_unlock(&EXFAT_SB(sb)->s_lock); |
|---|
| 285 | 285 | if (!dir_emit(ctx, nb->lfn, strlen(nb->lfn), inum, |
|---|
| 286 | 286 | (de.attr & ATTR_SUBDIR) ? DT_DIR : DT_REG)) |
|---|
| 287 | | - goto out_unlocked; |
|---|
| 288 | | - mutex_lock(&EXFAT_SB(sb)->s_lock); |
|---|
| 287 | + goto out; |
|---|
| 289 | 288 | ctx->pos = cpos; |
|---|
| 290 | 289 | goto get_new; |
|---|
| 291 | 290 | |
|---|
| .. | .. |
|---|
| 293 | 292 | if (!cpos && fake_offset) |
|---|
| 294 | 293 | cpos = ITER_POS_FILLED_DOTS; |
|---|
| 295 | 294 | ctx->pos = cpos; |
|---|
| 296 | | -unlock: |
|---|
| 297 | 295 | mutex_unlock(&EXFAT_SB(sb)->s_lock); |
|---|
| 298 | | -out_unlocked: |
|---|
| 296 | +out: |
|---|
| 299 | 297 | /* |
|---|
| 300 | 298 | * To improve performance, free namebuf after unlock sb_lock. |
|---|
| 301 | 299 | * If namebuf is not allocated, this function do nothing |
|---|
| .. | .. |
|---|
| 615 | 613 | bforget(es->bh[i]); |
|---|
| 616 | 614 | else |
|---|
| 617 | 615 | brelse(es->bh[i]); |
|---|
| 616 | + |
|---|
| 617 | + if (IS_DYNAMIC_ES(es)) |
|---|
| 618 | + kfree(es->bh); |
|---|
| 619 | + |
|---|
| 618 | 620 | kfree(es); |
|---|
| 619 | 621 | return err; |
|---|
| 620 | 622 | } |
|---|
| .. | .. |
|---|
| 850 | 852 | /* byte offset in sector */ |
|---|
| 851 | 853 | off = EXFAT_BLK_OFFSET(byte_offset, sb); |
|---|
| 852 | 854 | es->start_off = off; |
|---|
| 855 | + es->bh = es->__bh; |
|---|
| 853 | 856 | |
|---|
| 854 | 857 | /* sector offset in cluster */ |
|---|
| 855 | 858 | sec = EXFAT_B_TO_BLK(byte_offset, sb); |
|---|
| .. | .. |
|---|
| 869 | 872 | es->num_entries = num_entries; |
|---|
| 870 | 873 | |
|---|
| 871 | 874 | num_bh = EXFAT_B_TO_BLK_ROUND_UP(off + num_entries * DENTRY_SIZE, sb); |
|---|
| 875 | + if (num_bh > ARRAY_SIZE(es->__bh)) { |
|---|
| 876 | + es->bh = kmalloc_array(num_bh, sizeof(*es->bh), GFP_KERNEL); |
|---|
| 877 | + if (!es->bh) { |
|---|
| 878 | + brelse(bh); |
|---|
| 879 | + kfree(es); |
|---|
| 880 | + return NULL; |
|---|
| 881 | + } |
|---|
| 882 | + es->bh[0] = bh; |
|---|
| 883 | + } |
|---|
| 884 | + |
|---|
| 872 | 885 | for (i = 1; i < num_bh; i++) { |
|---|
| 873 | 886 | /* get the next sector */ |
|---|
| 874 | 887 | if (exfat_is_last_sector_in_cluster(sbi, sec)) { |
|---|
| .. | .. |
|---|
| 908 | 921 | }; |
|---|
| 909 | 922 | |
|---|
| 910 | 923 | /* |
|---|
| 911 | | - * return values: |
|---|
| 912 | | - * >= 0 : return dir entiry position with the name in dir |
|---|
| 913 | | - * -ENOENT : entry with the name does not exist |
|---|
| 914 | | - * -EIO : I/O error |
|---|
| 924 | + * @ei: inode info of parent directory |
|---|
| 925 | + * @p_dir: directory structure of parent directory |
|---|
| 926 | + * @num_entries:entry size of p_uniname |
|---|
| 927 | + * @hint_opt: If p_uniname is found, filled with optimized dir/entry |
|---|
| 928 | + * for traversing cluster chain. |
|---|
| 929 | + * @return: |
|---|
| 930 | + * >= 0: file directory entry position where the name exists |
|---|
| 931 | + * -ENOENT: entry with the name does not exist |
|---|
| 932 | + * -EIO: I/O error |
|---|
| 915 | 933 | */ |
|---|
| 916 | 934 | int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei, |
|---|
| 917 | 935 | struct exfat_chain *p_dir, struct exfat_uni_name *p_uniname, |
|---|
| 918 | | - int num_entries, unsigned int type) |
|---|
| 936 | + int num_entries, unsigned int type, struct exfat_hint *hint_opt) |
|---|
| 919 | 937 | { |
|---|
| 920 | 938 | int i, rewind = 0, dentry = 0, end_eidx = 0, num_ext = 0, len; |
|---|
| 921 | 939 | int order, step, name_len = 0; |
|---|
| .. | .. |
|---|
| 992 | 1010 | |
|---|
| 993 | 1011 | if (entry_type == TYPE_FILE || entry_type == TYPE_DIR) { |
|---|
| 994 | 1012 | step = DIRENT_STEP_FILE; |
|---|
| 1013 | + hint_opt->clu = clu.dir; |
|---|
| 1014 | + hint_opt->eidx = i; |
|---|
| 995 | 1015 | if (type == TYPE_ALL || type == entry_type) { |
|---|
| 996 | 1016 | num_ext = ep->dentry.file.num_ext; |
|---|
| 997 | 1017 | step = DIRENT_STEP_STRM; |
|---|
| .. | .. |
|---|
| 1026 | 1046 | if (entry_type == TYPE_EXTEND) { |
|---|
| 1027 | 1047 | unsigned short entry_uniname[16], unichar; |
|---|
| 1028 | 1048 | |
|---|
| 1029 | | - if (step != DIRENT_STEP_NAME) { |
|---|
| 1049 | + if (step != DIRENT_STEP_NAME || |
|---|
| 1050 | + name_len >= MAX_NAME_LENGTH) { |
|---|
| 1030 | 1051 | step = DIRENT_STEP_FILE; |
|---|
| 1031 | 1052 | continue; |
|---|
| 1032 | 1053 | } |
|---|