diff options
author | Eric Biggers <ebiggers@google.com> | 2017-04-24 13:00:13 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2017-05-04 11:44:40 -0400 |
commit | d9b9f8d5a88cb7881d9f1c2b7e9de9a3fe1dc9e2 (patch) | |
tree | d66e591c28ae42327d843e95d67b505d4ea80cfd /fs/ext4/namei.c | |
parent | 1f73d491779047e81fff047c4613e84d5d76ddae (diff) |
ext4: clean up ext4_match() and callers
When ext4 encryption was originally merged, we were encrypting the
user-specified filename in ext4_match(), introducing a lot of additional
complexity into ext4_match() and its callers. This has since been
changed to encrypt the filename earlier, so we can remove the gunk
that's no longer needed. This more or less reverts ext4_search_dir()
and ext4_find_dest_de() to the way they were in the v4.0 kernel.
Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/namei.c')
-rw-r--r-- | fs/ext4/namei.c | 81 |
1 files changed, 25 insertions, 56 deletions
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index a87e49c31248..4d9b587507d9 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
@@ -1237,18 +1237,17 @@ static void dx_insert_block(struct dx_frame *frame, u32 hash, ext4_lblk_t block) | |||
1237 | } | 1237 | } |
1238 | 1238 | ||
1239 | /* | 1239 | /* |
1240 | * NOTE! unlike strncmp, ext4_match returns 1 for success, 0 for failure. | 1240 | * Test whether a directory entry matches the filename being searched for. |
1241 | * | 1241 | * |
1242 | * `len <= EXT4_NAME_LEN' is guaranteed by caller. | 1242 | * Return: %true if the directory entry matches, otherwise %false. |
1243 | * `de != NULL' is guaranteed by caller. | ||
1244 | */ | 1243 | */ |
1245 | static inline int ext4_match(struct ext4_filename *fname, | 1244 | static inline bool ext4_match(const struct ext4_filename *fname, |
1246 | struct ext4_dir_entry_2 *de) | 1245 | const struct ext4_dir_entry_2 *de) |
1247 | { | 1246 | { |
1248 | struct fscrypt_name f; | 1247 | struct fscrypt_name f; |
1249 | 1248 | ||
1250 | if (!de->inode) | 1249 | if (!de->inode) |
1251 | return 0; | 1250 | return false; |
1252 | 1251 | ||
1253 | f.usr_fname = fname->usr_fname; | 1252 | f.usr_fname = fname->usr_fname; |
1254 | f.disk_name = fname->disk_name; | 1253 | f.disk_name = fname->disk_name; |
@@ -1269,48 +1268,31 @@ int ext4_search_dir(struct buffer_head *bh, char *search_buf, int buf_size, | |||
1269 | struct ext4_dir_entry_2 * de; | 1268 | struct ext4_dir_entry_2 * de; |
1270 | char * dlimit; | 1269 | char * dlimit; |
1271 | int de_len; | 1270 | int de_len; |
1272 | int res; | ||
1273 | 1271 | ||
1274 | de = (struct ext4_dir_entry_2 *)search_buf; | 1272 | de = (struct ext4_dir_entry_2 *)search_buf; |
1275 | dlimit = search_buf + buf_size; | 1273 | dlimit = search_buf + buf_size; |
1276 | while ((char *) de < dlimit) { | 1274 | while ((char *) de < dlimit) { |
1277 | /* this code is executed quadratically often */ | 1275 | /* this code is executed quadratically often */ |
1278 | /* do minimal checking `by hand' */ | 1276 | /* do minimal checking `by hand' */ |
1279 | if ((char *) de + de->name_len <= dlimit) { | 1277 | if ((char *) de + de->name_len <= dlimit && |
1280 | res = ext4_match(fname, de); | 1278 | ext4_match(fname, de)) { |
1281 | if (res < 0) { | 1279 | /* found a match - just to be sure, do |
1282 | res = -1; | 1280 | * a full check */ |
1283 | goto return_result; | 1281 | if (ext4_check_dir_entry(dir, NULL, de, bh, bh->b_data, |
1284 | } | 1282 | bh->b_size, offset)) |
1285 | if (res > 0) { | 1283 | return -1; |
1286 | /* found a match - just to be sure, do | 1284 | *res_dir = de; |
1287 | * a full check */ | 1285 | return 1; |
1288 | if (ext4_check_dir_entry(dir, NULL, de, bh, | ||
1289 | bh->b_data, | ||
1290 | bh->b_size, offset)) { | ||
1291 | res = -1; | ||
1292 | goto return_result; | ||
1293 | } | ||
1294 | *res_dir = de; | ||
1295 | res = 1; | ||
1296 | goto return_result; | ||
1297 | } | ||
1298 | |||
1299 | } | 1286 | } |
1300 | /* prevent looping on a bad block */ | 1287 | /* prevent looping on a bad block */ |
1301 | de_len = ext4_rec_len_from_disk(de->rec_len, | 1288 | de_len = ext4_rec_len_from_disk(de->rec_len, |
1302 | dir->i_sb->s_blocksize); | 1289 | dir->i_sb->s_blocksize); |
1303 | if (de_len <= 0) { | 1290 | if (de_len <= 0) |
1304 | res = -1; | 1291 | return -1; |
1305 | goto return_result; | ||
1306 | } | ||
1307 | offset += de_len; | 1292 | offset += de_len; |
1308 | de = (struct ext4_dir_entry_2 *) ((char *) de + de_len); | 1293 | de = (struct ext4_dir_entry_2 *) ((char *) de + de_len); |
1309 | } | 1294 | } |
1310 | 1295 | return 0; | |
1311 | res = 0; | ||
1312 | return_result: | ||
1313 | return res; | ||
1314 | } | 1296 | } |
1315 | 1297 | ||
1316 | static int is_dx_internal_node(struct inode *dir, ext4_lblk_t block, | 1298 | static int is_dx_internal_node(struct inode *dir, ext4_lblk_t block, |
@@ -1814,24 +1796,15 @@ int ext4_find_dest_de(struct inode *dir, struct inode *inode, | |||
1814 | int nlen, rlen; | 1796 | int nlen, rlen; |
1815 | unsigned int offset = 0; | 1797 | unsigned int offset = 0; |
1816 | char *top; | 1798 | char *top; |
1817 | int res; | ||
1818 | 1799 | ||
1819 | de = (struct ext4_dir_entry_2 *)buf; | 1800 | de = (struct ext4_dir_entry_2 *)buf; |
1820 | top = buf + buf_size - reclen; | 1801 | top = buf + buf_size - reclen; |
1821 | while ((char *) de <= top) { | 1802 | while ((char *) de <= top) { |
1822 | if (ext4_check_dir_entry(dir, NULL, de, bh, | 1803 | if (ext4_check_dir_entry(dir, NULL, de, bh, |
1823 | buf, buf_size, offset)) { | 1804 | buf, buf_size, offset)) |
1824 | res = -EFSCORRUPTED; | 1805 | return -EFSCORRUPTED; |
1825 | goto return_result; | 1806 | if (ext4_match(fname, de)) |
1826 | } | 1807 | return -EEXIST; |
1827 | /* Provide crypto context and crypto buffer to ext4 match */ | ||
1828 | res = ext4_match(fname, de); | ||
1829 | if (res < 0) | ||
1830 | goto return_result; | ||
1831 | if (res > 0) { | ||
1832 | res = -EEXIST; | ||
1833 | goto return_result; | ||
1834 | } | ||
1835 | nlen = EXT4_DIR_REC_LEN(de->name_len); | 1808 | nlen = EXT4_DIR_REC_LEN(de->name_len); |
1836 | rlen = ext4_rec_len_from_disk(de->rec_len, buf_size); | 1809 | rlen = ext4_rec_len_from_disk(de->rec_len, buf_size); |
1837 | if ((de->inode ? rlen - nlen : rlen) >= reclen) | 1810 | if ((de->inode ? rlen - nlen : rlen) >= reclen) |
@@ -1839,15 +1812,11 @@ int ext4_find_dest_de(struct inode *dir, struct inode *inode, | |||
1839 | de = (struct ext4_dir_entry_2 *)((char *)de + rlen); | 1812 | de = (struct ext4_dir_entry_2 *)((char *)de + rlen); |
1840 | offset += rlen; | 1813 | offset += rlen; |
1841 | } | 1814 | } |
1842 | |||
1843 | if ((char *) de > top) | 1815 | if ((char *) de > top) |
1844 | res = -ENOSPC; | 1816 | return -ENOSPC; |
1845 | else { | 1817 | |
1846 | *dest_de = de; | 1818 | *dest_de = de; |
1847 | res = 0; | 1819 | return 0; |
1848 | } | ||
1849 | return_result: | ||
1850 | return res; | ||
1851 | } | 1820 | } |
1852 | 1821 | ||
1853 | int ext4_insert_dentry(struct inode *dir, | 1822 | int ext4_insert_dentry(struct inode *dir, |