Skip to content

Commit d63d61c

Browse files
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>
1 parent cc41a53 commit d63d61c

File tree

5 files changed

+21
-3
lines changed

5 files changed

+21
-3
lines changed

fs/ubifs/journal.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,14 @@ static void mark_inode_clean(struct ubifs_info *c, struct ubifs_inode *ui)
501501
ui->dirty = 0;
502502
}
503503

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+
504512
/**
505513
* ubifs_jnl_update - update inode.
506514
* @c: UBIFS file-system description object
@@ -589,7 +597,7 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir,
589597
dent->nlen = cpu_to_le16(fname_len(nm));
590598
memcpy(dent->name, fname_name(nm), fname_len(nm));
591599
dent->name[fname_len(nm)] = '\0';
592-
dent->cookie = prandom_u32();
600+
set_dent_cookie(c, dent);
593601

594602
zero_dent_node_unused(dent);
595603
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,
11251133
dent->nlen = cpu_to_le16(fname_len(new_nm));
11261134
memcpy(dent->name, fname_name(new_nm), fname_len(new_nm));
11271135
dent->name[fname_len(new_nm)] = '\0';
1128-
dent->cookie = prandom_u32();
1136+
set_dent_cookie(c, dent);
11291137
zero_dent_node_unused(dent);
11301138
ubifs_prep_grp_node(c, dent, dlen1, 0);
11311139

@@ -1144,7 +1152,7 @@ int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir,
11441152
dent2->nlen = cpu_to_le16(fname_len(old_nm));
11451153
memcpy(dent2->name, fname_name(old_nm), fname_len(old_nm));
11461154
dent2->name[fname_len(old_nm)] = '\0';
1147-
dent2->cookie = prandom_u32();
1155+
set_dent_cookie(c, dent2);
11481156
zero_dent_node_unused(dent2);
11491157
ubifs_prep_grp_node(c, dent2, dlen2, 0);
11501158

fs/ubifs/sb.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ static int create_default_filesystem(struct ubifs_info *c)
163163
tmp64 = (long long)max_buds * c->leb_size;
164164
if (big_lpt)
165165
sup_flags |= UBIFS_FLG_BIGLPT;
166+
sup_flags |= UBIFS_FLG_DOUBLE_HASH;
166167

167168
sup->ch.node_type = UBIFS_SB_NODE;
168169
sup->key_hash = UBIFS_KEY_HASH_R5;
@@ -620,6 +621,7 @@ int ubifs_read_superblock(struct ubifs_info *c)
620621
memcpy(&c->uuid, &sup->uuid, 16);
621622
c->big_lpt = !!(sup_flags & UBIFS_FLG_BIGLPT);
622623
c->space_fixup = !!(sup_flags & UBIFS_FLG_SPACE_FIXUP);
624+
c->double_hash = !!(sup_flags & UBIFS_FLG_DOUBLE_HASH);
623625

624626
/* Automatically increase file system size to the maximum size */
625627
c->old_leb_cnt = c->leb_cnt;

fs/ubifs/tnc.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1930,6 +1930,9 @@ int ubifs_tnc_lookup_dh(struct ubifs_info *c, const union ubifs_key *key,
19301930
int err;
19311931
const struct ubifs_dent_node *dent = node;
19321932

1933+
if (!c->double_hash)
1934+
return -EOPNOTSUPP;
1935+
19331936
/*
19341937
* We assume that in most of the cases there are no name collisions and
19351938
* 'ubifs_tnc_lookup()' returns us the right direntry.

fs/ubifs/ubifs-media.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,10 +418,13 @@ enum {
418418
*
419419
* UBIFS_FLG_BIGLPT: if "big" LPT model is used if set
420420
* 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
421423
*/
422424
enum {
423425
UBIFS_FLG_BIGLPT = 0x02,
424426
UBIFS_FLG_SPACE_FIXUP = 0x04,
427+
UBIFS_FLG_DOUBLE_HASH = 0x08,
425428
};
426429

427430
/**

fs/ubifs/ubifs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,6 +1006,7 @@ struct ubifs_debug_info;
10061006
*
10071007
* @big_lpt: flag that LPT is too big to write whole during commit
10081008
* @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
10091010
* @no_chk_data_crc: do not check CRCs when reading data nodes (except during
10101011
* recovery)
10111012
* @bulk_read: enable bulk-reads
@@ -1248,6 +1249,7 @@ struct ubifs_info {
12481249

12491250
unsigned int big_lpt:1;
12501251
unsigned int space_fixup:1;
1252+
unsigned int double_hash:1;
12511253
unsigned int no_chk_data_crc:1;
12521254
unsigned int bulk_read:1;
12531255
unsigned int default_compr:2;

0 commit comments

Comments
 (0)