Lines Matching +full:de +full:- +full:be
1 // SPDX-License-Identifier: GPL-2.0
7 * Laboratoire MASI - Institut Blaise Pascal
16 * Big-endian to little-endian byte-swapping/bitmaps by
19 * for B-tree directories by Theodore Ts'o ([email protected]), 1998
61 if (unlikely(EXT4_SB(inode->i_sb)->s_max_dir_size_kb && in ext4_append()
62 ((inode->i_size >> 10) >= in ext4_append()
63 EXT4_SB(inode->i_sb)->s_max_dir_size_kb))) in ext4_append()
64 return ERR_PTR(-ENOSPC); in ext4_append()
66 *block = inode->i_size >> inode->i_sb->s_blocksize_bits; in ext4_append()
80 return ERR_PTR(-EFSCORRUPTED); in ext4_append()
86 inode->i_size += inode->i_sb->s_blocksize; in ext4_append()
87 EXT4_I(inode)->i_disksize = inode->i_size; in ext4_append()
92 err = ext4_journal_get_write_access(handle, inode->i_sb, bh, in ext4_append()
100 ext4_std_error(inode->i_sb, err); in ext4_append()
109 * block being read to be an index block, or a block containing
114 * the caller doesn't know what kind of directory block will be read,
115 * so no specific verification will be done.
134 if (block >= inode->i_size >> inode->i_blkbits) { in __ext4_read_dirblock()
137 block, inode->i_size); in __ext4_read_dirblock()
138 return ERR_PTR(-EFSCORRUPTED); in __ext4_read_dirblock()
141 if (ext4_simulate_fail(inode->i_sb, EXT4_SIM_DIRBLOCK_EIO)) in __ext4_read_dirblock()
142 bh = ERR_PTR(-EIO); in __ext4_read_dirblock()
146 __ext4_warning(inode->i_sb, func, line, in __ext4_read_dirblock()
149 inode->i_ino, (unsigned long)block, in __ext4_read_dirblock()
150 current->comm, PTR_ERR(bh)); in __ext4_read_dirblock()
154 /* The first directory block must not be a hole. */ in __ext4_read_dirblock()
159 return ERR_PTR(-EFSCORRUPTED); in __ext4_read_dirblock()
163 dirent = (struct ext4_dir_entry *) bh->b_data; in __ext4_read_dirblock()
168 else if (ext4_rec_len_from_disk(dirent->rec_len, in __ext4_read_dirblock()
169 inode->i_sb->s_blocksize) == in __ext4_read_dirblock()
170 inode->i_sb->s_blocksize) in __ext4_read_dirblock()
177 return ERR_PTR(-EFSCORRUPTED); in __ext4_read_dirblock()
179 if (!ext4_has_metadata_csum(inode->i_sb) || in __ext4_read_dirblock()
186 * caller is sure it should be an index block. in __ext4_read_dirblock()
190 !ext4_simulate_fail(inode->i_sb, EXT4_SIM_DIRBLOCK_CRC)) in __ext4_read_dirblock()
197 return ERR_PTR(-EFSBADCRC); in __ext4_read_dirblock()
202 !ext4_simulate_fail(inode->i_sb, EXT4_SIM_DIRBLOCK_CRC)) in __ext4_read_dirblock()
209 return ERR_PTR(-EFSBADCRC); in __ext4_read_dirblock()
243 * dirent the two low bits of the hash version will be zero. Therefore, the
244 * hash version mod 4 should never be 0. Sincerely, the paranoia department.
334 struct ext4_dir_entry_tail *t = EXT4_DIRENT_TAIL(bh->b_data, blocksize); in ext4_initialize_dirent_tail()
337 t->det_rec_len = ext4_rec_len_to_disk( in ext4_initialize_dirent_tail()
339 t->det_reserved_ft = EXT4_FT_DIR_CSUM; in ext4_initialize_dirent_tail()
347 int blocksize = EXT4_BLOCK_SIZE(inode->i_sb); in get_dirent_tail()
352 d = (struct ext4_dir_entry *)bh->b_data; in get_dirent_tail()
353 top = (struct ext4_dir_entry *)(bh->b_data + in get_dirent_tail()
354 (blocksize - sizeof(struct ext4_dir_entry_tail))); in get_dirent_tail()
355 while (d < top && ext4_rec_len_from_disk(d->rec_len, blocksize)) in get_dirent_tail()
357 ext4_rec_len_from_disk(d->rec_len, blocksize)); in get_dirent_tail()
364 t = EXT4_DIRENT_TAIL(bh->b_data, EXT4_BLOCK_SIZE(inode->i_sb)); in get_dirent_tail()
367 if (t->det_reserved_zero1 || in get_dirent_tail()
368 (ext4_rec_len_from_disk(t->det_rec_len, blocksize) != in get_dirent_tail()
370 t->det_reserved_zero2 || in get_dirent_tail()
371 t->det_reserved_ft != EXT4_FT_DIR_CSUM) in get_dirent_tail()
379 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); in ext4_dirblock_csum()
383 csum = ext4_chksum(sbi, ei->i_csum_seed, (__u8 *)dirent, size); in ext4_dirblock_csum()
394 "No space for directory leaf checksum. Please run e2fsck -D."); in __warn_no_space_for_csum()
401 if (!ext4_has_metadata_csum(inode->i_sb)) in ext4_dirblock_csum_verify()
410 if (t->det_checksum != ext4_dirblock_csum(inode, bh->b_data, in ext4_dirblock_csum_verify()
411 (char *)t - bh->b_data)) in ext4_dirblock_csum_verify()
422 if (!ext4_has_metadata_csum(inode->i_sb)) in ext4_dirblock_csum_set()
431 t->det_checksum = ext4_dirblock_csum(inode, bh->b_data, in ext4_dirblock_csum_set()
432 (char *)t - bh->b_data); in ext4_dirblock_csum_set()
450 int blocksize = EXT4_BLOCK_SIZE(inode->i_sb); in get_dx_countlimit()
451 unsigned int rlen = ext4_rec_len_from_disk(dirent->rec_len, blocksize); in get_dx_countlimit()
457 if (ext4_rec_len_from_disk(dp->rec_len, blocksize) != blocksize - 12) in get_dx_countlimit()
460 if (root->reserved_zero || in get_dx_countlimit()
461 root->info_length != sizeof(struct dx_root_info)) in get_dx_countlimit()
475 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); in ext4_dx_csum()
483 csum = ext4_chksum(sbi, ei->i_csum_seed, (__u8 *)dirent, size); in ext4_dx_csum()
497 if (!ext4_has_metadata_csum(inode->i_sb)) in ext4_dx_csum_verify()
502 EXT4_ERROR_INODE(inode, "dir seems corrupt? Run e2fsck -D."); in ext4_dx_csum_verify()
505 limit = le16_to_cpu(c->limit); in ext4_dx_csum_verify()
506 count = le16_to_cpu(c->count); in ext4_dx_csum_verify()
508 EXT4_BLOCK_SIZE(inode->i_sb) - sizeof(struct dx_tail)) { in ext4_dx_csum_verify()
514 if (t->dt_checksum != ext4_dx_csum(inode, dirent, count_offset, in ext4_dx_csum_verify()
526 if (!ext4_has_metadata_csum(inode->i_sb)) in ext4_dx_csum_set()
531 EXT4_ERROR_INODE(inode, "dir seems corrupt? Run e2fsck -D."); in ext4_dx_csum_set()
534 limit = le16_to_cpu(c->limit); in ext4_dx_csum_set()
535 count = le16_to_cpu(c->count); in ext4_dx_csum_set()
537 EXT4_BLOCK_SIZE(inode->i_sb) - sizeof(struct dx_tail)) { in ext4_dx_csum_set()
543 t->dt_checksum = ext4_dx_csum(inode, dirent, count_offset, count, t); in ext4_dx_csum_set()
550 ext4_dx_csum_set(inode, (struct ext4_dir_entry *)bh->b_data); in ext4_handle_dirty_dx_node()
561 ext4_rec_len_from_disk(p->rec_len, blocksize)); in ext4_next_entry()
565 * Future: use high four bits of block for coalesce-on-delete flags
571 return le32_to_cpu(entry->block) & 0x0fffffff; in dx_get_block()
576 entry->block = cpu_to_le32(value); in dx_set_block()
581 return le32_to_cpu(entry->hash); in dx_get_hash()
586 entry->hash = cpu_to_le32(value); in dx_set_hash()
591 return le16_to_cpu(((struct dx_countlimit *) entries)->count); in dx_get_count()
596 return le16_to_cpu(((struct dx_countlimit *) entries)->limit); in dx_get_limit()
601 ((struct dx_countlimit *) entries)->count = cpu_to_le16(value); in dx_set_count()
606 ((struct dx_countlimit *) entries)->limit = cpu_to_le16(value); in dx_set_limit()
611 unsigned int entry_space = dir->i_sb->s_blocksize - in dx_root_limit()
612 ext4_dir_rec_len(1, NULL) - in dx_root_limit()
613 ext4_dir_rec_len(2, NULL) - infosize; in dx_root_limit()
615 if (ext4_has_metadata_csum(dir->i_sb)) in dx_root_limit()
616 entry_space -= sizeof(struct dx_tail); in dx_root_limit()
622 unsigned int entry_space = dir->i_sb->s_blocksize - in dx_node_limit()
625 if (ext4_has_metadata_csum(dir->i_sb)) in dx_node_limit()
626 entry_space -= sizeof(struct dx_tail); in dx_node_limit()
639 printk(KERN_CONT " %x->%lu", in dx_show_index()
655 struct ext4_dir_entry_2 *de, in dx_show_leaf() argument
659 char *base = (char *) de; in dx_show_leaf()
663 while ((char *) de < base + size) in dx_show_leaf()
665 if (de->inode) in dx_show_leaf()
676 name = de->name; in dx_show_leaf()
677 len = de->name_len; in dx_show_leaf()
680 (void) ext4fs_dirhash(dir, de->name, in dx_show_leaf()
681 de->name_len, &h); in dx_show_leaf()
684 (unsigned) ((char *) de in dx_show_leaf()
685 - base)); in dx_show_leaf()
696 "buffer--skipping " in dx_show_leaf()
713 h.hash = EXT4_DIRENT_HASH(de); in dx_show_leaf()
716 de->name, in dx_show_leaf()
717 de->name_len, &h); in dx_show_leaf()
719 h.hash, (unsigned) ((char *) de in dx_show_leaf()
720 - base)); in dx_show_leaf()
725 int len = de->name_len; in dx_show_leaf()
726 char *name = de->name; in dx_show_leaf()
727 (void) ext4fs_dirhash(dir, de->name, in dx_show_leaf()
728 de->name_len, &h); in dx_show_leaf()
730 (unsigned) ((char *) de - base)); in dx_show_leaf()
733 space += ext4_dir_rec_len(de->name_len, dir); in dx_show_leaf()
736 de = ext4_next_entry(de, size); in dx_show_leaf()
745 unsigned blocksize = dir->i_sb->s_blocksize; in dx_show_entries()
754 u32 range = i < count - 1? (dx_get_hash(entries + 1) - hash): ~hash; in dx_show_entries()
761 dx_show_entries(hinfo, dir, ((struct dx_node *) bh->b_data)->entries, levels - 1): in dx_show_entries()
763 bh->b_data, blocksize, 0); in dx_show_entries()
783 while (n--) { in htree_rep_invariant_check()
786 at--; in htree_rep_invariant_check()
790 ASSERT(at == target - 1); in htree_rep_invariant_check()
823 frame->bh = ext4_read_dirblock(dir, 0, INDEX); in dx_probe()
824 if (IS_ERR(frame->bh)) in dx_probe()
825 return (struct dx_frame *) frame->bh; in dx_probe()
827 root = (struct dx_root *) frame->bh->b_data; in dx_probe()
828 if (root->info.hash_version != DX_HASH_TEA && in dx_probe()
829 root->info.hash_version != DX_HASH_HALF_MD4 && in dx_probe()
830 root->info.hash_version != DX_HASH_LEGACY && in dx_probe()
831 root->info.hash_version != DX_HASH_SIPHASH) { in dx_probe()
833 root->info.hash_version); in dx_probe()
837 if (root->info.hash_version != DX_HASH_SIPHASH) { in dx_probe()
843 if (root->info.hash_version == DX_HASH_SIPHASH) { in dx_probe()
850 hinfo = &fname->hinfo; in dx_probe()
851 hinfo->hash_version = root->info.hash_version; in dx_probe()
852 if (hinfo->hash_version <= DX_HASH_TEA) in dx_probe()
853 hinfo->hash_version += EXT4_SB(dir->i_sb)->s_hash_unsigned; in dx_probe()
854 hinfo->seed = EXT4_SB(dir->i_sb)->s_hash_seed; in dx_probe()
865 hash = hinfo->hash; in dx_probe()
867 if (root->info.unused_flags & 1) { in dx_probe()
869 root->info.unused_flags); in dx_probe()
873 indirect = root->info.indirect_levels; in dx_probe()
874 if (indirect >= ext4_dir_htree_level(dir->i_sb)) { in dx_probe()
875 ext4_warning(dir->i_sb, in dx_probe()
877 "supported value", dir->i_ino, in dx_probe()
878 ext4_dir_htree_level(dir->i_sb)); in dx_probe()
879 if (ext4_dir_htree_level(dir->i_sb) < EXT4_HTREE_LEVEL) { in dx_probe()
880 ext4_warning(dir->i_sb, "Enable large directory " in dx_probe()
886 entries = (struct dx_entry *)(((char *)&root->info) + in dx_probe()
887 root->info.info_length); in dx_probe()
890 root->info.info_length)) { in dx_probe()
893 dx_root_limit(dir, root->info.info_length)); in dx_probe()
910 q = entries + count - 1; in dx_probe()
912 m = p + (q - p) / 2; in dx_probe()
915 q = m - 1; in dx_probe()
920 htree_rep_invariant_check(entries, p, hash, count - 1); in dx_probe()
922 at = p - 1; in dx_probe()
923 dxtrace(printk(KERN_CONT " %x->%u\n", in dx_probe()
926 frame->entries = entries; in dx_probe()
927 frame->at = at; in dx_probe()
942 frame->bh = ext4_read_dirblock(dir, block, INDEX); in dx_probe()
943 if (IS_ERR(frame->bh)) { in dx_probe()
944 ret_err = (struct dx_frame *) frame->bh; in dx_probe()
945 frame->bh = NULL; in dx_probe()
949 entries = ((struct dx_node *) frame->bh->b_data)->entries; in dx_probe()
960 brelse(frame->bh); in dx_probe()
961 frame--; in dx_probe()
979 info = &((struct dx_root *)frames[0].bh->b_data)->info; in dx_release()
980 /* save local copy, "info" may be freed after brelse() */ in dx_release()
981 indirect_levels = info->indirect_levels; in dx_release()
993 * should be necessary. Whether or not the search is necessary is
1004 * If start_hash is non-null, it will be filled in with the starting
1023 * nodes need to be read. in ext4_htree_next_block()
1026 if (++(p->at) < p->entries + dx_get_count(p->entries)) in ext4_htree_next_block()
1031 p--; in ext4_htree_next_block()
1041 bhash = dx_get_hash(p->at); in ext4_htree_next_block()
1052 while (num_frames--) { in ext4_htree_next_block()
1053 bh = ext4_read_dirblock(dir, dx_get_block(p->at), INDEX); in ext4_htree_next_block()
1057 brelse(p->bh); in ext4_htree_next_block()
1058 p->bh = bh; in ext4_htree_next_block()
1059 p->at = p->entries = ((struct dx_node *) bh->b_data)->entries; in ext4_htree_next_block()
1066 * This function fills a red-black tree with information from a
1076 struct ext4_dir_entry_2 *de, *top; in htree_dirblock_to_tree() local
1079 int csum = ext4_has_metadata_csum(dir->i_sb); in htree_dirblock_to_tree()
1087 de = (struct ext4_dir_entry_2 *) bh->b_data; in htree_dirblock_to_tree()
1089 top = (struct ext4_dir_entry_2 *) ((char *) de + in htree_dirblock_to_tree()
1090 dir->i_sb->s_blocksize - in htree_dirblock_to_tree()
1108 for (; de < top; de = ext4_next_entry(de, dir->i_sb->s_blocksize)) { in htree_dirblock_to_tree()
1109 if (ext4_check_dir_entry(dir, NULL, de, bh, in htree_dirblock_to_tree()
1110 bh->b_data, bh->b_size, in htree_dirblock_to_tree()
1111 (block<<EXT4_BLOCK_SIZE_BITS(dir->i_sb)) in htree_dirblock_to_tree()
1112 + ((char *)de - bh->b_data))) { in htree_dirblock_to_tree()
1117 if (de->name_len && de->inode) { in htree_dirblock_to_tree()
1118 hinfo->hash = EXT4_DIRENT_HASH(de); in htree_dirblock_to_tree()
1119 hinfo->minor_hash = EXT4_DIRENT_MINOR_HASH(de); in htree_dirblock_to_tree()
1121 hinfo->hash = 0; in htree_dirblock_to_tree()
1122 hinfo->minor_hash = 0; in htree_dirblock_to_tree()
1125 err = ext4fs_dirhash(dir, de->name, in htree_dirblock_to_tree()
1126 de->name_len, hinfo); in htree_dirblock_to_tree()
1132 if ((hinfo->hash < start_hash) || in htree_dirblock_to_tree()
1133 ((hinfo->hash == start_hash) && in htree_dirblock_to_tree()
1134 (hinfo->minor_hash < start_minor_hash))) in htree_dirblock_to_tree()
1136 if (de->inode == 0) in htree_dirblock_to_tree()
1139 tmp_str.name = de->name; in htree_dirblock_to_tree()
1140 tmp_str.len = de->name_len; in htree_dirblock_to_tree()
1142 hinfo->hash, hinfo->minor_hash, de, in htree_dirblock_to_tree()
1146 struct fscrypt_str de_name = FSTR_INIT(de->name, in htree_dirblock_to_tree()
1147 de->name_len); in htree_dirblock_to_tree()
1150 err = fscrypt_fname_disk_to_usr(dir, hinfo->hash, in htree_dirblock_to_tree()
1151 hinfo->minor_hash, &de_name, in htree_dirblock_to_tree()
1158 hinfo->hash, hinfo->minor_hash, de, in htree_dirblock_to_tree()
1176 * This function fills a red-black tree with information from a
1187 struct ext4_dir_entry_2 *de; in ext4_htree_fill_tree() local
1204 EXT4_SB(dir->i_sb)->s_def_hash_version; in ext4_htree_fill_tree()
1207 EXT4_SB(dir->i_sb)->s_hash_unsigned; in ext4_htree_fill_tree()
1208 hinfo.seed = EXT4_SB(dir->i_sb)->s_hash_seed; in ext4_htree_fill_tree()
1233 de = (struct ext4_dir_entry_2 *) frames[0].bh->b_data; in ext4_htree_fill_tree()
1234 tmp_str.name = de->name; in ext4_htree_fill_tree()
1235 tmp_str.len = de->name_len; in ext4_htree_fill_tree()
1237 de, &tmp_str); in ext4_htree_fill_tree()
1243 de = (struct ext4_dir_entry_2 *) frames[0].bh->b_data; in ext4_htree_fill_tree()
1244 de = ext4_next_entry(de, dir->i_sb->s_blocksize); in ext4_htree_fill_tree()
1245 tmp_str.name = de->name; in ext4_htree_fill_tree()
1246 tmp_str.len = de->name_len; in ext4_htree_fill_tree()
1248 de, &tmp_str); in ext4_htree_fill_tree()
1256 err = -ERESTARTSYS; in ext4_htree_fill_tree()
1260 block = dx_get_block(frame->at); in ext4_htree_fill_tree()
1300 return ext4_search_dir(bh, bh->b_data, dir->i_sb->s_blocksize, dir, in search_dirblock()
1317 struct ext4_dir_entry_2 *de = (struct ext4_dir_entry_2 *)bh->b_data; in dx_make_map() local
1318 unsigned int buflen = bh->b_size; in dx_make_map()
1319 char *base = bh->b_data; in dx_make_map()
1321 int blocksize = EXT4_BLOCK_SIZE(dir->i_sb); in dx_make_map()
1323 if (ext4_has_metadata_csum(dir->i_sb)) in dx_make_map()
1324 buflen -= sizeof(struct ext4_dir_entry_tail); in dx_make_map()
1326 while ((char *) de < base + buflen) { in dx_make_map()
1327 if (ext4_check_dir_entry(dir, NULL, de, bh, base, buflen, in dx_make_map()
1328 ((char *)de) - base)) in dx_make_map()
1329 return -EFSCORRUPTED; in dx_make_map()
1330 if (de->name_len && de->inode) { in dx_make_map()
1332 h.hash = EXT4_DIRENT_HASH(de); in dx_make_map()
1334 int err = ext4fs_dirhash(dir, de->name, in dx_make_map()
1335 de->name_len, &h); in dx_make_map()
1339 map_tail--; in dx_make_map()
1340 map_tail->hash = h.hash; in dx_make_map()
1341 map_tail->offs = ((char *) de - base)>>2; in dx_make_map()
1342 map_tail->size = ext4_rec_len_from_disk(de->rec_len, in dx_make_map()
1347 de = ext4_next_entry(de, blocksize); in dx_make_map()
1355 struct dx_map_entry *p, *q, *top = map + count - 1; in dx_sort_map()
1360 if (count - 9 < 2) /* 9, 10 -> 11 */ in dx_sort_map()
1362 for (p = top, q = p - count; q >= map; p--, q--) in dx_sort_map()
1363 if (p->hash < q->hash) in dx_sort_map()
1370 while (q-- > map) { in dx_sort_map()
1381 struct dx_entry *entries = frame->entries; in dx_insert_block()
1382 struct dx_entry *old = frame->at, *new = old + 1; in dx_insert_block()
1387 memmove(new + 1, new, (char *)(entries + count) - (char *)(new)); in dx_insert_block()
1397 struct qstr *cf_name = &name->cf_name; in ext4_fname_setup_ci_filename()
1399 struct dx_hash_info *hinfo = &name->hinfo; in ext4_fname_setup_ci_filename()
1404 cf_name->name = NULL; in ext4_fname_setup_ci_filename()
1410 return -ENOMEM; in ext4_fname_setup_ci_filename()
1412 len = utf8_casefold(dir->i_sb->s_encoding, iname, buf, EXT4_NAME_LEN); in ext4_fname_setup_ci_filename()
1417 cf_name->name = buf; in ext4_fname_setup_ci_filename()
1418 cf_name->len = (unsigned) len; in ext4_fname_setup_ci_filename()
1423 hinfo->hash_version = DX_HASH_SIPHASH; in ext4_fname_setup_ci_filename()
1424 hinfo->seed = NULL; in ext4_fname_setup_ci_filename()
1425 if (cf_name->name) in ext4_fname_setup_ci_filename()
1426 return ext4fs_dirhash(dir, cf_name->name, cf_name->len, hinfo); in ext4_fname_setup_ci_filename()
1428 return ext4fs_dirhash(dir, iname->name, iname->len, hinfo); in ext4_fname_setup_ci_filename()
1439 struct ext4_dir_entry_2 *de) in ext4_match() argument
1443 if (!de->inode) in ext4_match()
1446 f.usr_fname = fname->usr_fname; in ext4_match()
1447 f.disk_name = fname->disk_name; in ext4_match()
1449 f.crypto_buf = fname->crypto_buf; in ext4_match()
1461 * mismatch will be a false negative. Therefore, make in ext4_match()
1465 if (IS_ENCRYPTED(parent) && fname->cf_name.name && in ext4_match()
1466 (fname->hinfo.hash != EXT4_DIRENT_HASH(de) || in ext4_match()
1467 fname->hinfo.minor_hash != EXT4_DIRENT_MINOR_HASH(de))) in ext4_match()
1475 return generic_ci_match(parent, fname->usr_fname, in ext4_match()
1476 &fname->cf_name, de->name, in ext4_match()
1477 de->name_len) > 0; in ext4_match()
1481 return fscrypt_match_name(&f, de->name, de->name_len); in ext4_match()
1485 * Returns 0 if not found, -EFSCORRUPTED on failure, and 1 on success
1491 struct ext4_dir_entry_2 * de; in ext4_search_dir() local
1495 de = (struct ext4_dir_entry_2 *)search_buf; in ext4_search_dir()
1497 while ((char *) de < dlimit - EXT4_BASE_DIR_LEN) { in ext4_search_dir()
1500 if (de->name + de->name_len <= dlimit && in ext4_search_dir()
1501 ext4_match(dir, fname, de)) { in ext4_search_dir()
1502 /* found a match - just to be sure, do in ext4_search_dir()
1504 if (ext4_check_dir_entry(dir, NULL, de, bh, search_buf, in ext4_search_dir()
1506 return -EFSCORRUPTED; in ext4_search_dir()
1507 *res_dir = de; in ext4_search_dir()
1511 de_len = ext4_rec_len_from_disk(de->rec_len, in ext4_search_dir()
1512 dir->i_sb->s_blocksize); in ext4_search_dir()
1514 return -EFSCORRUPTED; in ext4_search_dir()
1516 de = (struct ext4_dir_entry_2 *) ((char *) de + de_len); in ext4_search_dir()
1522 struct ext4_dir_entry *de) in is_dx_internal_node() argument
1524 struct super_block *sb = dir->i_sb; in is_dx_internal_node()
1530 if (de->inode == 0 && in is_dx_internal_node()
1531 ext4_rec_len_from_disk(de->rec_len, sb->s_blocksize) == in is_dx_internal_node()
1532 sb->s_blocksize) in is_dx_internal_node()
1542 * itself (as a parameter - res_dir). It does NOT read the inode of the
1543 * entry - you'll have to do that yourself if you want to.
1545 * The returned buffer_head has ->b_count elevated. The caller is expected
1557 const u8 *name = fname->usr_fname->name; in __ext4_find_entry()
1566 sb = dir->i_sb; in __ext4_find_entry()
1567 namelen = fname->usr_fname->len; in __ext4_find_entry()
1584 * "." or ".." will only be in the first block in __ext4_find_entry()
1585 * NFS may look up ".."; "." should be handled by the VFS in __ext4_find_entry()
1604 nblocks = dir->i_size >> EXT4_BLOCK_SIZE_BITS(sb); in __ext4_find_entry()
1609 start = EXT4_I(dir)->i_dir_start_lookup; in __ext4_find_entry()
1616 * We deal with the read-ahead logic here. in __ext4_find_entry()
1623 ra_max = start - block; in __ext4_find_entry()
1625 ra_max = nblocks - block; in __ext4_find_entry()
1643 ret = ERR_PTR(-EIO); in __ext4_find_entry()
1648 (struct ext4_dir_entry *)bh->b_data) && in __ext4_find_entry()
1654 ret = ERR_PTR(-EFSBADCRC); in __ext4_find_entry()
1661 EXT4_I(dir)->i_dir_start_lookup = block; in __ext4_find_entry()
1681 nblocks = dir->i_size >> EXT4_BLOCK_SIZE_BITS(sb); in __ext4_find_entry()
1688 /* Clean up the read-ahead blocks */ in __ext4_find_entry()
1704 if (err == -ENOENT) in ext4_find_entry()
1724 if (err == -ENOENT) in ext4_lookup_entry()
1739 struct super_block * sb = dir->i_sb; in ext4_dx_find_entry()
1752 block = dx_get_block(frame->at); in ext4_dx_find_entry()
1769 retval = ext4_htree_next_block(dir, fname->hinfo.hash, frame, in ext4_dx_find_entry()
1782 dxtrace(printk(KERN_DEBUG "%s not found\n", fname->usr_fname->name)); in ext4_dx_find_entry()
1791 struct ext4_dir_entry_2 *de; in ext4_lookup() local
1794 if (dentry->d_name.len > EXT4_NAME_LEN) in ext4_lookup()
1795 return ERR_PTR(-ENAMETOOLONG); in ext4_lookup()
1797 bh = ext4_lookup_entry(dir, dentry, &de); in ext4_lookup()
1802 __u32 ino = le32_to_cpu(de->inode); in ext4_lookup()
1804 if (!ext4_valid_inum(dir->i_sb, ino)) { in ext4_lookup()
1806 return ERR_PTR(-EFSCORRUPTED); in ext4_lookup()
1808 if (unlikely(ino == dir->i_ino)) { in ext4_lookup()
1811 return ERR_PTR(-EFSCORRUPTED); in ext4_lookup()
1813 inode = ext4_iget(dir->i_sb, ino, EXT4_IGET_NORMAL); in ext4_lookup()
1814 if (inode == ERR_PTR(-ESTALE)) { in ext4_lookup()
1818 return ERR_PTR(-EFSCORRUPTED); in ext4_lookup()
1821 (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) && in ext4_lookup()
1823 ext4_warning(inode->i_sb, in ext4_lookup()
1825 dir->i_ino, inode->i_ino); in ext4_lookup()
1827 return ERR_PTR(-EPERM); in ext4_lookup()
1847 struct ext4_dir_entry_2 * de; in ext4_get_parent() local
1850 bh = ext4_find_entry(d_inode(child), &dotdot_name, &de, NULL); in ext4_get_parent()
1854 return ERR_PTR(-ENOENT); in ext4_get_parent()
1855 ino = le32_to_cpu(de->inode); in ext4_get_parent()
1858 if (!ext4_valid_inum(child->d_sb, ino)) { in ext4_get_parent()
1861 return ERR_PTR(-EFSCORRUPTED); in ext4_get_parent()
1864 return d_obtain_alias(ext4_iget(child->d_sb, ino, EXT4_IGET_NORMAL)); in ext4_get_parent()
1878 while (count--) { in dx_move_dirents()
1879 struct ext4_dir_entry_2 *de = (struct ext4_dir_entry_2 *) in dx_move_dirents() local
1880 (from + (map->offs<<2)); in dx_move_dirents()
1881 rec_len = ext4_dir_rec_len(de->name_len, dir); in dx_move_dirents()
1883 memcpy (to, de, rec_len); in dx_move_dirents()
1884 ((struct ext4_dir_entry_2 *) to)->rec_len = in dx_move_dirents()
1888 de->inode = 0; in dx_move_dirents()
1889 memset(&de->name_len, 0, ext4_rec_len_from_disk(de->rec_len, in dx_move_dirents()
1890 blocksize) - in dx_move_dirents()
1897 return (struct ext4_dir_entry_2 *) (to - rec_len); in dx_move_dirents()
1907 struct ext4_dir_entry_2 *next, *to, *prev, *de = (struct ext4_dir_entry_2 *) base; in dx_pack_dirents() local
1910 prev = to = de; in dx_pack_dirents()
1911 while ((char*)de < base + blocksize) { in dx_pack_dirents()
1912 next = ext4_next_entry(de, blocksize); in dx_pack_dirents()
1913 if (de->inode && de->name_len) { in dx_pack_dirents()
1914 rec_len = ext4_dir_rec_len(de->name_len, dir); in dx_pack_dirents()
1915 if (de > to) in dx_pack_dirents()
1916 memmove(to, de, rec_len); in dx_pack_dirents()
1917 to->rec_len = ext4_rec_len_to_disk(rec_len, blocksize); in dx_pack_dirents()
1921 de = next; in dx_pack_dirents()
1929 * Returns pointer to de in block into which the new entry will be inserted.
1935 unsigned blocksize = dir->i_sb->s_blocksize; in do_split()
1942 char *data1 = (*bh)->b_data, *data2; in do_split()
1944 struct ext4_dir_entry_2 *de = NULL, *de2; in do_split() local
1948 if (ext4_has_metadata_csum(dir->i_sb)) in do_split()
1959 err = ext4_journal_get_write_access(handle, dir->i_sb, *bh, in do_split()
1964 BUFFER_TRACE(frame->bh, "get_write_access"); in do_split()
1965 err = ext4_journal_get_write_access(handle, dir->i_sb, frame->bh, in do_split()
1970 data2 = bh2->b_data; in do_split()
1979 map -= count; in do_split()
1984 for (i = count-1; i >= 0; i--) { in do_split()
1999 split = count - move; in do_split()
2004 /* Should never happen, but avoid out-of-bounds access below */ in do_split()
2005 ext4_error_inode_block(dir, (*bh)->b_blocknr, 0, in do_split()
2007 hinfo->hash, hinfo->minor_hash, count, move); in do_split()
2008 err = -EFSCORRUPTED; in do_split()
2013 continued = hash2 == map[split - 1].hash; in do_split()
2015 (unsigned long)dx_get_block(frame->at), in do_split()
2016 hash2, split, count-split)); in do_split()
2019 de2 = dx_move_dirents(dir, data1, data2, map + split, count - split, in do_split()
2021 de = dx_pack_dirents(dir, data1, blocksize); in do_split()
2022 de->rec_len = ext4_rec_len_to_disk(data1 + (blocksize - csum_size) - in do_split()
2023 (char *) de, in do_split()
2025 de2->rec_len = ext4_rec_len_to_disk(data2 + (blocksize - csum_size) - in do_split()
2039 if (hinfo->hash >= hash2) { in do_split()
2041 de = de2; in do_split()
2047 err = ext4_handle_dirty_dx_node(handle, dir, frame->bh); in do_split()
2051 dxtrace(dx_show_index("frame", frame->entries)); in do_split()
2052 return de; in do_split()
2055 ext4_std_error(dir->i_sb, err); in do_split()
2069 struct ext4_dir_entry_2 *de; in ext4_find_dest_de() local
2075 de = buf; in ext4_find_dest_de()
2076 top = buf + buf_size - reclen; in ext4_find_dest_de()
2077 while ((char *) de <= top) { in ext4_find_dest_de()
2078 if (ext4_check_dir_entry(dir, NULL, de, bh, in ext4_find_dest_de()
2080 return -EFSCORRUPTED; in ext4_find_dest_de()
2081 if (ext4_match(dir, fname, de)) in ext4_find_dest_de()
2082 return -EEXIST; in ext4_find_dest_de()
2083 nlen = ext4_dir_rec_len(de->name_len, dir); in ext4_find_dest_de()
2084 rlen = ext4_rec_len_from_disk(de->rec_len, buf_size); in ext4_find_dest_de()
2085 if ((de->inode ? rlen - nlen : rlen) >= reclen) in ext4_find_dest_de()
2087 de = (struct ext4_dir_entry_2 *)((char *)de + rlen); in ext4_find_dest_de()
2090 if ((char *) de > top) in ext4_find_dest_de()
2091 return -ENOSPC; in ext4_find_dest_de()
2093 *dest_de = de; in ext4_find_dest_de()
2099 struct ext4_dir_entry_2 *de, in ext4_insert_dentry() argument
2106 nlen = ext4_dir_rec_len(de->name_len, dir); in ext4_insert_dentry()
2107 rlen = ext4_rec_len_from_disk(de->rec_len, buf_size); in ext4_insert_dentry()
2108 if (de->inode) { in ext4_insert_dentry()
2110 (struct ext4_dir_entry_2 *)((char *)de + nlen); in ext4_insert_dentry()
2111 de1->rec_len = ext4_rec_len_to_disk(rlen - nlen, buf_size); in ext4_insert_dentry()
2112 de->rec_len = ext4_rec_len_to_disk(nlen, buf_size); in ext4_insert_dentry()
2113 de = de1; in ext4_insert_dentry()
2115 de->file_type = EXT4_FT_UNKNOWN; in ext4_insert_dentry()
2116 de->inode = cpu_to_le32(inode->i_ino); in ext4_insert_dentry()
2117 ext4_set_de_type(inode->i_sb, de, inode->i_mode); in ext4_insert_dentry()
2118 de->name_len = fname_len(fname); in ext4_insert_dentry()
2119 memcpy(de->name, fname_name(fname), fname_len(fname)); in ext4_insert_dentry()
2121 struct dx_hash_info *hinfo = &fname->hinfo; in ext4_insert_dentry()
2123 EXT4_DIRENT_HASHES(de)->hash = cpu_to_le32(hinfo->hash); in ext4_insert_dentry()
2124 EXT4_DIRENT_HASHES(de)->minor_hash = in ext4_insert_dentry()
2125 cpu_to_le32(hinfo->minor_hash); in ext4_insert_dentry()
2130 * Add a new entry into a directory (leaf) block. If de is non-NULL,
2131 * it points to a directory entry which is guaranteed to be large
2132 * enough for new directory entry. If de is NULL, then
2134 * space. It will return -ENOSPC if no space is available, and -EIO
2135 * and -EEXIST if directory entry already exists.
2139 struct inode *inode, struct ext4_dir_entry_2 *de, in add_dirent_to_buf() argument
2142 unsigned int blocksize = dir->i_sb->s_blocksize; in add_dirent_to_buf()
2146 if (ext4_has_metadata_csum(inode->i_sb)) in add_dirent_to_buf()
2149 if (!de) { in add_dirent_to_buf()
2150 err = ext4_find_dest_de(dir, inode, bh, bh->b_data, in add_dirent_to_buf()
2151 blocksize - csum_size, fname, &de); in add_dirent_to_buf()
2156 err = ext4_journal_get_write_access(handle, dir->i_sb, bh, in add_dirent_to_buf()
2159 ext4_std_error(dir->i_sb, err); in add_dirent_to_buf()
2164 ext4_insert_dentry(dir, inode, de, blocksize, fname); in add_dirent_to_buf()
2184 ext4_std_error(dir->i_sb, err); in add_dirent_to_buf()
2193 unsigned int blocksize = dir->i_sb->s_blocksize; in ext4_check_dx_root()
2194 char *blockend = (char *)root + dir->i_sb->s_blocksize; in ext4_check_dx_root()
2196 fde = &root->dot; in ext4_check_dx_root()
2197 if (unlikely(fde->name_len != 1)) { in ext4_check_dx_root()
2201 if (unlikely(strncmp(root->dot_name, ".", fde->name_len))) { in ext4_check_dx_root()
2205 rlen = ext4_rec_len_from_disk(fde->rec_len, blocksize); in ext4_check_dx_root()
2211 fde = &root->dotdot; in ext4_check_dx_root()
2212 if (unlikely(fde->name_len != 2)) { in ext4_check_dx_root()
2216 if (unlikely(strncmp(root->dotdot_name, "..", fde->name_len))) { in ext4_check_dx_root()
2220 rlen = ext4_rec_len_from_disk(fde->rec_len, blocksize); in ext4_check_dx_root()
2246 struct ext4_dir_entry_2 *de, *de2; in make_indexed_dir() local
2255 if (ext4_has_metadata_csum(inode->i_sb)) in make_indexed_dir()
2258 blocksize = dir->i_sb->s_blocksize; in make_indexed_dir()
2259 dxtrace(printk(KERN_DEBUG "Creating index: inode %lu\n", dir->i_ino)); in make_indexed_dir()
2261 retval = ext4_journal_get_write_access(handle, dir->i_sb, bh, in make_indexed_dir()
2264 ext4_std_error(dir->i_sb, retval); in make_indexed_dir()
2269 root = (struct dx_root *) bh->b_data; in make_indexed_dir()
2272 return -EFSCORRUPTED; in make_indexed_dir()
2276 fde = &root->dotdot; in make_indexed_dir()
2277 de = (struct ext4_dir_entry_2 *)((char *)fde + in make_indexed_dir()
2278 ext4_rec_len_from_disk(fde->rec_len, blocksize)); in make_indexed_dir()
2279 len = ((char *) root) + (blocksize - csum_size) - (char *) de; in make_indexed_dir()
2288 data2 = bh2->b_data; in make_indexed_dir()
2290 memcpy(data2, de, len); in make_indexed_dir()
2291 memset(de, 0, len); /* wipe old data */ in make_indexed_dir()
2292 de = (struct ext4_dir_entry_2 *) data2; in make_indexed_dir()
2294 while ((char *)(de2 = ext4_next_entry(de, blocksize)) < top) { in make_indexed_dir()
2295 if (ext4_check_dir_entry(dir, NULL, de, bh2, data2, len, in make_indexed_dir()
2296 (char *)de - data2)) { in make_indexed_dir()
2299 return -EFSCORRUPTED; in make_indexed_dir()
2301 de = de2; in make_indexed_dir()
2303 de->rec_len = ext4_rec_len_to_disk(data2 + (blocksize - csum_size) - in make_indexed_dir()
2304 (char *) de, blocksize); in make_indexed_dir()
2310 de = (struct ext4_dir_entry_2 *) (&root->dotdot); in make_indexed_dir()
2311 de->rec_len = ext4_rec_len_to_disk( in make_indexed_dir()
2312 blocksize - ext4_dir_rec_len(2, NULL), blocksize); in make_indexed_dir()
2313 memset (&root->info, 0, sizeof(root->info)); in make_indexed_dir()
2314 root->info.info_length = sizeof(root->info); in make_indexed_dir()
2316 root->info.hash_version = DX_HASH_SIPHASH; in make_indexed_dir()
2318 root->info.hash_version = in make_indexed_dir()
2319 EXT4_SB(dir->i_sb)->s_def_hash_version; in make_indexed_dir()
2321 entries = root->entries; in make_indexed_dir()
2324 dx_set_limit(entries, dx_root_limit(dir, sizeof(root->info))); in make_indexed_dir()
2327 fname->hinfo.hash_version = root->info.hash_version; in make_indexed_dir()
2328 if (fname->hinfo.hash_version <= DX_HASH_TEA) in make_indexed_dir()
2329 fname->hinfo.hash_version += EXT4_SB(dir->i_sb)->s_hash_unsigned; in make_indexed_dir()
2330 fname->hinfo.seed = EXT4_SB(dir->i_sb)->s_hash_seed; in make_indexed_dir()
2335 fname_len(fname), &fname->hinfo); in make_indexed_dir()
2344 frame->entries = entries; in make_indexed_dir()
2345 frame->at = entries; in make_indexed_dir()
2346 frame->bh = bh; in make_indexed_dir()
2348 retval = ext4_handle_dirty_dx_node(handle, dir, frame->bh); in make_indexed_dir()
2355 de = do_split(handle,dir, &bh2, frame, &fname->hinfo); in make_indexed_dir()
2356 if (IS_ERR(de)) { in make_indexed_dir()
2357 retval = PTR_ERR(de); in make_indexed_dir()
2361 retval = add_dirent_to_buf(handle, fname, dir, inode, de, bh2); in make_indexed_dir()
2381 * NOTE!! The inode part of 'de' is left at 0 - which means you
2388 struct inode *dir = d_inode(dentry->d_parent); in ext4_add_entry()
2390 struct ext4_dir_entry_2 *de; in ext4_add_entry() local
2399 if (ext4_has_metadata_csum(inode->i_sb)) in ext4_add_entry()
2402 sb = dir->i_sb; in ext4_add_entry()
2403 blocksize = sb->s_blocksize; in ext4_add_entry()
2406 return -ENOKEY; in ext4_add_entry()
2408 if (!generic_ci_validate_strict_name(dir, &dentry->d_name)) in ext4_add_entry()
2409 return -EINVAL; in ext4_add_entry()
2411 retval = ext4_fname_setup_filename(dir, &dentry->d_name, 0, &fname); in ext4_add_entry()
2433 retval = -EFSCORRUPTED; in ext4_add_entry()
2442 blocks = dir->i_size >> sb->s_blocksize_bits; in ext4_add_entry()
2457 if (retval != -ENOSPC) in ext4_add_entry()
2476 de = (struct ext4_dir_entry_2 *) bh->b_data; in ext4_add_entry()
2477 de->inode = 0; in ext4_add_entry()
2478 de->rec_len = ext4_rec_len_to_disk(blocksize - csum_size, blocksize); in ext4_add_entry()
2483 retval = add_dirent_to_buf(handle, &fname, dir, inode, de, bh); in ext4_add_entry()
2501 struct super_block *sb = dir->i_sb; in ext4_dx_add_entry()
2502 struct ext4_dir_entry_2 *de; in ext4_dx_add_entry() local
2511 entries = frame->entries; in ext4_dx_add_entry()
2512 at = frame->at; in ext4_dx_add_entry()
2513 bh = ext4_read_dirblock(dir, dx_get_block(frame->at), DIRENT_HTREE); in ext4_dx_add_entry()
2526 if (err != -ENOSPC) in ext4_dx_add_entry()
2536 int levels = frame - frames + 1; in ext4_dx_add_entry()
2544 if (dx_get_count((frame - 1)->entries) < in ext4_dx_add_entry()
2545 dx_get_limit((frame - 1)->entries)) { in ext4_dx_add_entry()
2549 frame--; /* split higher index block */ in ext4_dx_add_entry()
2550 at = frame->at; in ext4_dx_add_entry()
2551 entries = frame->entries; in ext4_dx_add_entry()
2557 dir->i_ino, levels); in ext4_dx_add_entry()
2563 err = -ENOSPC; in ext4_dx_add_entry()
2572 node2 = (struct dx_node *)(bh2->b_data); in ext4_dx_add_entry()
2573 entries2 = node2->entries; in ext4_dx_add_entry()
2574 memset(&node2->fake, 0, sizeof(struct fake_dirent)); in ext4_dx_add_entry()
2575 node2->fake.rec_len = ext4_rec_len_to_disk(sb->s_blocksize, in ext4_dx_add_entry()
2576 sb->s_blocksize); in ext4_dx_add_entry()
2577 BUFFER_TRACE(frame->bh, "get_write_access"); in ext4_dx_add_entry()
2578 err = ext4_journal_get_write_access(handle, sb, frame->bh, in ext4_dx_add_entry()
2585 unsigned icount1 = icount/2, icount2 = icount - icount1; in ext4_dx_add_entry()
2590 BUFFER_TRACE(frame->bh, "get_write_access"); /* index root */ in ext4_dx_add_entry()
2592 (frame - 1)->bh, in ext4_dx_add_entry()
2606 if (at - entries >= icount1) { in ext4_dx_add_entry()
2607 frame->at = at - entries - icount1 + entries2; in ext4_dx_add_entry()
2608 frame->entries = entries = entries2; in ext4_dx_add_entry()
2609 swap(frame->bh, bh2); in ext4_dx_add_entry()
2611 dx_insert_block((frame - 1), hash2, newblock); in ext4_dx_add_entry()
2612 dxtrace(dx_show_index("node", frame->entries)); in ext4_dx_add_entry()
2614 ((struct dx_node *) bh2->b_data)->entries)); in ext4_dx_add_entry()
2622 (frame - 1)->bh); in ext4_dx_add_entry()
2626 frame->bh); in ext4_dx_add_entry()
2638 dxroot = (struct dx_root *)frames[0].bh->b_data; in ext4_dx_add_entry()
2639 dxroot->info.indirect_levels += 1; in ext4_dx_add_entry()
2642 dxroot->info.indirect_levels)); in ext4_dx_add_entry()
2643 err = ext4_handle_dirty_dx_node(handle, dir, frame->bh); in ext4_dx_add_entry()
2654 de = do_split(handle, dir, &bh, frame, &fname->hinfo); in ext4_dx_add_entry()
2655 if (IS_ERR(de)) { in ext4_dx_add_entry()
2656 err = PTR_ERR(de); in ext4_dx_add_entry()
2659 err = add_dirent_to_buf(handle, fname, dir, inode, de, bh); in ext4_dx_add_entry()
2663 ext4_std_error(dir->i_sb, err); /* this is a no-op if err == 0 */ in ext4_dx_add_entry()
2667 /* @restart is true means htree-path has been changed, we need to in ext4_dx_add_entry()
2668 * repeat dx_probe() to find out valid htree-path in ext4_dx_add_entry()
2686 struct ext4_dir_entry_2 *de, *pde; in ext4_generic_delete_entry() local
2687 unsigned int blocksize = dir->i_sb->s_blocksize; in ext4_generic_delete_entry()
2692 de = entry_buf; in ext4_generic_delete_entry()
2693 while (i < buf_size - csum_size) { in ext4_generic_delete_entry()
2694 if (ext4_check_dir_entry(dir, NULL, de, bh, in ext4_generic_delete_entry()
2696 return -EFSCORRUPTED; in ext4_generic_delete_entry()
2697 if (de == de_del) { in ext4_generic_delete_entry()
2699 pde->rec_len = ext4_rec_len_to_disk( in ext4_generic_delete_entry()
2700 ext4_rec_len_from_disk(pde->rec_len, in ext4_generic_delete_entry()
2702 ext4_rec_len_from_disk(de->rec_len, in ext4_generic_delete_entry()
2707 memset(de, 0, ext4_rec_len_from_disk(de->rec_len, in ext4_generic_delete_entry()
2711 de->inode = 0; in ext4_generic_delete_entry()
2712 memset(&de->name_len, 0, in ext4_generic_delete_entry()
2713 ext4_rec_len_from_disk(de->rec_len, in ext4_generic_delete_entry()
2714 blocksize) - in ext4_generic_delete_entry()
2722 i += ext4_rec_len_from_disk(de->rec_len, blocksize); in ext4_generic_delete_entry()
2723 pde = de; in ext4_generic_delete_entry()
2724 de = ext4_next_entry(de, blocksize); in ext4_generic_delete_entry()
2726 return -ENOENT; in ext4_generic_delete_entry()
2744 if (ext4_has_metadata_csum(dir->i_sb)) in ext4_delete_entry()
2748 err = ext4_journal_get_write_access(handle, dir->i_sb, bh, in ext4_delete_entry()
2753 err = ext4_generic_delete_entry(dir, de_del, bh, bh->b_data, in ext4_delete_entry()
2754 dir->i_sb->s_blocksize, csum_size); in ext4_delete_entry()
2765 if (err != -ENOENT) in ext4_delete_entry()
2766 ext4_std_error(dir->i_sb, err); in ext4_delete_entry()
2773 * the 16-bit i_links_count field on disk. Directories with i_nlink == 1 mean
2777 * feature is not enabled and returned -EMLINK. The is_dx() check is a proxy
2778 * for checking S_ISDIR(inode) (since the INODE_INDEX feature will not be set
2779 * on regular files) and to avoid creating huge/slow non-HTREE directories.
2785 (inode->i_nlink > EXT4_LINK_MAX || inode->i_nlink == 2)) in ext4_inc_count()
2790 * If a directory had nlink == 1, then we should let it be 1. This indicates
2795 if (!S_ISDIR(inode->i_mode) || inode->i_nlink > 2) in ext4_dec_count()
2801 * Add non-directory inode to a directory. On success, the inode reference is
2809 struct inode *dir = d_inode(dentry->d_parent); in ext4_add_nondir()
2830 * is so far negative - it has no inode.
2846 credits = (EXT4_DATA_TRANS_BLOCKS(dir->i_sb) + in ext4_create()
2849 inode = ext4_new_inode_start_handle(idmap, dir, mode, &dentry->d_name, in ext4_create()
2854 inode->i_op = &ext4_file_inode_operations; in ext4_create()
2855 inode->i_fop = &ext4_file_operations; in ext4_create()
2865 if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries)) in ext4_create()
2881 credits = (EXT4_DATA_TRANS_BLOCKS(dir->i_sb) + in ext4_mknod()
2884 inode = ext4_new_inode_start_handle(idmap, dir, mode, &dentry->d_name, in ext4_mknod()
2889 init_special_inode(inode, inode->i_mode, rdev); in ext4_mknod()
2890 inode->i_op = &ext4_special_inode_operations; in ext4_mknod()
2899 if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries)) in ext4_mknod()
2919 EXT4_MAXQUOTAS_TRANS_BLOCKS(dir->i_sb) + in ext4_tmpfile()
2924 inode->i_op = &ext4_file_inode_operations; in ext4_tmpfile()
2925 inode->i_fop = &ext4_file_operations; in ext4_tmpfile()
2936 if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries)) in ext4_tmpfile()
2946 struct ext4_dir_entry_2 *de, in ext4_init_dot_dotdot() argument
2950 de->inode = cpu_to_le32(inode->i_ino); in ext4_init_dot_dotdot()
2951 de->name_len = 1; in ext4_init_dot_dotdot()
2952 de->rec_len = ext4_rec_len_to_disk(ext4_dir_rec_len(de->name_len, NULL), in ext4_init_dot_dotdot()
2954 strcpy(de->name, "."); in ext4_init_dot_dotdot()
2955 ext4_set_de_type(inode->i_sb, de, S_IFDIR); in ext4_init_dot_dotdot()
2957 de = ext4_next_entry(de, blocksize); in ext4_init_dot_dotdot()
2958 de->inode = cpu_to_le32(parent_ino); in ext4_init_dot_dotdot()
2959 de->name_len = 2; in ext4_init_dot_dotdot()
2961 de->rec_len = ext4_rec_len_to_disk(blocksize - in ext4_init_dot_dotdot()
2965 de->rec_len = ext4_rec_len_to_disk( in ext4_init_dot_dotdot()
2966 ext4_dir_rec_len(de->name_len, NULL), in ext4_init_dot_dotdot()
2968 strcpy(de->name, ".."); in ext4_init_dot_dotdot()
2969 ext4_set_de_type(inode->i_sb, de, S_IFDIR); in ext4_init_dot_dotdot()
2971 return ext4_next_entry(de, blocksize); in ext4_init_dot_dotdot()
2978 struct ext4_dir_entry_2 *de; in ext4_init_new_dir() local
2980 unsigned int blocksize = dir->i_sb->s_blocksize; in ext4_init_new_dir()
2984 if (ext4_has_metadata_csum(dir->i_sb)) in ext4_init_new_dir()
2989 if (err < 0 && err != -ENOSPC) in ext4_init_new_dir()
2995 inode->i_size = 0; in ext4_init_new_dir()
2999 de = (struct ext4_dir_entry_2 *)dir_block->b_data; in ext4_init_new_dir()
3000 ext4_init_dot_dotdot(inode, de, blocksize, csum_size, dir->i_ino, 0); in ext4_init_new_dir()
3023 return -EMLINK; in ext4_mkdir()
3029 credits = (EXT4_DATA_TRANS_BLOCKS(dir->i_sb) + in ext4_mkdir()
3033 &dentry->d_name, in ext4_mkdir()
3040 inode->i_op = &ext4_dir_inode_operations; in ext4_mkdir()
3041 inode->i_fop = &ext4_dir_operations; in ext4_mkdir()
3075 if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries)) in ext4_mkdir()
3087 struct ext4_dir_entry_2 *de; in ext4_empty_dir() local
3099 sb = inode->i_sb; in ext4_empty_dir()
3100 if (inode->i_size < ext4_dir_rec_len(1, NULL) + in ext4_empty_dir()
3109 de = (struct ext4_dir_entry_2 *) bh->b_data; in ext4_empty_dir()
3110 if (ext4_check_dir_entry(inode, NULL, de, bh, bh->b_data, bh->b_size, in ext4_empty_dir()
3112 le32_to_cpu(de->inode) != inode->i_ino || strcmp(".", de->name)) { in ext4_empty_dir()
3117 offset = ext4_rec_len_from_disk(de->rec_len, sb->s_blocksize); in ext4_empty_dir()
3118 de = ext4_next_entry(de, sb->s_blocksize); in ext4_empty_dir()
3119 if (ext4_check_dir_entry(inode, NULL, de, bh, bh->b_data, bh->b_size, in ext4_empty_dir()
3121 le32_to_cpu(de->inode) == 0 || strcmp("..", de->name)) { in ext4_empty_dir()
3126 offset += ext4_rec_len_from_disk(de->rec_len, sb->s_blocksize); in ext4_empty_dir()
3127 while (offset < inode->i_size) { in ext4_empty_dir()
3128 if (!(offset & (sb->s_blocksize - 1))) { in ext4_empty_dir()
3134 offset += sb->s_blocksize; in ext4_empty_dir()
3140 de = (struct ext4_dir_entry_2 *) (bh->b_data + in ext4_empty_dir()
3141 (offset & (sb->s_blocksize - 1))); in ext4_empty_dir()
3142 if (ext4_check_dir_entry(inode, NULL, de, bh, in ext4_empty_dir()
3143 bh->b_data, bh->b_size, offset) || in ext4_empty_dir()
3144 le32_to_cpu(de->inode)) { in ext4_empty_dir()
3148 offset += ext4_rec_len_from_disk(de->rec_len, sb->s_blocksize); in ext4_empty_dir()
3159 struct ext4_dir_entry_2 *de; in ext4_rmdir() local
3162 if (unlikely(ext4_forced_shutdown(dir->i_sb))) in ext4_rmdir()
3163 return -EIO; in ext4_rmdir()
3174 retval = -ENOENT; in ext4_rmdir()
3175 bh = ext4_find_entry(dir, &dentry->d_name, &de, NULL); in ext4_rmdir()
3183 retval = -EFSCORRUPTED; in ext4_rmdir()
3184 if (le32_to_cpu(de->inode) != inode->i_ino) in ext4_rmdir()
3187 retval = -ENOTEMPTY; in ext4_rmdir()
3192 EXT4_DATA_TRANS_BLOCKS(dir->i_sb)); in ext4_rmdir()
3202 retval = ext4_delete_entry(handle, dir, de, bh); in ext4_rmdir()
3208 dentry->d_name.len, dentry->d_name.name, in ext4_rmdir()
3209 inode->i_nlink); in ext4_rmdir()
3215 inode->i_size = 0; in ext4_rmdir()
3228 * Case-insensitiveness. Eventually we'll want avoid in ext4_rmdir()
3247 int retval = -ENOENT; in __ext4_unlink()
3249 struct ext4_dir_entry_2 *de; in __ext4_unlink() local
3255 * directory's encryption key, which isn't GFP_NOFS-safe. in __ext4_unlink()
3257 bh = ext4_find_entry(dir, d_name, &de, NULL); in __ext4_unlink()
3262 return -ENOENT; in __ext4_unlink()
3264 if (le32_to_cpu(de->inode) != inode->i_ino) { in __ext4_unlink()
3270 if (EXT4_SB(inode->i_sb)->s_mount_state & EXT4_FC_REPLAY) in __ext4_unlink()
3277 EXT4_DATA_TRANS_BLOCKS(dir->i_sb)); in __ext4_unlink()
3287 retval = ext4_delete_entry(handle, dir, de, bh); in __ext4_unlink()
3298 if (inode->i_nlink == 0) in __ext4_unlink()
3300 d_name->len, d_name->name); in __ext4_unlink()
3303 if (!inode->i_nlink) in __ext4_unlink()
3320 if (unlikely(ext4_forced_shutdown(dir->i_sb))) in ext4_unlink()
3321 return -EIO; in ext4_unlink()
3335 retval = __ext4_unlink(dir, &dentry->d_name, d_inode(dentry), dentry); in ext4_unlink()
3338 * Case-insensitiveness. Eventually we'll want avoid in ext4_unlink()
3363 err = ext4_journal_get_write_access(handle, inode->i_sb, bh, EXT4_JTR_NONE); in ext4_init_symlink_block()
3367 kaddr = (char *)bh->b_data; in ext4_init_symlink_block()
3368 memcpy(kaddr, disk_link->name, disk_link->len); in ext4_init_symlink_block()
3369 inode->i_size = disk_link->len - 1; in ext4_init_symlink_block()
3370 EXT4_I(inode)->i_disksize = inode->i_size; in ext4_init_symlink_block()
3387 if (unlikely(ext4_forced_shutdown(dir->i_sb))) in ext4_symlink()
3388 return -EIO; in ext4_symlink()
3390 err = fscrypt_prepare_symlink(dir, symname, len, dir->i_sb->s_blocksize, in ext4_symlink()
3405 credits = EXT4_DATA_TRANS_BLOCKS(dir->i_sb) + in ext4_symlink()
3409 &dentry->d_name, 0, NULL, in ext4_symlink()
3423 inode->i_op = &ext4_encrypted_symlink_inode_operations; in ext4_symlink()
3426 inode->i_op = &ext4_symlink_inode_operations; in ext4_symlink()
3428 inode->i_op = &ext4_fast_symlink_inode_operations; in ext4_symlink()
3440 memcpy((char *)&EXT4_I(inode)->i_data, disk_link.name, in ext4_symlink()
3442 inode->i_size = disk_link.len - 1; in ext4_symlink()
3443 EXT4_I(inode)->i_disksize = inode->i_size; in ext4_symlink()
3445 inode_set_cached_link(inode, (char *)&EXT4_I(inode)->i_data, in ext4_symlink()
3446 inode->i_size); in ext4_symlink()
3463 if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries)) in ext4_symlink()
3476 (EXT4_DATA_TRANS_BLOCKS(dir->i_sb) + in __ext4_link()
3494 if (inode->i_nlink == 1) in __ext4_link()
3503 if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries)) in __ext4_link()
3514 if (inode->i_nlink >= EXT4_LINK_MAX) in ext4_link()
3515 return -EMLINK; in ext4_link()
3522 (!projid_eq(EXT4_I(dir)->i_projid, in ext4_link()
3523 EXT4_I(old_dentry->d_inode)->i_projid))) in ext4_link()
3524 return -EXDEV; in ext4_link()
3534 * It should be the inode block if it is inlined or the 1st block
3546 struct ext4_dir_entry_2 *de; in ext4_get_first_dir_block() local
3555 de = (struct ext4_dir_entry_2 *) bh->b_data; in ext4_get_first_dir_block()
3556 if (ext4_check_dir_entry(inode, NULL, de, bh, bh->b_data, in ext4_get_first_dir_block()
3557 bh->b_size, 0) || in ext4_get_first_dir_block()
3558 le32_to_cpu(de->inode) != inode->i_ino || in ext4_get_first_dir_block()
3559 strcmp(".", de->name)) { in ext4_get_first_dir_block()
3562 *retval = -EFSCORRUPTED; in ext4_get_first_dir_block()
3565 offset = ext4_rec_len_from_disk(de->rec_len, in ext4_get_first_dir_block()
3566 inode->i_sb->s_blocksize); in ext4_get_first_dir_block()
3567 de = ext4_next_entry(de, inode->i_sb->s_blocksize); in ext4_get_first_dir_block()
3568 if (ext4_check_dir_entry(inode, NULL, de, bh, bh->b_data, in ext4_get_first_dir_block()
3569 bh->b_size, offset) || in ext4_get_first_dir_block()
3570 le32_to_cpu(de->inode) == 0 || strcmp("..", de->name)) { in ext4_get_first_dir_block()
3573 *retval = -EFSCORRUPTED; in ext4_get_first_dir_block()
3576 *parent_de = de; in ext4_get_first_dir_block()
3594 struct ext4_dir_entry_2 *de; member
3607 ent->is_dir = true; in ext4_rename_dir_prepare()
3611 ent->dir_bh = ext4_get_first_dir_block(handle, ent->inode, in ext4_rename_dir_prepare()
3612 &retval, &ent->parent_de, in ext4_rename_dir_prepare()
3613 &ent->dir_inlined); in ext4_rename_dir_prepare()
3614 if (!ent->dir_bh) in ext4_rename_dir_prepare()
3616 if (le32_to_cpu(ent->parent_de->inode) != ent->dir->i_ino) in ext4_rename_dir_prepare()
3617 return -EFSCORRUPTED; in ext4_rename_dir_prepare()
3618 BUFFER_TRACE(ent->dir_bh, "get_write_access"); in ext4_rename_dir_prepare()
3619 return ext4_journal_get_write_access(handle, ent->dir->i_sb, in ext4_rename_dir_prepare()
3620 ent->dir_bh, EXT4_JTR_NONE); in ext4_rename_dir_prepare()
3628 if (!ent->dir_bh) in ext4_rename_dir_finish()
3631 ent->parent_de->inode = cpu_to_le32(dir_ino); in ext4_rename_dir_finish()
3632 BUFFER_TRACE(ent->dir_bh, "call ext4_handle_dirty_metadata"); in ext4_rename_dir_finish()
3633 if (!ent->dir_inlined) { in ext4_rename_dir_finish()
3634 if (is_dx(ent->inode)) { in ext4_rename_dir_finish()
3636 ent->inode, in ext4_rename_dir_finish()
3637 ent->dir_bh); in ext4_rename_dir_finish()
3639 retval = ext4_handle_dirty_dirblock(handle, ent->inode, in ext4_rename_dir_finish()
3640 ent->dir_bh); in ext4_rename_dir_finish()
3643 retval = ext4_mark_inode_dirty(handle, ent->inode); in ext4_rename_dir_finish()
3646 ext4_std_error(ent->dir->i_sb, retval); in ext4_rename_dir_finish()
3657 BUFFER_TRACE(ent->bh, "get write access"); in ext4_setent()
3658 retval = ext4_journal_get_write_access(handle, ent->dir->i_sb, ent->bh, in ext4_setent()
3662 ent->de->inode = cpu_to_le32(ino); in ext4_setent()
3663 if (ext4_has_feature_filetype(ent->dir->i_sb)) in ext4_setent()
3664 ent->de->file_type = file_type; in ext4_setent()
3665 inode_inc_iversion(ent->dir); in ext4_setent()
3666 inode_set_mtime_to_ts(ent->dir, inode_set_ctime_current(ent->dir)); in ext4_setent()
3667 retval = ext4_mark_inode_dirty(handle, ent->dir); in ext4_setent()
3668 BUFFER_TRACE(ent->bh, "call ext4_handle_dirty_metadata"); in ext4_setent()
3669 if (!ent->inlined) { in ext4_setent()
3670 retval2 = ext4_handle_dirty_dirblock(handle, ent->dir, ent->bh); in ext4_setent()
3672 ext4_std_error(ent->dir->i_sb, retval2); in ext4_setent()
3686 * old->de could have moved from under us during make indexed dir, in ext4_resetent()
3687 * so the old->de may no longer valid and need to find it again in ext4_resetent()
3690 old.bh = ext4_find_entry(old.dir, &old.dentry->d_name, &old.de, in ext4_resetent()
3695 retval = -ENOENT; in ext4_resetent()
3697 ext4_std_error(old.dir->i_sb, retval); in ext4_resetent()
3708 int retval = -ENOENT; in ext4_find_delete_entry()
3710 struct ext4_dir_entry_2 *de; in ext4_find_delete_entry() local
3712 bh = ext4_find_entry(dir, d_name, &de, NULL); in ext4_find_delete_entry()
3716 retval = ext4_delete_entry(handle, dir, de, bh); in ext4_find_delete_entry()
3727 * ent->de could have moved from under us during htree split, so make in ext4_rename_delete()
3728 * sure that we are deleting the right entry. We might also be pointing in ext4_rename_delete()
3729 * to a stale entry in the unused part of ent->bh so just checking inum in ext4_rename_delete()
3732 if (le32_to_cpu(ent->de->inode) != ent->inode->i_ino || in ext4_rename_delete()
3733 ent->de->name_len != ent->dentry->d_name.len || in ext4_rename_delete()
3734 strncmp(ent->de->name, ent->dentry->d_name.name, in ext4_rename_delete()
3735 ent->de->name_len) || in ext4_rename_delete()
3737 retval = ext4_find_delete_entry(handle, ent->dir, in ext4_rename_delete()
3738 &ent->dentry->d_name); in ext4_rename_delete()
3740 retval = ext4_delete_entry(handle, ent->dir, ent->de, ent->bh); in ext4_rename_delete()
3741 if (retval == -ENOENT) { in ext4_rename_delete()
3742 retval = ext4_find_delete_entry(handle, ent->dir, in ext4_rename_delete()
3743 &ent->dentry->d_name); in ext4_rename_delete()
3748 ext4_warning_inode(ent->dir, in ext4_rename_delete()
3750 ent->dir->i_nlink, retval); in ext4_rename_delete()
3756 if (ent->dir_nlink_delta) { in ext4_update_dir_count()
3757 if (ent->dir_nlink_delta == -1) in ext4_update_dir_count()
3758 ext4_dec_count(ent->dir); in ext4_update_dir_count()
3760 ext4_inc_count(ent->dir); in ext4_update_dir_count()
3761 ext4_mark_inode_dirty(handle, ent->dir); in ext4_update_dir_count()
3777 credits += (EXT4_MAXQUOTAS_TRANS_BLOCKS(ent->dir->i_sb) + in ext4_whiteout_for_rename()
3780 wh = ext4_new_inode_start_handle(idmap, ent->dir, in ext4_whiteout_for_rename()
3782 &ent->dentry->d_name, 0, NULL, in ext4_whiteout_for_rename()
3789 if (PTR_ERR(wh) == -ENOSPC && in ext4_whiteout_for_rename()
3790 ext4_should_retry_alloc(ent->dir->i_sb, &retries)) in ext4_whiteout_for_rename()
3794 init_special_inode(wh, wh->i_mode, WHITEOUT_DEV); in ext4_whiteout_for_rename()
3795 wh->i_op = &ext4_special_inode_operations; in ext4_whiteout_for_rename()
3802 * higher-level routines.
3829 if (new.inode && new.inode->i_nlink == 0) { in ext4_rename()
3832 return -EFSCORRUPTED; in ext4_rename()
3836 (!projid_eq(EXT4_I(new_dir)->i_projid, in ext4_rename()
3837 EXT4_I(old_dentry->d_inode)->i_projid))) in ext4_rename()
3838 return -EXDEV; in ext4_rename()
3858 old.bh = ext4_find_entry(old.dir, &old.dentry->d_name, &old.de, in ext4_rename()
3867 * same name. Goodbye sticky bit ;-< in ext4_rename()
3869 retval = -ENOENT; in ext4_rename()
3870 if (!old.bh || le32_to_cpu(old.de->inode) != old.inode->i_ino) in ext4_rename()
3873 new.bh = ext4_find_entry(new.dir, &new.dentry->d_name, in ext4_rename()
3874 &new.de, &new.inlined); in ext4_rename()
3886 if (new.inode && !test_opt(new.dir->i_sb, NO_AUTO_DA_ALLOC)) in ext4_rename()
3889 credits = (2 * EXT4_DATA_TRANS_BLOCKS(old.dir->i_sb) + in ext4_rename()
3905 old_file_type = old.de->file_type; in ext4_rename()
3909 if (S_ISDIR(old.inode->i_mode)) { in ext4_rename()
3911 retval = -ENOTEMPTY; in ext4_rename()
3915 retval = -EMLINK; in ext4_rename()
3927 * re-read the directory, or else we end up trying to delete a dirent in ext4_rename()
3930 force_reread = (new.dir->i_ino == old.dir->i_ino && in ext4_rename()
3936 * to be still pointing to the valid old entry. in ext4_rename()
3938 retval = ext4_setent(handle, &old, whiteout->i_ino, in ext4_rename()
3953 old.inode->i_ino, old_file_type); in ext4_rename()
3984 retval = ext4_rename_dir_finish(handle, &old, new.dir->i_ino); in ext4_rename()
3991 * parent, ext4_dec_count() won't work for many-linked in ext4_rename()
4012 ext4_fc_mark_ineligible(old.inode->i_sb, in ext4_rename()
4015 struct super_block *sb = old.inode->i_sb; in ext4_rename()
4020 !(EXT4_SB(sb)->s_mount_state & EXT4_FC_REPLAY) && in ext4_rename()
4034 if (!new.inode->i_nlink) in ext4_rename()
4043 old.inode->i_ino, old_file_type); in ext4_rename()
4080 !projid_eq(EXT4_I(new_dir)->i_projid, in ext4_cross_rename()
4081 EXT4_I(old_dentry->d_inode)->i_projid)) || in ext4_cross_rename()
4083 !projid_eq(EXT4_I(old_dir)->i_projid, in ext4_cross_rename()
4084 EXT4_I(new_dentry->d_inode)->i_projid))) in ext4_cross_rename()
4085 return -EXDEV; in ext4_cross_rename()
4094 old.bh = ext4_find_entry(old.dir, &old.dentry->d_name, in ext4_cross_rename()
4095 &old.de, &old.inlined); in ext4_cross_rename()
4102 * same name. Goodbye sticky bit ;-< in ext4_cross_rename()
4104 retval = -ENOENT; in ext4_cross_rename()
4105 if (!old.bh || le32_to_cpu(old.de->inode) != old.inode->i_ino) in ext4_cross_rename()
4108 new.bh = ext4_find_entry(new.dir, &new.dentry->d_name, in ext4_cross_rename()
4109 &new.de, &new.inlined); in ext4_cross_rename()
4117 if (!new.bh || le32_to_cpu(new.de->inode) != new.inode->i_ino) in ext4_cross_rename()
4121 (2 * EXT4_DATA_TRANS_BLOCKS(old.dir->i_sb) + in ext4_cross_rename()
4132 if (S_ISDIR(old.inode->i_mode)) { in ext4_cross_rename()
4137 if (S_ISDIR(new.inode->i_mode)) { in ext4_cross_rename()
4145 * nlink only needs to be modified if this is a cross directory rename. in ext4_cross_rename()
4148 old.dir_nlink_delta = old.is_dir ? -1 : 1; in ext4_cross_rename()
4149 new.dir_nlink_delta = -old.dir_nlink_delta; in ext4_cross_rename()
4150 retval = -EMLINK; in ext4_cross_rename()
4156 new_file_type = new.de->file_type; in ext4_cross_rename()
4157 retval = ext4_setent(handle, &new, old.inode->i_ino, old.de->file_type); in ext4_cross_rename()
4161 retval = ext4_setent(handle, &old, new.inode->i_ino, new_file_type); in ext4_cross_rename()
4177 ext4_fc_mark_ineligible(new.inode->i_sb, in ext4_cross_rename()
4180 retval = ext4_rename_dir_finish(handle, &old, new.dir->i_ino); in ext4_cross_rename()
4185 retval = ext4_rename_dir_finish(handle, &new, old.dir->i_ino); in ext4_cross_rename()
4210 if (unlikely(ext4_forced_shutdown(old_dir->i_sb))) in ext4_rename2()
4211 return -EIO; in ext4_rename2()
4214 return -EINVAL; in ext4_rename2()