summaryrefslogtreecommitdiffstats
path: root/fs/ubifs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ubifs')
-rw-r--r--fs/ubifs/dir.c7
-rw-r--r--fs/ubifs/journal.c1
-rw-r--r--fs/ubifs/tnc.c90
-rw-r--r--fs/ubifs/ubifs-media.h5
-rw-r--r--fs/ubifs/ubifs.h2
5 files changed, 98 insertions, 7 deletions
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index 7d3bc3fb8831..7f01f3d2ac3b 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -253,7 +253,7 @@ static struct dentry *ubifs_lookup(struct inode *dir, struct dentry *dentry,
253 ubifs_assert(fname_len(&nm) == 0); 253 ubifs_assert(fname_len(&nm) == 0);
254 ubifs_assert(fname_name(&nm) == NULL); 254 ubifs_assert(fname_name(&nm) == NULL);
255 dent_key_init_hash(c, &key, dir->i_ino, nm.hash); 255 dent_key_init_hash(c, &key, dir->i_ino, nm.hash);
256 err = ubifs_tnc_lookup(c, &key, dent); 256 err = ubifs_tnc_lookup_dh(c, &key, dent, nm.minor_hash);
257 } else { 257 } else {
258 dent_key_init(c, &key, dir->i_ino, &nm); 258 dent_key_init(c, &key, dir->i_ino, &nm);
259 err = ubifs_tnc_lookup_nm(c, &key, dent, &nm); 259 err = ubifs_tnc_lookup_nm(c, &key, dent, &nm);
@@ -628,7 +628,10 @@ static int ubifs_readdir(struct file *file, struct dir_context *ctx)
628 if (encrypted) { 628 if (encrypted) {
629 fstr.len = fstr_real_len; 629 fstr.len = fstr_real_len;
630 630
631 err = fscrypt_fname_disk_to_usr(dir, key_hash_flash(c, &dent->key), 0, &nm.disk_name, &fstr); 631 err = fscrypt_fname_disk_to_usr(dir, key_hash_flash(c,
632 &dent->key),
633 le32_to_cpu(dent->cookie),
634 &nm.disk_name, &fstr);
632 if (err) 635 if (err)
633 goto out; 636 goto out;
634 } else { 637 } else {
diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c
index f2b989dbe25a..0698cccc6223 100644
--- a/fs/ubifs/journal.c
+++ b/fs/ubifs/journal.c
@@ -78,7 +78,6 @@ static inline void zero_ino_node_unused(struct ubifs_ino_node *ino)
78static inline void zero_dent_node_unused(struct ubifs_dent_node *dent) 78static inline void zero_dent_node_unused(struct ubifs_dent_node *dent)
79{ 79{
80 dent->padding1 = 0; 80 dent->padding1 = 0;
81 memset(dent->padding2, 0, 4);
82} 81}
83 82
84/** 83/**
diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c
index 0d751297873e..1bba4c8b5d3d 100644
--- a/fs/ubifs/tnc.c
+++ b/fs/ubifs/tnc.c
@@ -1783,7 +1783,7 @@ int ubifs_tnc_bulk_read(struct ubifs_info *c, struct bu_info *bu)
1783 * @node: the node is returned here 1783 * @node: the node is returned here
1784 * @nm: node name 1784 * @nm: node name
1785 * 1785 *
1786 * This function look up and reads a node which contains name hash in the key. 1786 * This function looks up and reads a node which contains name hash in the key.
1787 * Since the hash may have collisions, there may be many nodes with the same 1787 * Since the hash may have collisions, there may be many nodes with the same
1788 * key, so we have to sequentially look to all of them until the needed one is 1788 * key, so we have to sequentially look to all of them until the needed one is
1789 * found. This function returns zero in case of success, %-ENOENT if the node 1789 * found. This function returns zero in case of success, %-ENOENT if the node
@@ -1831,7 +1831,7 @@ out_unlock:
1831 * @node: the node is returned here 1831 * @node: the node is returned here
1832 * @nm: node name 1832 * @nm: node name
1833 * 1833 *
1834 * This function look up and reads a node which contains name hash in the key. 1834 * This function looks up and reads a node which contains name hash in the key.
1835 * Since the hash may have collisions, there may be many nodes with the same 1835 * Since the hash may have collisions, there may be many nodes with the same
1836 * key, so we have to sequentially look to all of them until the needed one is 1836 * key, so we have to sequentially look to all of them until the needed one is
1837 * found. This function returns zero in case of success, %-ENOENT if the node 1837 * found. This function returns zero in case of success, %-ENOENT if the node
@@ -1859,9 +1859,95 @@ int ubifs_tnc_lookup_nm(struct ubifs_info *c, const union ubifs_key *key,
1859 * Unluckily, there are hash collisions and we have to iterate over 1859 * Unluckily, there are hash collisions and we have to iterate over
1860 * them look at each direntry with colliding name hash sequentially. 1860 * them look at each direntry with colliding name hash sequentially.
1861 */ 1861 */
1862
1862 return do_lookup_nm(c, key, node, nm); 1863 return do_lookup_nm(c, key, node, nm);
1863} 1864}
1864 1865
1866static int do_lookup_dh(struct ubifs_info *c, const union ubifs_key *key,
1867 struct ubifs_dent_node *dent, uint32_t cookie)
1868{
1869 int n, err, type = key_type(c, key);
1870 struct ubifs_znode *znode;
1871 struct ubifs_zbranch *zbr;
1872 union ubifs_key *dkey, start_key;
1873
1874 ubifs_assert(is_hash_key(c, key));
1875
1876 lowest_dent_key(c, &start_key, key_inum(c, key));
1877
1878 mutex_lock(&c->tnc_mutex);
1879 err = ubifs_lookup_level0(c, &start_key, &znode, &n);
1880 if (unlikely(err < 0))
1881 goto out_unlock;
1882
1883 for (;;) {
1884 if (!err) {
1885 err = tnc_next(c, &znode, &n);
1886 if (err)
1887 goto out_unlock;
1888 }
1889
1890 zbr = &znode->zbranch[n];
1891 dkey = &zbr->key;
1892
1893 if (key_inum(c, dkey) != key_inum(c, key) ||
1894 key_type(c, dkey) != type) {
1895 err = -ENOENT;
1896 goto out_unlock;
1897 }
1898
1899 err = tnc_read_hashed_node(c, zbr, dent);
1900 if (err)
1901 goto out_unlock;
1902
1903 if (key_hash(c, key) == key_hash(c, dkey) &&
1904 le32_to_cpu(dent->cookie) == cookie)
1905 goto out_unlock;
1906 }
1907
1908out_unlock:
1909 mutex_unlock(&c->tnc_mutex);
1910 return err;
1911}
1912
1913/**
1914 * ubifs_tnc_lookup_dh - look up a "double hashed" node.
1915 * @c: UBIFS file-system description object
1916 * @key: node key to lookup
1917 * @node: the node is returned here
1918 * @cookie: node cookie for collision resolution
1919 *
1920 * This function looks up and reads a node which contains name hash in the key.
1921 * Since the hash may have collisions, there may be many nodes with the same
1922 * key, so we have to sequentially look to all of them until the needed one
1923 * with the same cookie value is found.
1924 * This function returns zero in case of success, %-ENOENT if the node
1925 * was not found, and a negative error code in case of failure.
1926 */
1927int ubifs_tnc_lookup_dh(struct ubifs_info *c, const union ubifs_key *key,
1928 void *node, uint32_t cookie)
1929{
1930 int err;
1931 const struct ubifs_dent_node *dent = node;
1932
1933 /*
1934 * We assume that in most of the cases there are no name collisions and
1935 * 'ubifs_tnc_lookup()' returns us the right direntry.
1936 */
1937 err = ubifs_tnc_lookup(c, key, node);
1938 if (err)
1939 return err;
1940
1941 if (le32_to_cpu(dent->cookie) == cookie)
1942 return 0;
1943
1944 /*
1945 * Unluckily, there are hash collisions and we have to iterate over
1946 * them look at each direntry with colliding name hash sequentially.
1947 */
1948 return do_lookup_dh(c, key, node, cookie);
1949}
1950
1865/** 1951/**
1866 * correct_parent_keys - correct parent znodes' keys. 1952 * correct_parent_keys - correct parent znodes' keys.
1867 * @c: UBIFS file-system description object 1953 * @c: UBIFS file-system description object
diff --git a/fs/ubifs/ubifs-media.h b/fs/ubifs/ubifs-media.h
index e46331dcca4c..249124d9a801 100644
--- a/fs/ubifs/ubifs-media.h
+++ b/fs/ubifs/ubifs-media.h
@@ -530,7 +530,8 @@ struct ubifs_ino_node {
530 * @padding1: reserved for future, zeroes 530 * @padding1: reserved for future, zeroes
531 * @type: type of the target inode (%UBIFS_ITYPE_REG, %UBIFS_ITYPE_DIR, etc) 531 * @type: type of the target inode (%UBIFS_ITYPE_REG, %UBIFS_ITYPE_DIR, etc)
532 * @nlen: name length 532 * @nlen: name length
533 * @padding2: reserved for future, zeroes 533 * @cookie: A 32bits random number, used to construct a 64bits
534 * identifier.
534 * @name: zero-terminated name 535 * @name: zero-terminated name
535 * 536 *
536 * Note, do not forget to amend 'zero_dent_node_unused()' function when 537 * Note, do not forget to amend 'zero_dent_node_unused()' function when
@@ -543,7 +544,7 @@ struct ubifs_dent_node {
543 __u8 padding1; 544 __u8 padding1;
544 __u8 type; 545 __u8 type;
545 __le16 nlen; 546 __le16 nlen;
546 __u8 padding2[4]; /* Watch 'zero_dent_node_unused()' if changing! */ 547 __le32 cookie;
547 __u8 name[]; 548 __u8 name[];
548} __packed; 549} __packed;
549 550
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index 8ccd19257a81..a80610758543 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -1571,6 +1571,8 @@ int ubifs_lookup_level0(struct ubifs_info *c, const union ubifs_key *key,
1571 struct ubifs_znode **zn, int *n); 1571 struct ubifs_znode **zn, int *n);
1572int ubifs_tnc_lookup_nm(struct ubifs_info *c, const union ubifs_key *key, 1572int ubifs_tnc_lookup_nm(struct ubifs_info *c, const union ubifs_key *key,
1573 void *node, const struct fscrypt_name *nm); 1573 void *node, const struct fscrypt_name *nm);
1574int ubifs_tnc_lookup_dh(struct ubifs_info *c, const union ubifs_key *key,
1575 void *node, uint32_t secondary_hash);
1574int ubifs_tnc_locate(struct ubifs_info *c, const union ubifs_key *key, 1576int ubifs_tnc_locate(struct ubifs_info *c, const union ubifs_key *key,
1575 void *node, int *lnum, int *offs); 1577 void *node, int *lnum, int *offs);
1576int ubifs_tnc_add(struct ubifs_info *c, const union ubifs_key *key, int lnum, 1578int ubifs_tnc_add(struct ubifs_info *c, const union ubifs_key *key, int lnum,