| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* * This file is part of UBIFS. |
|---|
| 2 | 3 | * |
|---|
| 3 | 4 | * Copyright (C) 2006-2008 Nokia Corporation. |
|---|
| 4 | 5 | * Copyright (C) 2006, 2007 University of Szeged, Hungary |
|---|
| 5 | | - * |
|---|
| 6 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 7 | | - * under the terms of the GNU General Public License version 2 as published by |
|---|
| 8 | | - * the Free Software Foundation. |
|---|
| 9 | | - * |
|---|
| 10 | | - * This program is distributed in the hope that it will be useful, but WITHOUT |
|---|
| 11 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|---|
| 12 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
|---|
| 13 | | - * more details. |
|---|
| 14 | | - * |
|---|
| 15 | | - * You should have received a copy of the GNU General Public License along with |
|---|
| 16 | | - * this program; if not, write to the Free Software Foundation, Inc., 51 |
|---|
| 17 | | - * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
|---|
| 18 | 6 | * |
|---|
| 19 | 7 | * Authors: Artem Bityutskiy (Битюцкий Артём) |
|---|
| 20 | 8 | * Adrian Hunter |
|---|
| .. | .. |
|---|
| 93 | 81 | struct ubifs_inode *ui; |
|---|
| 94 | 82 | bool encrypted = false; |
|---|
| 95 | 83 | |
|---|
| 96 | | - if (ubifs_crypt_is_encrypted(dir)) { |
|---|
| 97 | | - err = fscrypt_get_encryption_info(dir); |
|---|
| 98 | | - if (err) { |
|---|
| 99 | | - ubifs_err(c, "fscrypt_get_encryption_info failed: %i", err); |
|---|
| 100 | | - return ERR_PTR(err); |
|---|
| 101 | | - } |
|---|
| 102 | | - |
|---|
| 103 | | - if (!fscrypt_has_encryption_key(dir)) |
|---|
| 104 | | - return ERR_PTR(-EPERM); |
|---|
| 105 | | - |
|---|
| 106 | | - encrypted = true; |
|---|
| 107 | | - } |
|---|
| 108 | | - |
|---|
| 109 | 84 | inode = new_inode(c->vfs_sb); |
|---|
| 110 | 85 | ui = ubifs_inode(inode); |
|---|
| 111 | 86 | if (!inode) |
|---|
| .. | .. |
|---|
| 123 | 98 | inode->i_mtime = inode->i_atime = inode->i_ctime = |
|---|
| 124 | 99 | current_time(inode); |
|---|
| 125 | 100 | inode->i_mapping->nrpages = 0; |
|---|
| 101 | + |
|---|
| 102 | + err = fscrypt_prepare_new_inode(dir, inode, &encrypted); |
|---|
| 103 | + if (err) { |
|---|
| 104 | + ubifs_err(c, "fscrypt_prepare_new_inode failed: %i", err); |
|---|
| 105 | + goto out_iput; |
|---|
| 106 | + } |
|---|
| 126 | 107 | |
|---|
| 127 | 108 | switch (mode & S_IFMT) { |
|---|
| 128 | 109 | case S_IFREG: |
|---|
| .. | .. |
|---|
| 143 | 124 | case S_IFBLK: |
|---|
| 144 | 125 | case S_IFCHR: |
|---|
| 145 | 126 | inode->i_op = &ubifs_file_inode_operations; |
|---|
| 146 | | - encrypted = false; |
|---|
| 147 | 127 | break; |
|---|
| 148 | 128 | default: |
|---|
| 149 | 129 | BUG(); |
|---|
| .. | .. |
|---|
| 163 | 143 | if (c->highest_inum >= INUM_WATERMARK) { |
|---|
| 164 | 144 | spin_unlock(&c->cnt_lock); |
|---|
| 165 | 145 | ubifs_err(c, "out of inode numbers"); |
|---|
| 166 | | - make_bad_inode(inode); |
|---|
| 167 | | - iput(inode); |
|---|
| 168 | | - return ERR_PTR(-EINVAL); |
|---|
| 146 | + err = -EINVAL; |
|---|
| 147 | + goto out_iput; |
|---|
| 169 | 148 | } |
|---|
| 170 | 149 | ubifs_warn(c, "running out of inode numbers (current %lu, max %u)", |
|---|
| 171 | 150 | (unsigned long)c->highest_inum, INUM_WATERMARK); |
|---|
| .. | .. |
|---|
| 183 | 162 | spin_unlock(&c->cnt_lock); |
|---|
| 184 | 163 | |
|---|
| 185 | 164 | if (encrypted) { |
|---|
| 186 | | - err = fscrypt_inherit_context(dir, inode, &encrypted, true); |
|---|
| 165 | + err = fscrypt_set_context(inode, NULL); |
|---|
| 187 | 166 | if (err) { |
|---|
| 188 | | - ubifs_err(c, "fscrypt_inherit_context failed: %i", err); |
|---|
| 189 | | - make_bad_inode(inode); |
|---|
| 190 | | - iput(inode); |
|---|
| 191 | | - return ERR_PTR(err); |
|---|
| 167 | + ubifs_err(c, "fscrypt_set_context failed: %i", err); |
|---|
| 168 | + goto out_iput; |
|---|
| 192 | 169 | } |
|---|
| 193 | 170 | } |
|---|
| 194 | 171 | |
|---|
| 195 | 172 | return inode; |
|---|
| 173 | + |
|---|
| 174 | +out_iput: |
|---|
| 175 | + make_bad_inode(inode); |
|---|
| 176 | + iput(inode); |
|---|
| 177 | + return ERR_PTR(err); |
|---|
| 196 | 178 | } |
|---|
| 197 | 179 | |
|---|
| 198 | 180 | static int dbg_check_name(const struct ubifs_info *c, |
|---|
| .. | .. |
|---|
| 208 | 190 | return 0; |
|---|
| 209 | 191 | } |
|---|
| 210 | 192 | |
|---|
| 211 | | -static void ubifs_set_d_ops(struct inode *dir, struct dentry *dentry); |
|---|
| 212 | 193 | static struct dentry *ubifs_lookup(struct inode *dir, struct dentry *dentry, |
|---|
| 213 | 194 | unsigned int flags) |
|---|
| 214 | 195 | { |
|---|
| .. | .. |
|---|
| 222 | 203 | dbg_gen("'%pd' in dir ino %lu", dentry, dir->i_ino); |
|---|
| 223 | 204 | |
|---|
| 224 | 205 | err = fscrypt_prepare_lookup(dir, dentry, &nm); |
|---|
| 225 | | - ubifs_set_d_ops(dir, dentry); |
|---|
| 206 | + generic_set_encrypted_ci_d_ops(dentry); |
|---|
| 226 | 207 | if (err == -ENOENT) |
|---|
| 227 | 208 | return d_splice_alias(NULL, dentry); |
|---|
| 228 | 209 | if (err) |
|---|
| .. | .. |
|---|
| 275 | 256 | goto done; |
|---|
| 276 | 257 | } |
|---|
| 277 | 258 | |
|---|
| 278 | | - if (ubifs_crypt_is_encrypted(dir) && |
|---|
| 259 | + if (IS_ENCRYPTED(dir) && |
|---|
| 279 | 260 | (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) && |
|---|
| 280 | 261 | !fscrypt_has_permitted_context(dir, inode)) { |
|---|
| 281 | 262 | ubifs_warn(c, "Inconsistent encryption contexts: %lu/%lu", |
|---|
| .. | .. |
|---|
| 373 | 354 | { |
|---|
| 374 | 355 | struct inode *inode; |
|---|
| 375 | 356 | struct ubifs_info *c = dir->i_sb->s_fs_info; |
|---|
| 376 | | - struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1}; |
|---|
| 357 | + struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1, |
|---|
| 358 | + .dirtied_ino = 1}; |
|---|
| 377 | 359 | struct ubifs_budget_req ino_req = { .dirtied_ino = 1 }; |
|---|
| 378 | 360 | struct ubifs_inode *ui, *dir_ui = ubifs_inode(dir); |
|---|
| 379 | 361 | int err, instantiated = 0; |
|---|
| 380 | 362 | struct fscrypt_name nm; |
|---|
| 381 | 363 | |
|---|
| 382 | 364 | /* |
|---|
| 383 | | - * Budget request settings: new dirty inode, new direntry, |
|---|
| 384 | | - * budget for dirtied inode will be released via writeback. |
|---|
| 365 | + * Budget request settings: new inode, new direntry, changing the |
|---|
| 366 | + * parent directory inode. |
|---|
| 367 | + * Allocate budget separately for new dirtied inode, the budget will |
|---|
| 368 | + * be released via writeback. |
|---|
| 385 | 369 | */ |
|---|
| 386 | 370 | |
|---|
| 387 | 371 | dbg_gen("dent '%pd', mode %#hx in dir ino %lu", |
|---|
| .. | .. |
|---|
| 442 | 426 | mutex_unlock(&dir_ui->ui_mutex); |
|---|
| 443 | 427 | |
|---|
| 444 | 428 | ubifs_release_budget(c, &req); |
|---|
| 429 | + fscrypt_free_filename(&nm); |
|---|
| 445 | 430 | |
|---|
| 446 | 431 | return 0; |
|---|
| 447 | 432 | |
|---|
| .. | .. |
|---|
| 451 | 436 | make_bad_inode(inode); |
|---|
| 452 | 437 | if (!instantiated) |
|---|
| 453 | 438 | iput(inode); |
|---|
| 439 | + else if (whiteout) |
|---|
| 440 | + iput(*whiteout); |
|---|
| 454 | 441 | out_budg: |
|---|
| 455 | 442 | ubifs_release_budget(c, &req); |
|---|
| 456 | 443 | if (!instantiated) |
|---|
| .. | .. |
|---|
| 522 | 509 | struct ubifs_dent_node *dent; |
|---|
| 523 | 510 | struct inode *dir = file_inode(file); |
|---|
| 524 | 511 | struct ubifs_info *c = dir->i_sb->s_fs_info; |
|---|
| 525 | | - bool encrypted = ubifs_crypt_is_encrypted(dir); |
|---|
| 512 | + bool encrypted = IS_ENCRYPTED(dir); |
|---|
| 526 | 513 | |
|---|
| 527 | 514 | dbg_gen("dir ino %lu, f_pos %#llx", dir->i_ino, ctx->pos); |
|---|
| 528 | 515 | |
|---|
| .. | .. |
|---|
| 534 | 521 | return 0; |
|---|
| 535 | 522 | |
|---|
| 536 | 523 | if (encrypted) { |
|---|
| 537 | | - err = fscrypt_get_encryption_info(dir); |
|---|
| 524 | + err = fscrypt_prepare_readdir(dir); |
|---|
| 538 | 525 | if (err) |
|---|
| 539 | 526 | return err; |
|---|
| 540 | 527 | |
|---|
| 541 | | - err = fscrypt_fname_alloc_buffer(dir, UBIFS_MAX_NLEN, &fstr); |
|---|
| 528 | + err = fscrypt_fname_alloc_buffer(UBIFS_MAX_NLEN, &fstr); |
|---|
| 542 | 529 | if (err) |
|---|
| 543 | 530 | return err; |
|---|
| 544 | 531 | |
|---|
| .. | .. |
|---|
| 801 | 788 | dentry, inode->i_ino, |
|---|
| 802 | 789 | inode->i_nlink, dir->i_ino); |
|---|
| 803 | 790 | |
|---|
| 804 | | - if (ubifs_crypt_is_encrypted(dir)) { |
|---|
| 805 | | - err = fscrypt_get_encryption_info(dir); |
|---|
| 806 | | - if (err && err != -ENOKEY) |
|---|
| 807 | | - return err; |
|---|
| 808 | | - } |
|---|
| 809 | | - |
|---|
| 810 | 791 | err = fscrypt_setup_filename(dir, &dentry->d_name, 1, &nm); |
|---|
| 792 | + if (err) |
|---|
| 793 | + return err; |
|---|
| 794 | + |
|---|
| 795 | + err = ubifs_purge_xattrs(inode); |
|---|
| 811 | 796 | if (err) |
|---|
| 812 | 797 | return err; |
|---|
| 813 | 798 | |
|---|
| .. | .. |
|---|
| 911 | 896 | if (err) |
|---|
| 912 | 897 | return err; |
|---|
| 913 | 898 | |
|---|
| 914 | | - if (ubifs_crypt_is_encrypted(dir)) { |
|---|
| 915 | | - err = fscrypt_get_encryption_info(dir); |
|---|
| 916 | | - if (err && err != -ENOKEY) |
|---|
| 917 | | - return err; |
|---|
| 918 | | - } |
|---|
| 919 | | - |
|---|
| 920 | 899 | err = fscrypt_setup_filename(dir, &dentry->d_name, 1, &nm); |
|---|
| 900 | + if (err) |
|---|
| 901 | + return err; |
|---|
| 902 | + |
|---|
| 903 | + err = ubifs_purge_xattrs(inode); |
|---|
| 921 | 904 | if (err) |
|---|
| 922 | 905 | return err; |
|---|
| 923 | 906 | |
|---|
| .. | .. |
|---|
| 971 | 954 | struct ubifs_inode *dir_ui = ubifs_inode(dir); |
|---|
| 972 | 955 | struct ubifs_info *c = dir->i_sb->s_fs_info; |
|---|
| 973 | 956 | int err, sz_change; |
|---|
| 974 | | - struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1 }; |
|---|
| 957 | + struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1, |
|---|
| 958 | + .dirtied_ino = 1}; |
|---|
| 975 | 959 | struct fscrypt_name nm; |
|---|
| 976 | 960 | |
|---|
| 977 | 961 | /* |
|---|
| .. | .. |
|---|
| 1135 | 1119 | int err, sz_change, len = strlen(symname); |
|---|
| 1136 | 1120 | struct fscrypt_str disk_link; |
|---|
| 1137 | 1121 | struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1, |
|---|
| 1138 | | - .new_ino_d = ALIGN(len, 8), |
|---|
| 1139 | 1122 | .dirtied_ino = 1 }; |
|---|
| 1140 | 1123 | struct fscrypt_name nm; |
|---|
| 1141 | 1124 | |
|---|
| .. | .. |
|---|
| 1151 | 1134 | * Budget request settings: new inode, new direntry and changing parent |
|---|
| 1152 | 1135 | * directory inode. |
|---|
| 1153 | 1136 | */ |
|---|
| 1137 | + req.new_ino_d = ALIGN(disk_link.len - 1, 8); |
|---|
| 1154 | 1138 | err = ubifs_budget_space(c, &req); |
|---|
| 1155 | 1139 | if (err) |
|---|
| 1156 | 1140 | return err; |
|---|
| .. | .. |
|---|
| 1287 | 1271 | struct ubifs_budget_req ino_req = { .dirtied_ino = 1, |
|---|
| 1288 | 1272 | .dirtied_ino_d = ALIGN(old_inode_ui->data_len, 8) }; |
|---|
| 1289 | 1273 | struct timespec64 time; |
|---|
| 1290 | | - unsigned int uninitialized_var(saved_nlink); |
|---|
| 1274 | + unsigned int saved_nlink; |
|---|
| 1291 | 1275 | struct fscrypt_name old_nm, new_nm; |
|---|
| 1292 | 1276 | |
|---|
| 1293 | 1277 | /* |
|---|
| .. | .. |
|---|
| 1303 | 1287 | old_dentry, old_inode->i_ino, old_dir->i_ino, |
|---|
| 1304 | 1288 | new_dentry, new_dir->i_ino, flags); |
|---|
| 1305 | 1289 | |
|---|
| 1306 | | - if (unlink) |
|---|
| 1290 | + if (unlink) { |
|---|
| 1307 | 1291 | ubifs_assert(c, inode_is_locked(new_inode)); |
|---|
| 1292 | + |
|---|
| 1293 | + /* Budget for old inode's data when its nlink > 1. */ |
|---|
| 1294 | + req.dirtied_ino_d = ALIGN(ubifs_inode(new_inode)->data_len, 8); |
|---|
| 1295 | + err = ubifs_purge_xattrs(new_inode); |
|---|
| 1296 | + if (err) |
|---|
| 1297 | + return err; |
|---|
| 1298 | + } |
|---|
| 1308 | 1299 | |
|---|
| 1309 | 1300 | if (unlink && is_dir) { |
|---|
| 1310 | 1301 | err = ubifs_check_dir_empty(new_inode); |
|---|
| .. | .. |
|---|
| 1341 | 1332 | |
|---|
| 1342 | 1333 | if (flags & RENAME_WHITEOUT) { |
|---|
| 1343 | 1334 | union ubifs_dev_desc *dev = NULL; |
|---|
| 1335 | + struct ubifs_budget_req wht_req; |
|---|
| 1344 | 1336 | |
|---|
| 1345 | 1337 | dev = kmalloc(sizeof(union ubifs_dev_desc), GFP_NOFS); |
|---|
| 1346 | 1338 | if (!dev) { |
|---|
| .. | .. |
|---|
| 1362 | 1354 | whiteout_ui->data = dev; |
|---|
| 1363 | 1355 | whiteout_ui->data_len = ubifs_encode_dev(dev, MKDEV(0, 0)); |
|---|
| 1364 | 1356 | ubifs_assert(c, !whiteout_ui->dirty); |
|---|
| 1357 | + |
|---|
| 1358 | + memset(&wht_req, 0, sizeof(struct ubifs_budget_req)); |
|---|
| 1359 | + wht_req.dirtied_ino = 1; |
|---|
| 1360 | + wht_req.dirtied_ino_d = ALIGN(whiteout_ui->data_len, 8); |
|---|
| 1361 | + /* |
|---|
| 1362 | + * To avoid deadlock between space budget (holds ui_mutex and |
|---|
| 1363 | + * waits wb work) and writeback work(waits ui_mutex), do space |
|---|
| 1364 | + * budget before ubifs inodes locked. |
|---|
| 1365 | + */ |
|---|
| 1366 | + err = ubifs_budget_space(c, &wht_req); |
|---|
| 1367 | + if (err) { |
|---|
| 1368 | + iput(whiteout); |
|---|
| 1369 | + goto out_release; |
|---|
| 1370 | + } |
|---|
| 1371 | + |
|---|
| 1372 | + /* Add the old_dentry size to the old_dir size. */ |
|---|
| 1373 | + old_sz -= CALC_DENT_SIZE(fname_len(&old_nm)); |
|---|
| 1365 | 1374 | } |
|---|
| 1366 | 1375 | |
|---|
| 1367 | 1376 | lock_4_inodes(old_dir, new_dir, new_inode, whiteout); |
|---|
| .. | .. |
|---|
| 1436 | 1445 | } |
|---|
| 1437 | 1446 | |
|---|
| 1438 | 1447 | if (whiteout) { |
|---|
| 1439 | | - struct ubifs_budget_req wht_req = { .dirtied_ino = 1, |
|---|
| 1440 | | - .dirtied_ino_d = \ |
|---|
| 1441 | | - ALIGN(ubifs_inode(whiteout)->data_len, 8) }; |
|---|
| 1442 | | - |
|---|
| 1443 | | - err = ubifs_budget_space(c, &wht_req); |
|---|
| 1444 | | - if (err) { |
|---|
| 1445 | | - kfree(whiteout_ui->data); |
|---|
| 1446 | | - whiteout_ui->data_len = 0; |
|---|
| 1447 | | - iput(whiteout); |
|---|
| 1448 | | - goto out_release; |
|---|
| 1449 | | - } |
|---|
| 1450 | | - |
|---|
| 1451 | 1448 | inc_nlink(whiteout); |
|---|
| 1452 | 1449 | mark_inode_dirty(whiteout); |
|---|
| 1453 | 1450 | |
|---|
| .. | .. |
|---|
| 1537 | 1534 | return err; |
|---|
| 1538 | 1535 | } |
|---|
| 1539 | 1536 | |
|---|
| 1537 | + err = ubifs_budget_space(c, &req); |
|---|
| 1538 | + if (err) |
|---|
| 1539 | + goto out; |
|---|
| 1540 | + |
|---|
| 1540 | 1541 | lock_4_inodes(old_dir, new_dir, NULL, NULL); |
|---|
| 1541 | 1542 | |
|---|
| 1542 | 1543 | time = current_time(old_dir); |
|---|
| .. | .. |
|---|
| 1562 | 1563 | unlock_4_inodes(old_dir, new_dir, NULL, NULL); |
|---|
| 1563 | 1564 | ubifs_release_budget(c, &req); |
|---|
| 1564 | 1565 | |
|---|
| 1566 | +out: |
|---|
| 1565 | 1567 | fscrypt_free_filename(&fst_nm); |
|---|
| 1566 | 1568 | fscrypt_free_filename(&snd_nm); |
|---|
| 1567 | 1569 | return err; |
|---|
| .. | .. |
|---|
| 1645 | 1647 | return 0; |
|---|
| 1646 | 1648 | } |
|---|
| 1647 | 1649 | |
|---|
| 1648 | | -static int ubifs_dir_open(struct inode *dir, struct file *file) |
|---|
| 1649 | | -{ |
|---|
| 1650 | | - if (ubifs_crypt_is_encrypted(dir)) |
|---|
| 1651 | | - return fscrypt_get_encryption_info(dir) ? -EACCES : 0; |
|---|
| 1652 | | - |
|---|
| 1653 | | - return 0; |
|---|
| 1654 | | -} |
|---|
| 1655 | | - |
|---|
| 1656 | 1650 | const struct inode_operations ubifs_dir_inode_operations = { |
|---|
| 1657 | 1651 | .lookup = ubifs_lookup, |
|---|
| 1658 | 1652 | .create = ubifs_create, |
|---|
| .. | .. |
|---|
| 1668 | 1662 | #ifdef CONFIG_UBIFS_FS_XATTR |
|---|
| 1669 | 1663 | .listxattr = ubifs_listxattr, |
|---|
| 1670 | 1664 | #endif |
|---|
| 1671 | | -#ifdef CONFIG_UBIFS_ATIME_SUPPORT |
|---|
| 1672 | 1665 | .update_time = ubifs_update_time, |
|---|
| 1673 | | -#endif |
|---|
| 1674 | 1666 | .tmpfile = ubifs_tmpfile, |
|---|
| 1675 | 1667 | }; |
|---|
| 1676 | 1668 | |
|---|
| .. | .. |
|---|
| 1681 | 1673 | .iterate_shared = ubifs_readdir, |
|---|
| 1682 | 1674 | .fsync = ubifs_fsync, |
|---|
| 1683 | 1675 | .unlocked_ioctl = ubifs_ioctl, |
|---|
| 1684 | | - .open = ubifs_dir_open, |
|---|
| 1685 | 1676 | #ifdef CONFIG_COMPAT |
|---|
| 1686 | 1677 | .compat_ioctl = ubifs_compat_ioctl, |
|---|
| 1687 | 1678 | #endif |
|---|
| 1688 | 1679 | }; |
|---|
| 1689 | | - |
|---|
| 1690 | | -#ifdef CONFIG_FS_ENCRYPTION |
|---|
| 1691 | | -static const struct dentry_operations ubifs_encrypted_dentry_ops = { |
|---|
| 1692 | | - .d_revalidate = fscrypt_d_revalidate, |
|---|
| 1693 | | -}; |
|---|
| 1694 | | -#endif |
|---|
| 1695 | | - |
|---|
| 1696 | | -static void ubifs_set_d_ops(struct inode *dir, struct dentry *dentry) |
|---|
| 1697 | | -{ |
|---|
| 1698 | | -#ifdef CONFIG_FS_ENCRYPTION |
|---|
| 1699 | | - if (dentry->d_flags & DCACHE_ENCRYPTED_NAME) { |
|---|
| 1700 | | - d_set_d_op(dentry, &ubifs_encrypted_dentry_ops); |
|---|
| 1701 | | - return; |
|---|
| 1702 | | - } |
|---|
| 1703 | | -#endif |
|---|
| 1704 | | -} |
|---|