diff options
author | Richard Weinberger <richard@nod.at> | 2016-10-19 09:59:12 -0400 |
---|---|---|
committer | Richard Weinberger <richard@nod.at> | 2016-12-12 17:07:38 -0500 |
commit | d63d61c16972c667d770f713c21aa04e2c0489d2 (patch) | |
tree | 9e40aed759c90f2435d36ea98a2ddbfed4c0e811 /fs/ubifs | |
parent | cc41a536524fba126ab11c41a866cf9037adbaf8 (diff) |
ubifs: Implement UBIFS_FLG_DOUBLE_HASH
This feature flag indicates that all directory entry nodes have a 32bit
cookie set and therefore UBIFS is allowed to perform lookups by hash.
Signed-off-by: Richard Weinberger <richard@nod.at>
Diffstat (limited to 'fs/ubifs')
-rw-r--r-- | fs/ubifs/journal.c | 14 | ||||
-rw-r--r-- | fs/ubifs/sb.c | 2 | ||||
-rw-r--r-- | fs/ubifs/tnc.c | 3 | ||||
-rw-r--r-- | fs/ubifs/ubifs-media.h | 3 | ||||
-rw-r--r-- | fs/ubifs/ubifs.h | 2 |
5 files changed, 21 insertions, 3 deletions
diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c index 88d33775f18b..a459211a1c21 100644 --- a/fs/ubifs/journal.c +++ b/fs/ubifs/journal.c | |||
@@ -501,6 +501,14 @@ static void mark_inode_clean(struct ubifs_info *c, struct ubifs_inode *ui) | |||
501 | ui->dirty = 0; | 501 | ui->dirty = 0; |
502 | } | 502 | } |
503 | 503 | ||
504 | static void set_dent_cookie(struct ubifs_info *c, struct ubifs_dent_node *dent) | ||
505 | { | ||
506 | if (c->double_hash) | ||
507 | dent->cookie = prandom_u32(); | ||
508 | else | ||
509 | dent->cookie = 0; | ||
510 | } | ||
511 | |||
504 | /** | 512 | /** |
505 | * ubifs_jnl_update - update inode. | 513 | * ubifs_jnl_update - update inode. |
506 | * @c: UBIFS file-system description object | 514 | * @c: UBIFS file-system description object |
@@ -589,7 +597,7 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir, | |||
589 | dent->nlen = cpu_to_le16(fname_len(nm)); | 597 | dent->nlen = cpu_to_le16(fname_len(nm)); |
590 | memcpy(dent->name, fname_name(nm), fname_len(nm)); | 598 | memcpy(dent->name, fname_name(nm), fname_len(nm)); |
591 | dent->name[fname_len(nm)] = '\0'; | 599 | dent->name[fname_len(nm)] = '\0'; |
592 | dent->cookie = prandom_u32(); | 600 | set_dent_cookie(c, dent); |
593 | 601 | ||
594 | zero_dent_node_unused(dent); | 602 | zero_dent_node_unused(dent); |
595 | ubifs_prep_grp_node(c, dent, dlen, 0); | 603 | ubifs_prep_grp_node(c, dent, dlen, 0); |
@@ -1125,7 +1133,7 @@ int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir, | |||
1125 | dent->nlen = cpu_to_le16(fname_len(new_nm)); | 1133 | dent->nlen = cpu_to_le16(fname_len(new_nm)); |
1126 | memcpy(dent->name, fname_name(new_nm), fname_len(new_nm)); | 1134 | memcpy(dent->name, fname_name(new_nm), fname_len(new_nm)); |
1127 | dent->name[fname_len(new_nm)] = '\0'; | 1135 | dent->name[fname_len(new_nm)] = '\0'; |
1128 | dent->cookie = prandom_u32(); | 1136 | set_dent_cookie(c, dent); |
1129 | zero_dent_node_unused(dent); | 1137 | zero_dent_node_unused(dent); |
1130 | ubifs_prep_grp_node(c, dent, dlen1, 0); | 1138 | ubifs_prep_grp_node(c, dent, dlen1, 0); |
1131 | 1139 | ||
@@ -1144,7 +1152,7 @@ int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir, | |||
1144 | dent2->nlen = cpu_to_le16(fname_len(old_nm)); | 1152 | dent2->nlen = cpu_to_le16(fname_len(old_nm)); |
1145 | memcpy(dent2->name, fname_name(old_nm), fname_len(old_nm)); | 1153 | memcpy(dent2->name, fname_name(old_nm), fname_len(old_nm)); |
1146 | dent2->name[fname_len(old_nm)] = '\0'; | 1154 | dent2->name[fname_len(old_nm)] = '\0'; |
1147 | dent2->cookie = prandom_u32(); | 1155 | set_dent_cookie(c, dent2); |
1148 | zero_dent_node_unused(dent2); | 1156 | zero_dent_node_unused(dent2); |
1149 | ubifs_prep_grp_node(c, dent2, dlen2, 0); | 1157 | ubifs_prep_grp_node(c, dent2, dlen2, 0); |
1150 | 1158 | ||
diff --git a/fs/ubifs/sb.c b/fs/ubifs/sb.c index 3cbb904a6d7d..4a2b4c361587 100644 --- a/fs/ubifs/sb.c +++ b/fs/ubifs/sb.c | |||
@@ -163,6 +163,7 @@ static int create_default_filesystem(struct ubifs_info *c) | |||
163 | tmp64 = (long long)max_buds * c->leb_size; | 163 | tmp64 = (long long)max_buds * c->leb_size; |
164 | if (big_lpt) | 164 | if (big_lpt) |
165 | sup_flags |= UBIFS_FLG_BIGLPT; | 165 | sup_flags |= UBIFS_FLG_BIGLPT; |
166 | sup_flags |= UBIFS_FLG_DOUBLE_HASH; | ||
166 | 167 | ||
167 | sup->ch.node_type = UBIFS_SB_NODE; | 168 | sup->ch.node_type = UBIFS_SB_NODE; |
168 | sup->key_hash = UBIFS_KEY_HASH_R5; | 169 | sup->key_hash = UBIFS_KEY_HASH_R5; |
@@ -620,6 +621,7 @@ int ubifs_read_superblock(struct ubifs_info *c) | |||
620 | memcpy(&c->uuid, &sup->uuid, 16); | 621 | memcpy(&c->uuid, &sup->uuid, 16); |
621 | c->big_lpt = !!(sup_flags & UBIFS_FLG_BIGLPT); | 622 | c->big_lpt = !!(sup_flags & UBIFS_FLG_BIGLPT); |
622 | c->space_fixup = !!(sup_flags & UBIFS_FLG_SPACE_FIXUP); | 623 | c->space_fixup = !!(sup_flags & UBIFS_FLG_SPACE_FIXUP); |
624 | c->double_hash = !!(sup_flags & UBIFS_FLG_DOUBLE_HASH); | ||
623 | 625 | ||
624 | /* Automatically increase file system size to the maximum size */ | 626 | /* Automatically increase file system size to the maximum size */ |
625 | c->old_leb_cnt = c->leb_cnt; | 627 | c->old_leb_cnt = c->leb_cnt; |
diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c index 1bba4c8b5d3d..74ae2de949df 100644 --- a/fs/ubifs/tnc.c +++ b/fs/ubifs/tnc.c | |||
@@ -1930,6 +1930,9 @@ int ubifs_tnc_lookup_dh(struct ubifs_info *c, const union ubifs_key *key, | |||
1930 | int err; | 1930 | int err; |
1931 | const struct ubifs_dent_node *dent = node; | 1931 | const struct ubifs_dent_node *dent = node; |
1932 | 1932 | ||
1933 | if (!c->double_hash) | ||
1934 | return -EOPNOTSUPP; | ||
1935 | |||
1933 | /* | 1936 | /* |
1934 | * We assume that in most of the cases there are no name collisions and | 1937 | * We assume that in most of the cases there are no name collisions and |
1935 | * 'ubifs_tnc_lookup()' returns us the right direntry. | 1938 | * 'ubifs_tnc_lookup()' returns us the right direntry. |
diff --git a/fs/ubifs/ubifs-media.h b/fs/ubifs/ubifs-media.h index 249124d9a801..0cbdc6b70a00 100644 --- a/fs/ubifs/ubifs-media.h +++ b/fs/ubifs/ubifs-media.h | |||
@@ -418,10 +418,13 @@ enum { | |||
418 | * | 418 | * |
419 | * UBIFS_FLG_BIGLPT: if "big" LPT model is used if set | 419 | * UBIFS_FLG_BIGLPT: if "big" LPT model is used if set |
420 | * UBIFS_FLG_SPACE_FIXUP: first-mount "fixup" of free space within LEBs needed | 420 | * UBIFS_FLG_SPACE_FIXUP: first-mount "fixup" of free space within LEBs needed |
421 | * UBIFS_FLG_DOUBLE_HASH: store a 32bit cookie in directory entry nodes to | ||
422 | * support 64bit cookies for lookups by hash | ||
421 | */ | 423 | */ |
422 | enum { | 424 | enum { |
423 | UBIFS_FLG_BIGLPT = 0x02, | 425 | UBIFS_FLG_BIGLPT = 0x02, |
424 | UBIFS_FLG_SPACE_FIXUP = 0x04, | 426 | UBIFS_FLG_SPACE_FIXUP = 0x04, |
427 | UBIFS_FLG_DOUBLE_HASH = 0x08, | ||
425 | }; | 428 | }; |
426 | 429 | ||
427 | /** | 430 | /** |
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index 9be71b6a4cd2..5089663c0d1b 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h | |||
@@ -1006,6 +1006,7 @@ struct ubifs_debug_info; | |||
1006 | * | 1006 | * |
1007 | * @big_lpt: flag that LPT is too big to write whole during commit | 1007 | * @big_lpt: flag that LPT is too big to write whole during commit |
1008 | * @space_fixup: flag indicating that free space in LEBs needs to be cleaned up | 1008 | * @space_fixup: flag indicating that free space in LEBs needs to be cleaned up |
1009 | * @double_hash: flag indicating that we can do lookups by hash | ||
1009 | * @no_chk_data_crc: do not check CRCs when reading data nodes (except during | 1010 | * @no_chk_data_crc: do not check CRCs when reading data nodes (except during |
1010 | * recovery) | 1011 | * recovery) |
1011 | * @bulk_read: enable bulk-reads | 1012 | * @bulk_read: enable bulk-reads |
@@ -1248,6 +1249,7 @@ struct ubifs_info { | |||
1248 | 1249 | ||
1249 | unsigned int big_lpt:1; | 1250 | unsigned int big_lpt:1; |
1250 | unsigned int space_fixup:1; | 1251 | unsigned int space_fixup:1; |
1252 | unsigned int double_hash:1; | ||
1251 | unsigned int no_chk_data_crc:1; | 1253 | unsigned int no_chk_data_crc:1; |
1252 | unsigned int bulk_read:1; | 1254 | unsigned int bulk_read:1; |
1253 | unsigned int default_compr:2; | 1255 | unsigned int default_compr:2; |