summaryrefslogtreecommitdiffstats
path: root/fs/ext4/namei.c
diff options
context:
space:
mode:
authorEric Biggers <ebiggers@google.com>2017-04-24 13:00:13 -0400
committerTheodore Ts'o <tytso@mit.edu>2017-05-04 11:44:40 -0400
commitd9b9f8d5a88cb7881d9f1c2b7e9de9a3fe1dc9e2 (patch)
treed66e591c28ae42327d843e95d67b505d4ea80cfd /fs/ext4/namei.c
parent1f73d491779047e81fff047c4613e84d5d76ddae (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.c81
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 */
1245static inline int ext4_match(struct ext4_filename *fname, 1244static 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;
1312return_result:
1313 return res;
1314} 1296}
1315 1297
1316static int is_dx_internal_node(struct inode *dir, ext4_lblk_t block, 1298static 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 }
1849return_result:
1850 return res;
1851} 1820}
1852 1821
1853int ext4_insert_dentry(struct inode *dir, 1822int ext4_insert_dentry(struct inode *dir,