diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-12 18:16:31 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-12 18:16:31 -0400 |
commit | d7a02fa0a8f9ec1b81d57628ca9834563208ef33 (patch) | |
tree | b2f43dbee43b7abd7329b8745e4f0a9659ee6ffe /fs/ubifs | |
parent | 4dbf09fea60d158e60a30c419e0cfa1ea138dd57 (diff) | |
parent | 04d37e5a8b1fad2d625727af3d738c6fd9491720 (diff) |
Merge tag 'upstream-5.2-rc1' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/rw/ubifs
Pull UBI/UBIFS updates from Richard Weinberger:
- fscrypt framework usage updates
- One huge fix for xattr unlink
- Cleanup of fscrypt ifdefs
- Fix for our new UBIFS auth feature
* tag 'upstream-5.2-rc1' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/rw/ubifs:
ubi: wl: Fix uninitialized variable
ubifs: Drop unnecessary setting of zbr->znode
ubifs: Remove ifdefs around CONFIG_UBIFS_ATIME_SUPPORT
ubifs: Remove #ifdef around CONFIG_FS_ENCRYPTION
ubifs: Limit number of xattrs per inode
ubifs: orphan: Handle xattrs like files
ubifs: journal: Handle xattrs like files
ubifs: find.c: replace swap function with built-in one
ubifs: Do not skip hash checking in data nodes
ubifs: work around high stack usage with clang
ubifs: remove unused function __ubifs_shash_final
ubifs: remove unnecessary #ifdef around fscrypt_ioctl_get_policy()
ubifs: remove unnecessary calls to set up directory key
Diffstat (limited to 'fs/ubifs')
-rw-r--r-- | fs/ubifs/auth.c | 33 | ||||
-rw-r--r-- | fs/ubifs/debug.c | 1 | ||||
-rw-r--r-- | fs/ubifs/dir.c | 29 | ||||
-rw-r--r-- | fs/ubifs/file.c | 16 | ||||
-rw-r--r-- | fs/ubifs/find.c | 9 | ||||
-rw-r--r-- | fs/ubifs/ioctl.c | 11 | ||||
-rw-r--r-- | fs/ubifs/journal.c | 72 | ||||
-rw-r--r-- | fs/ubifs/misc.h | 8 | ||||
-rw-r--r-- | fs/ubifs/orphan.c | 208 | ||||
-rw-r--r-- | fs/ubifs/sb.c | 7 | ||||
-rw-r--r-- | fs/ubifs/super.c | 22 | ||||
-rw-r--r-- | fs/ubifs/tnc.c | 15 | ||||
-rw-r--r-- | fs/ubifs/ubifs.h | 6 | ||||
-rw-r--r-- | fs/ubifs/xattr.c | 71 |
14 files changed, 332 insertions, 176 deletions
diff --git a/fs/ubifs/auth.c b/fs/ubifs/auth.c index b758004085c4..60f43b93d06e 100644 --- a/fs/ubifs/auth.c +++ b/fs/ubifs/auth.c | |||
@@ -76,7 +76,6 @@ static int ubifs_hash_calc_hmac(const struct ubifs_info *c, const u8 *hash, | |||
76 | int ubifs_prepare_auth_node(struct ubifs_info *c, void *node, | 76 | int ubifs_prepare_auth_node(struct ubifs_info *c, void *node, |
77 | struct shash_desc *inhash) | 77 | struct shash_desc *inhash) |
78 | { | 78 | { |
79 | SHASH_DESC_ON_STACK(hash_desc, c->hash_tfm); | ||
80 | struct ubifs_auth_node *auth = node; | 79 | struct ubifs_auth_node *auth = node; |
81 | u8 *hash; | 80 | u8 *hash; |
82 | int err; | 81 | int err; |
@@ -85,12 +84,16 @@ int ubifs_prepare_auth_node(struct ubifs_info *c, void *node, | |||
85 | if (!hash) | 84 | if (!hash) |
86 | return -ENOMEM; | 85 | return -ENOMEM; |
87 | 86 | ||
88 | hash_desc->tfm = c->hash_tfm; | 87 | { |
89 | ubifs_shash_copy_state(c, inhash, hash_desc); | 88 | SHASH_DESC_ON_STACK(hash_desc, c->hash_tfm); |
90 | 89 | ||
91 | err = crypto_shash_final(hash_desc, hash); | 90 | hash_desc->tfm = c->hash_tfm; |
92 | if (err) | 91 | ubifs_shash_copy_state(c, inhash, hash_desc); |
93 | goto out; | 92 | |
93 | err = crypto_shash_final(hash_desc, hash); | ||
94 | if (err) | ||
95 | goto out; | ||
96 | } | ||
94 | 97 | ||
95 | err = ubifs_hash_calc_hmac(c, hash, auth->hmac); | 98 | err = ubifs_hash_calc_hmac(c, hash, auth->hmac); |
96 | if (err) | 99 | if (err) |
@@ -143,24 +146,6 @@ struct shash_desc *__ubifs_hash_get_desc(const struct ubifs_info *c) | |||
143 | } | 146 | } |
144 | 147 | ||
145 | /** | 148 | /** |
146 | * __ubifs_shash_final - finalize shash | ||
147 | * @c: UBIFS file-system description object | ||
148 | * @desc: the descriptor | ||
149 | * @out: the output hash | ||
150 | * | ||
151 | * Simple wrapper around crypto_shash_final(), safe to be called with | ||
152 | * disabled authentication. | ||
153 | */ | ||
154 | int __ubifs_shash_final(const struct ubifs_info *c, struct shash_desc *desc, | ||
155 | u8 *out) | ||
156 | { | ||
157 | if (ubifs_authenticated(c)) | ||
158 | return crypto_shash_final(desc, out); | ||
159 | |||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | /** | ||
164 | * ubifs_bad_hash - Report hash mismatches | 149 | * ubifs_bad_hash - Report hash mismatches |
165 | * @c: UBIFS file-system description object | 150 | * @c: UBIFS file-system description object |
166 | * @node: the node | 151 | * @node: the node |
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c index c49ff50fdceb..3a2613038e88 100644 --- a/fs/ubifs/debug.c +++ b/fs/ubifs/debug.c | |||
@@ -1603,7 +1603,6 @@ int dbg_walk_index(struct ubifs_info *c, dbg_leaf_callback leaf_cb, | |||
1603 | err = PTR_ERR(child); | 1603 | err = PTR_ERR(child); |
1604 | goto out_unlock; | 1604 | goto out_unlock; |
1605 | } | 1605 | } |
1606 | zbr->znode = child; | ||
1607 | } | 1606 | } |
1608 | 1607 | ||
1609 | znode = child; | 1608 | znode = child; |
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index b73de6d04fa3..1a379b596b0d 100644 --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c | |||
@@ -790,16 +790,14 @@ static int ubifs_unlink(struct inode *dir, struct dentry *dentry) | |||
790 | dentry, inode->i_ino, | 790 | dentry, inode->i_ino, |
791 | inode->i_nlink, dir->i_ino); | 791 | inode->i_nlink, dir->i_ino); |
792 | 792 | ||
793 | if (ubifs_crypt_is_encrypted(dir)) { | ||
794 | err = fscrypt_get_encryption_info(dir); | ||
795 | if (err && err != -ENOKEY) | ||
796 | return err; | ||
797 | } | ||
798 | |||
799 | err = fscrypt_setup_filename(dir, &dentry->d_name, 1, &nm); | 793 | err = fscrypt_setup_filename(dir, &dentry->d_name, 1, &nm); |
800 | if (err) | 794 | if (err) |
801 | return err; | 795 | return err; |
802 | 796 | ||
797 | err = ubifs_purge_xattrs(inode); | ||
798 | if (err) | ||
799 | return err; | ||
800 | |||
803 | sz_change = CALC_DENT_SIZE(fname_len(&nm)); | 801 | sz_change = CALC_DENT_SIZE(fname_len(&nm)); |
804 | 802 | ||
805 | ubifs_assert(c, inode_is_locked(dir)); | 803 | ubifs_assert(c, inode_is_locked(dir)); |
@@ -900,16 +898,14 @@ static int ubifs_rmdir(struct inode *dir, struct dentry *dentry) | |||
900 | if (err) | 898 | if (err) |
901 | return err; | 899 | return err; |
902 | 900 | ||
903 | if (ubifs_crypt_is_encrypted(dir)) { | ||
904 | err = fscrypt_get_encryption_info(dir); | ||
905 | if (err && err != -ENOKEY) | ||
906 | return err; | ||
907 | } | ||
908 | |||
909 | err = fscrypt_setup_filename(dir, &dentry->d_name, 1, &nm); | 901 | err = fscrypt_setup_filename(dir, &dentry->d_name, 1, &nm); |
910 | if (err) | 902 | if (err) |
911 | return err; | 903 | return err; |
912 | 904 | ||
905 | err = ubifs_purge_xattrs(inode); | ||
906 | if (err) | ||
907 | return err; | ||
908 | |||
913 | sz_change = CALC_DENT_SIZE(fname_len(&nm)); | 909 | sz_change = CALC_DENT_SIZE(fname_len(&nm)); |
914 | 910 | ||
915 | err = ubifs_budget_space(c, &req); | 911 | err = ubifs_budget_space(c, &req); |
@@ -1292,9 +1288,14 @@ static int do_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1292 | old_dentry, old_inode->i_ino, old_dir->i_ino, | 1288 | old_dentry, old_inode->i_ino, old_dir->i_ino, |
1293 | new_dentry, new_dir->i_ino, flags); | 1289 | new_dentry, new_dir->i_ino, flags); |
1294 | 1290 | ||
1295 | if (unlink) | 1291 | if (unlink) { |
1296 | ubifs_assert(c, inode_is_locked(new_inode)); | 1292 | ubifs_assert(c, inode_is_locked(new_inode)); |
1297 | 1293 | ||
1294 | err = ubifs_purge_xattrs(new_inode); | ||
1295 | if (err) | ||
1296 | return err; | ||
1297 | } | ||
1298 | |||
1298 | if (unlink && is_dir) { | 1299 | if (unlink && is_dir) { |
1299 | err = ubifs_check_dir_empty(new_inode); | 1300 | err = ubifs_check_dir_empty(new_inode); |
1300 | if (err) | 1301 | if (err) |
@@ -1650,9 +1651,7 @@ const struct inode_operations ubifs_dir_inode_operations = { | |||
1650 | #ifdef CONFIG_UBIFS_FS_XATTR | 1651 | #ifdef CONFIG_UBIFS_FS_XATTR |
1651 | .listxattr = ubifs_listxattr, | 1652 | .listxattr = ubifs_listxattr, |
1652 | #endif | 1653 | #endif |
1653 | #ifdef CONFIG_UBIFS_ATIME_SUPPORT | ||
1654 | .update_time = ubifs_update_time, | 1654 | .update_time = ubifs_update_time, |
1655 | #endif | ||
1656 | .tmpfile = ubifs_tmpfile, | 1655 | .tmpfile = ubifs_tmpfile, |
1657 | }; | 1656 | }; |
1658 | 1657 | ||
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c index 5d2ffb1a45fc..512e7d9c60cd 100644 --- a/fs/ubifs/file.c +++ b/fs/ubifs/file.c | |||
@@ -1375,7 +1375,6 @@ static inline int mctime_update_needed(const struct inode *inode, | |||
1375 | return 0; | 1375 | return 0; |
1376 | } | 1376 | } |
1377 | 1377 | ||
1378 | #ifdef CONFIG_UBIFS_ATIME_SUPPORT | ||
1379 | /** | 1378 | /** |
1380 | * ubifs_update_time - update time of inode. | 1379 | * ubifs_update_time - update time of inode. |
1381 | * @inode: inode to update | 1380 | * @inode: inode to update |
@@ -1392,6 +1391,9 @@ int ubifs_update_time(struct inode *inode, struct timespec64 *time, | |||
1392 | int iflags = I_DIRTY_TIME; | 1391 | int iflags = I_DIRTY_TIME; |
1393 | int err, release; | 1392 | int err, release; |
1394 | 1393 | ||
1394 | if (!IS_ENABLED(CONFIG_UBIFS_ATIME_SUPPORT)) | ||
1395 | return generic_update_time(inode, time, flags); | ||
1396 | |||
1395 | err = ubifs_budget_space(c, &req); | 1397 | err = ubifs_budget_space(c, &req); |
1396 | if (err) | 1398 | if (err) |
1397 | return err; | 1399 | return err; |
@@ -1414,7 +1416,6 @@ int ubifs_update_time(struct inode *inode, struct timespec64 *time, | |||
1414 | ubifs_release_budget(c, &req); | 1416 | ubifs_release_budget(c, &req); |
1415 | return 0; | 1417 | return 0; |
1416 | } | 1418 | } |
1417 | #endif | ||
1418 | 1419 | ||
1419 | /** | 1420 | /** |
1420 | * update_mctime - update mtime and ctime of an inode. | 1421 | * update_mctime - update mtime and ctime of an inode. |
@@ -1623,9 +1624,10 @@ static int ubifs_file_mmap(struct file *file, struct vm_area_struct *vma) | |||
1623 | if (err) | 1624 | if (err) |
1624 | return err; | 1625 | return err; |
1625 | vma->vm_ops = &ubifs_file_vm_ops; | 1626 | vma->vm_ops = &ubifs_file_vm_ops; |
1626 | #ifdef CONFIG_UBIFS_ATIME_SUPPORT | 1627 | |
1627 | file_accessed(file); | 1628 | if (IS_ENABLED(CONFIG_UBIFS_ATIME_SUPPORT)) |
1628 | #endif | 1629 | file_accessed(file); |
1630 | |||
1629 | return 0; | 1631 | return 0; |
1630 | } | 1632 | } |
1631 | 1633 | ||
@@ -1663,9 +1665,7 @@ const struct inode_operations ubifs_file_inode_operations = { | |||
1663 | #ifdef CONFIG_UBIFS_FS_XATTR | 1665 | #ifdef CONFIG_UBIFS_FS_XATTR |
1664 | .listxattr = ubifs_listxattr, | 1666 | .listxattr = ubifs_listxattr, |
1665 | #endif | 1667 | #endif |
1666 | #ifdef CONFIG_UBIFS_ATIME_SUPPORT | ||
1667 | .update_time = ubifs_update_time, | 1668 | .update_time = ubifs_update_time, |
1668 | #endif | ||
1669 | }; | 1669 | }; |
1670 | 1670 | ||
1671 | const struct inode_operations ubifs_symlink_inode_operations = { | 1671 | const struct inode_operations ubifs_symlink_inode_operations = { |
@@ -1675,9 +1675,7 @@ const struct inode_operations ubifs_symlink_inode_operations = { | |||
1675 | #ifdef CONFIG_UBIFS_FS_XATTR | 1675 | #ifdef CONFIG_UBIFS_FS_XATTR |
1676 | .listxattr = ubifs_listxattr, | 1676 | .listxattr = ubifs_listxattr, |
1677 | #endif | 1677 | #endif |
1678 | #ifdef CONFIG_UBIFS_ATIME_SUPPORT | ||
1679 | .update_time = ubifs_update_time, | 1678 | .update_time = ubifs_update_time, |
1680 | #endif | ||
1681 | }; | 1679 | }; |
1682 | 1680 | ||
1683 | const struct file_operations ubifs_file_operations = { | 1681 | const struct file_operations ubifs_file_operations = { |
diff --git a/fs/ubifs/find.c b/fs/ubifs/find.c index f9646835b026..5deaae7fcead 100644 --- a/fs/ubifs/find.c +++ b/fs/ubifs/find.c | |||
@@ -747,12 +747,6 @@ static int cmp_dirty_idx(const struct ubifs_lprops **a, | |||
747 | return lpa->dirty + lpa->free - lpb->dirty - lpb->free; | 747 | return lpa->dirty + lpa->free - lpb->dirty - lpb->free; |
748 | } | 748 | } |
749 | 749 | ||
750 | static void swap_dirty_idx(struct ubifs_lprops **a, struct ubifs_lprops **b, | ||
751 | int size) | ||
752 | { | ||
753 | swap(*a, *b); | ||
754 | } | ||
755 | |||
756 | /** | 750 | /** |
757 | * ubifs_save_dirty_idx_lnums - save an array of the most dirty index LEB nos. | 751 | * ubifs_save_dirty_idx_lnums - save an array of the most dirty index LEB nos. |
758 | * @c: the UBIFS file-system description object | 752 | * @c: the UBIFS file-system description object |
@@ -772,8 +766,7 @@ int ubifs_save_dirty_idx_lnums(struct ubifs_info *c) | |||
772 | sizeof(void *) * c->dirty_idx.cnt); | 766 | sizeof(void *) * c->dirty_idx.cnt); |
773 | /* Sort it so that the dirtiest is now at the end */ | 767 | /* Sort it so that the dirtiest is now at the end */ |
774 | sort(c->dirty_idx.arr, c->dirty_idx.cnt, sizeof(void *), | 768 | sort(c->dirty_idx.arr, c->dirty_idx.cnt, sizeof(void *), |
775 | (int (*)(const void *, const void *))cmp_dirty_idx, | 769 | (int (*)(const void *, const void *))cmp_dirty_idx, NULL); |
776 | (void (*)(void *, void *, int))swap_dirty_idx); | ||
777 | dbg_find("found %d dirty index LEBs", c->dirty_idx.cnt); | 770 | dbg_find("found %d dirty index LEBs", c->dirty_idx.cnt); |
778 | if (c->dirty_idx.cnt) | 771 | if (c->dirty_idx.cnt) |
779 | dbg_find("dirtiest index LEB is %d with dirty %d and free %d", | 772 | dbg_find("dirtiest index LEB is %d with dirty %d and free %d", |
diff --git a/fs/ubifs/ioctl.c b/fs/ubifs/ioctl.c index 82e4e6a30b04..6b05b3ec500e 100644 --- a/fs/ubifs/ioctl.c +++ b/fs/ubifs/ioctl.c | |||
@@ -193,7 +193,6 @@ long ubifs_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
193 | return err; | 193 | return err; |
194 | } | 194 | } |
195 | case FS_IOC_SET_ENCRYPTION_POLICY: { | 195 | case FS_IOC_SET_ENCRYPTION_POLICY: { |
196 | #ifdef CONFIG_FS_ENCRYPTION | ||
197 | struct ubifs_info *c = inode->i_sb->s_fs_info; | 196 | struct ubifs_info *c = inode->i_sb->s_fs_info; |
198 | 197 | ||
199 | err = ubifs_enable_encryption(c); | 198 | err = ubifs_enable_encryption(c); |
@@ -201,17 +200,9 @@ long ubifs_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
201 | return err; | 200 | return err; |
202 | 201 | ||
203 | return fscrypt_ioctl_set_policy(file, (const void __user *)arg); | 202 | return fscrypt_ioctl_set_policy(file, (const void __user *)arg); |
204 | #else | ||
205 | return -EOPNOTSUPP; | ||
206 | #endif | ||
207 | } | 203 | } |
208 | case FS_IOC_GET_ENCRYPTION_POLICY: { | 204 | case FS_IOC_GET_ENCRYPTION_POLICY: |
209 | #ifdef CONFIG_FS_ENCRYPTION | ||
210 | return fscrypt_ioctl_get_policy(file, (void __user *)arg); | 205 | return fscrypt_ioctl_get_policy(file, (void __user *)arg); |
211 | #else | ||
212 | return -EOPNOTSUPP; | ||
213 | #endif | ||
214 | } | ||
215 | 206 | ||
216 | default: | 207 | default: |
217 | return -ENOTTY; | 208 | return -ENOTTY; |
diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c index 729dc76c83df..74a7306978d0 100644 --- a/fs/ubifs/journal.c +++ b/fs/ubifs/journal.c | |||
@@ -852,10 +852,11 @@ out_free: | |||
852 | int ubifs_jnl_write_inode(struct ubifs_info *c, const struct inode *inode) | 852 | int ubifs_jnl_write_inode(struct ubifs_info *c, const struct inode *inode) |
853 | { | 853 | { |
854 | int err, lnum, offs; | 854 | int err, lnum, offs; |
855 | struct ubifs_ino_node *ino; | 855 | struct ubifs_ino_node *ino, *ino_start; |
856 | struct ubifs_inode *ui = ubifs_inode(inode); | 856 | struct ubifs_inode *ui = ubifs_inode(inode); |
857 | int sync = 0, write_len, ilen = UBIFS_INO_NODE_SZ; | 857 | int sync = 0, write_len = 0, ilen = UBIFS_INO_NODE_SZ; |
858 | int last_reference = !inode->i_nlink; | 858 | int last_reference = !inode->i_nlink; |
859 | int kill_xattrs = ui->xattr_cnt && last_reference; | ||
859 | u8 hash[UBIFS_HASH_ARR_SZ]; | 860 | u8 hash[UBIFS_HASH_ARR_SZ]; |
860 | 861 | ||
861 | dbg_jnl("ino %lu, nlink %u", inode->i_ino, inode->i_nlink); | 862 | dbg_jnl("ino %lu, nlink %u", inode->i_ino, inode->i_nlink); |
@@ -867,14 +868,16 @@ int ubifs_jnl_write_inode(struct ubifs_info *c, const struct inode *inode) | |||
867 | if (!last_reference) { | 868 | if (!last_reference) { |
868 | ilen += ui->data_len; | 869 | ilen += ui->data_len; |
869 | sync = IS_SYNC(inode); | 870 | sync = IS_SYNC(inode); |
871 | } else if (kill_xattrs) { | ||
872 | write_len += UBIFS_INO_NODE_SZ * ui->xattr_cnt; | ||
870 | } | 873 | } |
871 | 874 | ||
872 | if (ubifs_authenticated(c)) | 875 | if (ubifs_authenticated(c)) |
873 | write_len = ALIGN(ilen, 8) + ubifs_auth_node_sz(c); | 876 | write_len += ALIGN(ilen, 8) + ubifs_auth_node_sz(c); |
874 | else | 877 | else |
875 | write_len = ilen; | 878 | write_len += ilen; |
876 | 879 | ||
877 | ino = kmalloc(write_len, GFP_NOFS); | 880 | ino_start = ino = kmalloc(write_len, GFP_NOFS); |
878 | if (!ino) | 881 | if (!ino) |
879 | return -ENOMEM; | 882 | return -ENOMEM; |
880 | 883 | ||
@@ -883,12 +886,59 @@ int ubifs_jnl_write_inode(struct ubifs_info *c, const struct inode *inode) | |||
883 | if (err) | 886 | if (err) |
884 | goto out_free; | 887 | goto out_free; |
885 | 888 | ||
889 | if (kill_xattrs) { | ||
890 | union ubifs_key key; | ||
891 | struct fscrypt_name nm = {0}; | ||
892 | struct inode *xino; | ||
893 | struct ubifs_dent_node *xent, *pxent = NULL; | ||
894 | |||
895 | if (ui->xattr_cnt >= ubifs_xattr_max_cnt(c)) { | ||
896 | ubifs_err(c, "Cannot delete inode, it has too much xattrs!"); | ||
897 | goto out_release; | ||
898 | } | ||
899 | |||
900 | lowest_xent_key(c, &key, inode->i_ino); | ||
901 | while (1) { | ||
902 | xent = ubifs_tnc_next_ent(c, &key, &nm); | ||
903 | if (IS_ERR(xent)) { | ||
904 | err = PTR_ERR(xent); | ||
905 | if (err == -ENOENT) | ||
906 | break; | ||
907 | |||
908 | goto out_release; | ||
909 | } | ||
910 | |||
911 | fname_name(&nm) = xent->name; | ||
912 | fname_len(&nm) = le16_to_cpu(xent->nlen); | ||
913 | |||
914 | xino = ubifs_iget(c->vfs_sb, xent->inum); | ||
915 | if (IS_ERR(xino)) { | ||
916 | err = PTR_ERR(xino); | ||
917 | ubifs_err(c, "dead directory entry '%s', error %d", | ||
918 | xent->name, err); | ||
919 | ubifs_ro_mode(c, err); | ||
920 | goto out_release; | ||
921 | } | ||
922 | ubifs_assert(c, ubifs_inode(xino)->xattr); | ||
923 | |||
924 | clear_nlink(xino); | ||
925 | pack_inode(c, ino, xino, 0); | ||
926 | ino = (void *)ino + UBIFS_INO_NODE_SZ; | ||
927 | iput(xino); | ||
928 | |||
929 | kfree(pxent); | ||
930 | pxent = xent; | ||
931 | key_read(c, &xent->key, &key); | ||
932 | } | ||
933 | kfree(pxent); | ||
934 | } | ||
935 | |||
886 | pack_inode(c, ino, inode, 1); | 936 | pack_inode(c, ino, inode, 1); |
887 | err = ubifs_node_calc_hash(c, ino, hash); | 937 | err = ubifs_node_calc_hash(c, ino, hash); |
888 | if (err) | 938 | if (err) |
889 | goto out_release; | 939 | goto out_release; |
890 | 940 | ||
891 | err = write_head(c, BASEHD, ino, write_len, &lnum, &offs, sync); | 941 | err = write_head(c, BASEHD, ino_start, write_len, &lnum, &offs, sync); |
892 | if (err) | 942 | if (err) |
893 | goto out_release; | 943 | goto out_release; |
894 | if (!sync) | 944 | if (!sync) |
@@ -903,7 +953,7 @@ int ubifs_jnl_write_inode(struct ubifs_info *c, const struct inode *inode) | |||
903 | if (err) | 953 | if (err) |
904 | goto out_ro; | 954 | goto out_ro; |
905 | ubifs_delete_orphan(c, inode->i_ino); | 955 | ubifs_delete_orphan(c, inode->i_ino); |
906 | err = ubifs_add_dirt(c, lnum, ilen); | 956 | err = ubifs_add_dirt(c, lnum, write_len); |
907 | } else { | 957 | } else { |
908 | union ubifs_key key; | 958 | union ubifs_key key; |
909 | 959 | ||
@@ -917,7 +967,7 @@ int ubifs_jnl_write_inode(struct ubifs_info *c, const struct inode *inode) | |||
917 | spin_lock(&ui->ui_lock); | 967 | spin_lock(&ui->ui_lock); |
918 | ui->synced_i_size = ui->ui_size; | 968 | ui->synced_i_size = ui->ui_size; |
919 | spin_unlock(&ui->ui_lock); | 969 | spin_unlock(&ui->ui_lock); |
920 | kfree(ino); | 970 | kfree(ino_start); |
921 | return 0; | 971 | return 0; |
922 | 972 | ||
923 | out_release: | 973 | out_release: |
@@ -926,7 +976,7 @@ out_ro: | |||
926 | ubifs_ro_mode(c, err); | 976 | ubifs_ro_mode(c, err); |
927 | finish_reservation(c); | 977 | finish_reservation(c); |
928 | out_free: | 978 | out_free: |
929 | kfree(ino); | 979 | kfree(ino_start); |
930 | return err; | 980 | return err; |
931 | } | 981 | } |
932 | 982 | ||
@@ -966,8 +1016,8 @@ int ubifs_jnl_delete_inode(struct ubifs_info *c, const struct inode *inode) | |||
966 | 1016 | ||
967 | ubifs_assert(c, inode->i_nlink == 0); | 1017 | ubifs_assert(c, inode->i_nlink == 0); |
968 | 1018 | ||
969 | if (ui->del_cmtno != c->cmt_no) | 1019 | if (ui->xattr_cnt || ui->del_cmtno != c->cmt_no) |
970 | /* A commit happened for sure */ | 1020 | /* A commit happened for sure or inode hosts xattrs */ |
971 | return ubifs_jnl_write_inode(c, inode); | 1021 | return ubifs_jnl_write_inode(c, inode); |
972 | 1022 | ||
973 | down_read(&c->commit_sem); | 1023 | down_read(&c->commit_sem); |
diff --git a/fs/ubifs/misc.h b/fs/ubifs/misc.h index 6f87237fdbf4..78a6e97f846e 100644 --- a/fs/ubifs/misc.h +++ b/fs/ubifs/misc.h | |||
@@ -288,6 +288,14 @@ static inline int ubifs_next_log_lnum(const struct ubifs_info *c, int lnum) | |||
288 | return lnum; | 288 | return lnum; |
289 | } | 289 | } |
290 | 290 | ||
291 | static inline int ubifs_xattr_max_cnt(struct ubifs_info *c) | ||
292 | { | ||
293 | int max_xattrs = (c->leb_size / 2) / UBIFS_INO_NODE_SZ; | ||
294 | |||
295 | ubifs_assert(c, max_xattrs < c->max_orphans); | ||
296 | return max_xattrs; | ||
297 | } | ||
298 | |||
291 | const char *ubifs_assert_action_name(struct ubifs_info *c); | 299 | const char *ubifs_assert_action_name(struct ubifs_info *c); |
292 | 300 | ||
293 | #endif /* __UBIFS_MISC_H__ */ | 301 | #endif /* __UBIFS_MISC_H__ */ |
diff --git a/fs/ubifs/orphan.c b/fs/ubifs/orphan.c index 8f70494efb0c..2f1618f300fb 100644 --- a/fs/ubifs/orphan.c +++ b/fs/ubifs/orphan.c | |||
@@ -54,30 +54,24 @@ | |||
54 | 54 | ||
55 | static int dbg_check_orphans(struct ubifs_info *c); | 55 | static int dbg_check_orphans(struct ubifs_info *c); |
56 | 56 | ||
57 | /** | 57 | static struct ubifs_orphan *orphan_add(struct ubifs_info *c, ino_t inum, |
58 | * ubifs_add_orphan - add an orphan. | 58 | struct ubifs_orphan *parent_orphan) |
59 | * @c: UBIFS file-system description object | ||
60 | * @inum: orphan inode number | ||
61 | * | ||
62 | * Add an orphan. This function is called when an inodes link count drops to | ||
63 | * zero. | ||
64 | */ | ||
65 | int ubifs_add_orphan(struct ubifs_info *c, ino_t inum) | ||
66 | { | 59 | { |
67 | struct ubifs_orphan *orphan, *o; | 60 | struct ubifs_orphan *orphan, *o; |
68 | struct rb_node **p, *parent = NULL; | 61 | struct rb_node **p, *parent = NULL; |
69 | 62 | ||
70 | orphan = kzalloc(sizeof(struct ubifs_orphan), GFP_NOFS); | 63 | orphan = kzalloc(sizeof(struct ubifs_orphan), GFP_NOFS); |
71 | if (!orphan) | 64 | if (!orphan) |
72 | return -ENOMEM; | 65 | return ERR_PTR(-ENOMEM); |
73 | orphan->inum = inum; | 66 | orphan->inum = inum; |
74 | orphan->new = 1; | 67 | orphan->new = 1; |
68 | INIT_LIST_HEAD(&orphan->child_list); | ||
75 | 69 | ||
76 | spin_lock(&c->orphan_lock); | 70 | spin_lock(&c->orphan_lock); |
77 | if (c->tot_orphans >= c->max_orphans) { | 71 | if (c->tot_orphans >= c->max_orphans) { |
78 | spin_unlock(&c->orphan_lock); | 72 | spin_unlock(&c->orphan_lock); |
79 | kfree(orphan); | 73 | kfree(orphan); |
80 | return -ENFILE; | 74 | return ERR_PTR(-ENFILE); |
81 | } | 75 | } |
82 | p = &c->orph_tree.rb_node; | 76 | p = &c->orph_tree.rb_node; |
83 | while (*p) { | 77 | while (*p) { |
@@ -91,7 +85,7 @@ int ubifs_add_orphan(struct ubifs_info *c, ino_t inum) | |||
91 | ubifs_err(c, "orphaned twice"); | 85 | ubifs_err(c, "orphaned twice"); |
92 | spin_unlock(&c->orphan_lock); | 86 | spin_unlock(&c->orphan_lock); |
93 | kfree(orphan); | 87 | kfree(orphan); |
94 | return 0; | 88 | return ERR_PTR(-EINVAL); |
95 | } | 89 | } |
96 | } | 90 | } |
97 | c->tot_orphans += 1; | 91 | c->tot_orphans += 1; |
@@ -100,24 +94,22 @@ int ubifs_add_orphan(struct ubifs_info *c, ino_t inum) | |||
100 | rb_insert_color(&orphan->rb, &c->orph_tree); | 94 | rb_insert_color(&orphan->rb, &c->orph_tree); |
101 | list_add_tail(&orphan->list, &c->orph_list); | 95 | list_add_tail(&orphan->list, &c->orph_list); |
102 | list_add_tail(&orphan->new_list, &c->orph_new); | 96 | list_add_tail(&orphan->new_list, &c->orph_new); |
97 | |||
98 | if (parent_orphan) { | ||
99 | list_add_tail(&orphan->child_list, | ||
100 | &parent_orphan->child_list); | ||
101 | } | ||
102 | |||
103 | spin_unlock(&c->orphan_lock); | 103 | spin_unlock(&c->orphan_lock); |
104 | dbg_gen("ino %lu", (unsigned long)inum); | 104 | dbg_gen("ino %lu", (unsigned long)inum); |
105 | return 0; | 105 | return orphan; |
106 | } | 106 | } |
107 | 107 | ||
108 | /** | 108 | static struct ubifs_orphan *lookup_orphan(struct ubifs_info *c, ino_t inum) |
109 | * ubifs_delete_orphan - delete an orphan. | ||
110 | * @c: UBIFS file-system description object | ||
111 | * @inum: orphan inode number | ||
112 | * | ||
113 | * Delete an orphan. This function is called when an inode is deleted. | ||
114 | */ | ||
115 | void ubifs_delete_orphan(struct ubifs_info *c, ino_t inum) | ||
116 | { | 109 | { |
117 | struct ubifs_orphan *o; | 110 | struct ubifs_orphan *o; |
118 | struct rb_node *p; | 111 | struct rb_node *p; |
119 | 112 | ||
120 | spin_lock(&c->orphan_lock); | ||
121 | p = c->orph_tree.rb_node; | 113 | p = c->orph_tree.rb_node; |
122 | while (p) { | 114 | while (p) { |
123 | o = rb_entry(p, struct ubifs_orphan, rb); | 115 | o = rb_entry(p, struct ubifs_orphan, rb); |
@@ -126,37 +118,124 @@ void ubifs_delete_orphan(struct ubifs_info *c, ino_t inum) | |||
126 | else if (inum > o->inum) | 118 | else if (inum > o->inum) |
127 | p = p->rb_right; | 119 | p = p->rb_right; |
128 | else { | 120 | else { |
129 | if (o->del) { | 121 | return o; |
130 | spin_unlock(&c->orphan_lock); | ||
131 | dbg_gen("deleted twice ino %lu", | ||
132 | (unsigned long)inum); | ||
133 | return; | ||
134 | } | ||
135 | if (o->cmt) { | ||
136 | o->del = 1; | ||
137 | o->dnext = c->orph_dnext; | ||
138 | c->orph_dnext = o; | ||
139 | spin_unlock(&c->orphan_lock); | ||
140 | dbg_gen("delete later ino %lu", | ||
141 | (unsigned long)inum); | ||
142 | return; | ||
143 | } | ||
144 | rb_erase(p, &c->orph_tree); | ||
145 | list_del(&o->list); | ||
146 | c->tot_orphans -= 1; | ||
147 | if (o->new) { | ||
148 | list_del(&o->new_list); | ||
149 | c->new_orphans -= 1; | ||
150 | } | ||
151 | spin_unlock(&c->orphan_lock); | ||
152 | kfree(o); | ||
153 | dbg_gen("inum %lu", (unsigned long)inum); | ||
154 | return; | ||
155 | } | 122 | } |
156 | } | 123 | } |
124 | return NULL; | ||
125 | } | ||
126 | |||
127 | static void __orphan_drop(struct ubifs_info *c, struct ubifs_orphan *o) | ||
128 | { | ||
129 | rb_erase(&o->rb, &c->orph_tree); | ||
130 | list_del(&o->list); | ||
131 | c->tot_orphans -= 1; | ||
132 | |||
133 | if (o->new) { | ||
134 | list_del(&o->new_list); | ||
135 | c->new_orphans -= 1; | ||
136 | } | ||
137 | |||
138 | kfree(o); | ||
139 | } | ||
140 | |||
141 | static void orphan_delete(struct ubifs_info *c, ino_t inum) | ||
142 | { | ||
143 | struct ubifs_orphan *orph, *child_orph, *tmp_o; | ||
144 | |||
145 | spin_lock(&c->orphan_lock); | ||
146 | |||
147 | orph = lookup_orphan(c, inum); | ||
148 | if (!orph) { | ||
149 | spin_unlock(&c->orphan_lock); | ||
150 | ubifs_err(c, "missing orphan ino %lu", (unsigned long)inum); | ||
151 | dump_stack(); | ||
152 | |||
153 | return; | ||
154 | } | ||
155 | |||
156 | if (orph->del) { | ||
157 | spin_unlock(&c->orphan_lock); | ||
158 | dbg_gen("deleted twice ino %lu", | ||
159 | (unsigned long)inum); | ||
160 | return; | ||
161 | } | ||
162 | |||
163 | if (orph->cmt) { | ||
164 | orph->del = 1; | ||
165 | orph->dnext = c->orph_dnext; | ||
166 | c->orph_dnext = orph; | ||
167 | spin_unlock(&c->orphan_lock); | ||
168 | dbg_gen("delete later ino %lu", | ||
169 | (unsigned long)inum); | ||
170 | return; | ||
171 | } | ||
172 | |||
173 | list_for_each_entry_safe(child_orph, tmp_o, &orph->child_list, child_list) { | ||
174 | list_del(&child_orph->child_list); | ||
175 | __orphan_drop(c, child_orph); | ||
176 | } | ||
177 | |||
178 | __orphan_drop(c, orph); | ||
179 | |||
157 | spin_unlock(&c->orphan_lock); | 180 | spin_unlock(&c->orphan_lock); |
158 | ubifs_err(c, "missing orphan ino %lu", (unsigned long)inum); | 181 | } |
159 | dump_stack(); | 182 | |
183 | /** | ||
184 | * ubifs_add_orphan - add an orphan. | ||
185 | * @c: UBIFS file-system description object | ||
186 | * @inum: orphan inode number | ||
187 | * | ||
188 | * Add an orphan. This function is called when an inodes link count drops to | ||
189 | * zero. | ||
190 | */ | ||
191 | int ubifs_add_orphan(struct ubifs_info *c, ino_t inum) | ||
192 | { | ||
193 | int err = 0; | ||
194 | ino_t xattr_inum; | ||
195 | union ubifs_key key; | ||
196 | struct ubifs_dent_node *xent; | ||
197 | struct fscrypt_name nm = {0}; | ||
198 | struct ubifs_orphan *xattr_orphan; | ||
199 | struct ubifs_orphan *orphan; | ||
200 | |||
201 | orphan = orphan_add(c, inum, NULL); | ||
202 | if (IS_ERR(orphan)) | ||
203 | return PTR_ERR(orphan); | ||
204 | |||
205 | lowest_xent_key(c, &key, inum); | ||
206 | while (1) { | ||
207 | xent = ubifs_tnc_next_ent(c, &key, &nm); | ||
208 | if (IS_ERR(xent)) { | ||
209 | err = PTR_ERR(xent); | ||
210 | if (err == -ENOENT) | ||
211 | break; | ||
212 | return err; | ||
213 | } | ||
214 | |||
215 | fname_name(&nm) = xent->name; | ||
216 | fname_len(&nm) = le16_to_cpu(xent->nlen); | ||
217 | xattr_inum = le64_to_cpu(xent->inum); | ||
218 | |||
219 | xattr_orphan = orphan_add(c, xattr_inum, orphan); | ||
220 | if (IS_ERR(xattr_orphan)) | ||
221 | return PTR_ERR(xattr_orphan); | ||
222 | |||
223 | key_read(c, &xent->key, &key); | ||
224 | } | ||
225 | |||
226 | return 0; | ||
227 | } | ||
228 | |||
229 | /** | ||
230 | * ubifs_delete_orphan - delete an orphan. | ||
231 | * @c: UBIFS file-system description object | ||
232 | * @inum: orphan inode number | ||
233 | * | ||
234 | * Delete an orphan. This function is called when an inode is deleted. | ||
235 | */ | ||
236 | void ubifs_delete_orphan(struct ubifs_info *c, ino_t inum) | ||
237 | { | ||
238 | orphan_delete(c, inum); | ||
160 | } | 239 | } |
161 | 240 | ||
162 | /** | 241 | /** |
@@ -611,10 +690,16 @@ static int do_kill_orphans(struct ubifs_info *c, struct ubifs_scan_leb *sleb, | |||
611 | 690 | ||
612 | n = (le32_to_cpu(orph->ch.len) - UBIFS_ORPH_NODE_SZ) >> 3; | 691 | n = (le32_to_cpu(orph->ch.len) - UBIFS_ORPH_NODE_SZ) >> 3; |
613 | for (i = 0; i < n; i++) { | 692 | for (i = 0; i < n; i++) { |
693 | union ubifs_key key1, key2; | ||
694 | |||
614 | inum = le64_to_cpu(orph->inos[i]); | 695 | inum = le64_to_cpu(orph->inos[i]); |
615 | dbg_rcvry("deleting orphaned inode %lu", | 696 | dbg_rcvry("deleting orphaned inode %lu", |
616 | (unsigned long)inum); | 697 | (unsigned long)inum); |
617 | err = ubifs_tnc_remove_ino(c, inum); | 698 | |
699 | lowest_ino_key(c, &key1, inum); | ||
700 | highest_ino_key(c, &key2, inum); | ||
701 | |||
702 | err = ubifs_tnc_remove_range(c, &key1, &key2); | ||
618 | if (err) | 703 | if (err) |
619 | return err; | 704 | return err; |
620 | err = insert_dead_orphan(c, inum); | 705 | err = insert_dead_orphan(c, inum); |
@@ -744,26 +829,15 @@ struct check_info { | |||
744 | struct rb_root root; | 829 | struct rb_root root; |
745 | }; | 830 | }; |
746 | 831 | ||
747 | static int dbg_find_orphan(struct ubifs_info *c, ino_t inum) | 832 | static bool dbg_find_orphan(struct ubifs_info *c, ino_t inum) |
748 | { | 833 | { |
749 | struct ubifs_orphan *o; | 834 | bool found = false; |
750 | struct rb_node *p; | ||
751 | 835 | ||
752 | spin_lock(&c->orphan_lock); | 836 | spin_lock(&c->orphan_lock); |
753 | p = c->orph_tree.rb_node; | 837 | found = !!lookup_orphan(c, inum); |
754 | while (p) { | ||
755 | o = rb_entry(p, struct ubifs_orphan, rb); | ||
756 | if (inum < o->inum) | ||
757 | p = p->rb_left; | ||
758 | else if (inum > o->inum) | ||
759 | p = p->rb_right; | ||
760 | else { | ||
761 | spin_unlock(&c->orphan_lock); | ||
762 | return 1; | ||
763 | } | ||
764 | } | ||
765 | spin_unlock(&c->orphan_lock); | 838 | spin_unlock(&c->orphan_lock); |
766 | return 0; | 839 | |
840 | return found; | ||
767 | } | 841 | } |
768 | 842 | ||
769 | static int dbg_ins_check_orphan(struct rb_root *root, ino_t inum) | 843 | static int dbg_ins_check_orphan(struct rb_root *root, ino_t inum) |
diff --git a/fs/ubifs/sb.c b/fs/ubifs/sb.c index 67fac1e8adfb..2afc8b1d4c3b 100644 --- a/fs/ubifs/sb.c +++ b/fs/ubifs/sb.c | |||
@@ -748,14 +748,12 @@ int ubifs_read_superblock(struct ubifs_info *c) | |||
748 | goto out; | 748 | goto out; |
749 | } | 749 | } |
750 | 750 | ||
751 | #ifndef CONFIG_FS_ENCRYPTION | 751 | if (!IS_ENABLED(CONFIG_UBIFS_FS_ENCRYPTION) && c->encrypted) { |
752 | if (c->encrypted) { | ||
753 | ubifs_err(c, "file system contains encrypted files but UBIFS" | 752 | ubifs_err(c, "file system contains encrypted files but UBIFS" |
754 | " was built without crypto support."); | 753 | " was built without crypto support."); |
755 | err = -EINVAL; | 754 | err = -EINVAL; |
756 | goto out; | 755 | goto out; |
757 | } | 756 | } |
758 | #endif | ||
759 | 757 | ||
760 | /* Automatically increase file system size to the maximum size */ | 758 | /* Automatically increase file system size to the maximum size */ |
761 | c->old_leb_cnt = c->leb_cnt; | 759 | c->old_leb_cnt = c->leb_cnt; |
@@ -943,6 +941,9 @@ int ubifs_enable_encryption(struct ubifs_info *c) | |||
943 | int err; | 941 | int err; |
944 | struct ubifs_sb_node *sup = c->sup_node; | 942 | struct ubifs_sb_node *sup = c->sup_node; |
945 | 943 | ||
944 | if (!IS_ENABLED(CONFIG_UBIFS_FS_ENCRYPTION)) | ||
945 | return -EOPNOTSUPP; | ||
946 | |||
946 | if (c->encrypted) | 947 | if (c->encrypted) |
947 | return 0; | 948 | return 0; |
948 | 949 | ||
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 632f02d4d660..04b8ecfd3470 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c | |||
@@ -129,9 +129,10 @@ struct inode *ubifs_iget(struct super_block *sb, unsigned long inum) | |||
129 | goto out_ino; | 129 | goto out_ino; |
130 | 130 | ||
131 | inode->i_flags |= S_NOCMTIME; | 131 | inode->i_flags |= S_NOCMTIME; |
132 | #ifndef CONFIG_UBIFS_ATIME_SUPPORT | 132 | |
133 | inode->i_flags |= S_NOATIME; | 133 | if (!IS_ENABLED(CONFIG_UBIFS_ATIME_SUPPORT)) |
134 | #endif | 134 | inode->i_flags |= S_NOATIME; |
135 | |||
135 | set_nlink(inode, le32_to_cpu(ino->nlink)); | 136 | set_nlink(inode, le32_to_cpu(ino->nlink)); |
136 | i_uid_write(inode, le32_to_cpu(ino->uid)); | 137 | i_uid_write(inode, le32_to_cpu(ino->uid)); |
137 | i_gid_write(inode, le32_to_cpu(ino->gid)); | 138 | i_gid_write(inode, le32_to_cpu(ino->gid)); |
@@ -1545,6 +1546,8 @@ static int mount_ubifs(struct ubifs_info *c) | |||
1545 | c->bud_bytes, c->bud_bytes >> 10, c->bud_bytes >> 20); | 1546 | c->bud_bytes, c->bud_bytes >> 10, c->bud_bytes >> 20); |
1546 | dbg_gen("max. seq. number: %llu", c->max_sqnum); | 1547 | dbg_gen("max. seq. number: %llu", c->max_sqnum); |
1547 | dbg_gen("commit number: %llu", c->cmt_no); | 1548 | dbg_gen("commit number: %llu", c->cmt_no); |
1549 | dbg_gen("max. xattrs per inode: %d", ubifs_xattr_max_cnt(c)); | ||
1550 | dbg_gen("max orphans: %d", c->max_orphans); | ||
1548 | 1551 | ||
1549 | return 0; | 1552 | return 0; |
1550 | 1553 | ||
@@ -2141,9 +2144,7 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent) | |||
2141 | #ifdef CONFIG_UBIFS_FS_XATTR | 2144 | #ifdef CONFIG_UBIFS_FS_XATTR |
2142 | sb->s_xattr = ubifs_xattr_handlers; | 2145 | sb->s_xattr = ubifs_xattr_handlers; |
2143 | #endif | 2146 | #endif |
2144 | #ifdef CONFIG_FS_ENCRYPTION | 2147 | fscrypt_set_ops(sb, &ubifs_crypt_operations); |
2145 | sb->s_cop = &ubifs_crypt_operations; | ||
2146 | #endif | ||
2147 | 2148 | ||
2148 | mutex_lock(&c->umount_mutex); | 2149 | mutex_lock(&c->umount_mutex); |
2149 | err = mount_ubifs(c); | 2150 | err = mount_ubifs(c); |
@@ -2245,11 +2246,10 @@ static struct dentry *ubifs_mount(struct file_system_type *fs_type, int flags, | |||
2245 | goto out_deact; | 2246 | goto out_deact; |
2246 | /* We do not support atime */ | 2247 | /* We do not support atime */ |
2247 | sb->s_flags |= SB_ACTIVE; | 2248 | sb->s_flags |= SB_ACTIVE; |
2248 | #ifndef CONFIG_UBIFS_ATIME_SUPPORT | 2249 | if (IS_ENABLED(CONFIG_UBIFS_ATIME_SUPPORT)) |
2249 | sb->s_flags |= SB_NOATIME; | 2250 | ubifs_msg(c, "full atime support is enabled."); |
2250 | #else | 2251 | else |
2251 | ubifs_msg(c, "full atime support is enabled."); | 2252 | sb->s_flags |= SB_NOATIME; |
2252 | #endif | ||
2253 | } | 2253 | } |
2254 | 2254 | ||
2255 | /* 'fill_super()' opens ubi again so we must close it here */ | 2255 | /* 'fill_super()' opens ubi again so we must close it here */ |
diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c index 25572ffea163..ebf8c26f5b22 100644 --- a/fs/ubifs/tnc.c +++ b/fs/ubifs/tnc.c | |||
@@ -479,14 +479,13 @@ static int try_read_node(const struct ubifs_info *c, void *buf, int type, | |||
479 | if (node_len != len) | 479 | if (node_len != len) |
480 | return 0; | 480 | return 0; |
481 | 481 | ||
482 | if (type == UBIFS_DATA_NODE && c->no_chk_data_crc && !c->mounting && | 482 | if (type != UBIFS_DATA_NODE || !c->no_chk_data_crc || c->mounting || |
483 | !c->remounting_rw) | 483 | c->remounting_rw) { |
484 | return 1; | 484 | crc = crc32(UBIFS_CRC32_INIT, buf + 8, node_len - 8); |
485 | 485 | node_crc = le32_to_cpu(ch->crc); | |
486 | crc = crc32(UBIFS_CRC32_INIT, buf + 8, node_len - 8); | 486 | if (crc != node_crc) |
487 | node_crc = le32_to_cpu(ch->crc); | 487 | return 0; |
488 | if (crc != node_crc) | 488 | } |
489 | return 0; | ||
490 | 489 | ||
491 | err = ubifs_node_check_hash(c, buf, zbr->hash); | 490 | err = ubifs_node_check_hash(c, buf, zbr->hash); |
492 | if (err) { | 491 | if (err) { |
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index 1ae12900e01d..379b9f791ff6 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h | |||
@@ -924,6 +924,8 @@ struct ubifs_budget_req { | |||
924 | * @rb: rb-tree node of rb-tree of orphans sorted by inode number | 924 | * @rb: rb-tree node of rb-tree of orphans sorted by inode number |
925 | * @list: list head of list of orphans in order added | 925 | * @list: list head of list of orphans in order added |
926 | * @new_list: list head of list of orphans added since the last commit | 926 | * @new_list: list head of list of orphans added since the last commit |
927 | * @child_list: list of xattr childs if this orphan hosts xattrs, list head | ||
928 | * if this orphan is a xattr, not used otherwise. | ||
927 | * @cnext: next orphan to commit | 929 | * @cnext: next orphan to commit |
928 | * @dnext: next orphan to delete | 930 | * @dnext: next orphan to delete |
929 | * @inum: inode number | 931 | * @inum: inode number |
@@ -935,6 +937,7 @@ struct ubifs_orphan { | |||
935 | struct rb_node rb; | 937 | struct rb_node rb; |
936 | struct list_head list; | 938 | struct list_head list; |
937 | struct list_head new_list; | 939 | struct list_head new_list; |
940 | struct list_head child_list; | ||
938 | struct ubifs_orphan *cnext; | 941 | struct ubifs_orphan *cnext; |
939 | struct ubifs_orphan *dnext; | 942 | struct ubifs_orphan *dnext; |
940 | ino_t inum; | 943 | ino_t inum; |
@@ -1996,9 +1999,7 @@ int ubifs_calc_dark(const struct ubifs_info *c, int spc); | |||
1996 | /* file.c */ | 1999 | /* file.c */ |
1997 | int ubifs_fsync(struct file *file, loff_t start, loff_t end, int datasync); | 2000 | int ubifs_fsync(struct file *file, loff_t start, loff_t end, int datasync); |
1998 | int ubifs_setattr(struct dentry *dentry, struct iattr *attr); | 2001 | int ubifs_setattr(struct dentry *dentry, struct iattr *attr); |
1999 | #ifdef CONFIG_UBIFS_ATIME_SUPPORT | ||
2000 | int ubifs_update_time(struct inode *inode, struct timespec64 *time, int flags); | 2002 | int ubifs_update_time(struct inode *inode, struct timespec64 *time, int flags); |
2001 | #endif | ||
2002 | 2003 | ||
2003 | /* dir.c */ | 2004 | /* dir.c */ |
2004 | struct inode *ubifs_new_inode(struct ubifs_info *c, struct inode *dir, | 2005 | struct inode *ubifs_new_inode(struct ubifs_info *c, struct inode *dir, |
@@ -2014,6 +2015,7 @@ int ubifs_xattr_set(struct inode *host, const char *name, const void *value, | |||
2014 | size_t size, int flags, bool check_lock); | 2015 | size_t size, int flags, bool check_lock); |
2015 | ssize_t ubifs_xattr_get(struct inode *host, const char *name, void *buf, | 2016 | ssize_t ubifs_xattr_get(struct inode *host, const char *name, void *buf, |
2016 | size_t size); | 2017 | size_t size); |
2018 | int ubifs_purge_xattrs(struct inode *host); | ||
2017 | 2019 | ||
2018 | #ifdef CONFIG_UBIFS_FS_XATTR | 2020 | #ifdef CONFIG_UBIFS_FS_XATTR |
2019 | void ubifs_evict_xattr_inode(struct ubifs_info *c, ino_t xattr_inum); | 2021 | void ubifs_evict_xattr_inode(struct ubifs_info *c, ino_t xattr_inum); |
diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c index f5ad1ede7990..acab3181ab35 100644 --- a/fs/ubifs/xattr.c +++ b/fs/ubifs/xattr.c | |||
@@ -61,12 +61,6 @@ | |||
61 | #include <linux/xattr.h> | 61 | #include <linux/xattr.h> |
62 | 62 | ||
63 | /* | 63 | /* |
64 | * Limit the number of extended attributes per inode so that the total size | ||
65 | * (@xattr_size) is guaranteeded to fit in an 'unsigned int'. | ||
66 | */ | ||
67 | #define MAX_XATTRS_PER_INODE 65535 | ||
68 | |||
69 | /* | ||
70 | * Extended attribute type constants. | 64 | * Extended attribute type constants. |
71 | * | 65 | * |
72 | * USER_XATTR: user extended attribute ("user.*") | 66 | * USER_XATTR: user extended attribute ("user.*") |
@@ -106,7 +100,7 @@ static int create_xattr(struct ubifs_info *c, struct inode *host, | |||
106 | .new_ino_d = ALIGN(size, 8), .dirtied_ino = 1, | 100 | .new_ino_d = ALIGN(size, 8), .dirtied_ino = 1, |
107 | .dirtied_ino_d = ALIGN(host_ui->data_len, 8) }; | 101 | .dirtied_ino_d = ALIGN(host_ui->data_len, 8) }; |
108 | 102 | ||
109 | if (host_ui->xattr_cnt >= MAX_XATTRS_PER_INODE) { | 103 | if (host_ui->xattr_cnt >= ubifs_xattr_max_cnt(c)) { |
110 | ubifs_err(c, "inode %lu already has too many xattrs (%d), cannot create more", | 104 | ubifs_err(c, "inode %lu already has too many xattrs (%d), cannot create more", |
111 | host->i_ino, host_ui->xattr_cnt); | 105 | host->i_ino, host_ui->xattr_cnt); |
112 | return -ENOSPC; | 106 | return -ENOSPC; |
@@ -507,6 +501,69 @@ out_cancel: | |||
507 | return err; | 501 | return err; |
508 | } | 502 | } |
509 | 503 | ||
504 | int ubifs_purge_xattrs(struct inode *host) | ||
505 | { | ||
506 | union ubifs_key key; | ||
507 | struct ubifs_info *c = host->i_sb->s_fs_info; | ||
508 | struct ubifs_dent_node *xent, *pxent = NULL; | ||
509 | struct inode *xino; | ||
510 | struct fscrypt_name nm = {0}; | ||
511 | int err; | ||
512 | |||
513 | if (ubifs_inode(host)->xattr_cnt < ubifs_xattr_max_cnt(c)) | ||
514 | return 0; | ||
515 | |||
516 | ubifs_warn(c, "inode %lu has too many xattrs, doing a non-atomic deletion", | ||
517 | host->i_ino); | ||
518 | |||
519 | lowest_xent_key(c, &key, host->i_ino); | ||
520 | while (1) { | ||
521 | xent = ubifs_tnc_next_ent(c, &key, &nm); | ||
522 | if (IS_ERR(xent)) { | ||
523 | err = PTR_ERR(xent); | ||
524 | break; | ||
525 | } | ||
526 | |||
527 | fname_name(&nm) = xent->name; | ||
528 | fname_len(&nm) = le16_to_cpu(xent->nlen); | ||
529 | |||
530 | xino = ubifs_iget(c->vfs_sb, xent->inum); | ||
531 | if (IS_ERR(xino)) { | ||
532 | err = PTR_ERR(xino); | ||
533 | ubifs_err(c, "dead directory entry '%s', error %d", | ||
534 | xent->name, err); | ||
535 | ubifs_ro_mode(c, err); | ||
536 | kfree(pxent); | ||
537 | return err; | ||
538 | } | ||
539 | |||
540 | ubifs_assert(c, ubifs_inode(xino)->xattr); | ||
541 | |||
542 | clear_nlink(xino); | ||
543 | err = remove_xattr(c, host, xino, &nm); | ||
544 | if (err) { | ||
545 | kfree(pxent); | ||
546 | iput(xino); | ||
547 | ubifs_err(c, "cannot remove xattr, error %d", err); | ||
548 | return err; | ||
549 | } | ||
550 | |||
551 | iput(xino); | ||
552 | |||
553 | kfree(pxent); | ||
554 | pxent = xent; | ||
555 | key_read(c, &xent->key, &key); | ||
556 | } | ||
557 | |||
558 | kfree(pxent); | ||
559 | if (err != -ENOENT) { | ||
560 | ubifs_err(c, "cannot find next direntry, error %d", err); | ||
561 | return err; | ||
562 | } | ||
563 | |||
564 | return 0; | ||
565 | } | ||
566 | |||
510 | /** | 567 | /** |
511 | * ubifs_evict_xattr_inode - Evict an xattr inode. | 568 | * ubifs_evict_xattr_inode - Evict an xattr inode. |
512 | * @c: UBIFS file-system description object | 569 | * @c: UBIFS file-system description object |