hc
2024-05-14 bedbef8ad3e75a304af6361af235302bcc61d06b
kernel/fs/ext4/fast_commit.c
....@@ -66,7 +66,7 @@
6666 * Fast Commit Ineligibility
6767 * -------------------------
6868 * Not all operations are supported by fast commits today (e.g extended
69
- * attributes). Fast commit ineligiblity is marked by calling one of the
69
+ * attributes). Fast commit ineligibility is marked by calling one of the
7070 * two following functions:
7171 *
7272 * - ext4_fc_mark_ineligible(): This makes next fast commit operation to fall
....@@ -371,25 +371,33 @@
371371 struct __track_dentry_update_args *dentry_update =
372372 (struct __track_dentry_update_args *)arg;
373373 struct dentry *dentry = dentry_update->dentry;
374
- struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
374
+ struct inode *dir = dentry->d_parent->d_inode;
375
+ struct super_block *sb = inode->i_sb;
376
+ struct ext4_sb_info *sbi = EXT4_SB(sb);
375377
376378 mutex_unlock(&ei->i_fc_lock);
379
+
380
+ if (IS_ENCRYPTED(dir)) {
381
+ ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_ENCRYPTED_FILENAME);
382
+ mutex_lock(&ei->i_fc_lock);
383
+ return -EOPNOTSUPP;
384
+ }
385
+
377386 node = kmem_cache_alloc(ext4_fc_dentry_cachep, GFP_NOFS);
378387 if (!node) {
379
- ext4_fc_mark_ineligible(inode->i_sb, EXT4_FC_REASON_NOMEM);
388
+ ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_NOMEM);
380389 mutex_lock(&ei->i_fc_lock);
381390 return -ENOMEM;
382391 }
383392
384393 node->fcd_op = dentry_update->op;
385
- node->fcd_parent = dentry->d_parent->d_inode->i_ino;
394
+ node->fcd_parent = dir->i_ino;
386395 node->fcd_ino = inode->i_ino;
387396 if (dentry->d_name.len > DNAME_INLINE_LEN) {
388397 node->fcd_name.name = kmalloc(dentry->d_name.len, GFP_NOFS);
389398 if (!node->fcd_name.name) {
390399 kmem_cache_free(ext4_fc_dentry_cachep, node);
391
- ext4_fc_mark_ineligible(inode->i_sb,
392
- EXT4_FC_REASON_NOMEM);
400
+ ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_NOMEM);
393401 mutex_lock(&ei->i_fc_lock);
394402 return -ENOMEM;
395403 }
....@@ -628,6 +636,9 @@
628636 *crc = ext4_chksum(sbi, *crc, tl, sizeof(*tl));
629637 if (pad_len > 0)
630638 ext4_fc_memzero(sb, tl + 1, pad_len, crc);
639
+ /* Don't leak uninitialized memory in the unused last byte. */
640
+ *((u8 *)(tl + 1) + pad_len) = 0;
641
+
631642 ext4_fc_submit_bh(sb);
632643
633644 ret = jbd2_fc_get_buf(EXT4_SB(sb)->s_journal, &bh);
....@@ -684,6 +695,8 @@
684695 dst += sizeof(tail.fc_tid);
685696 tail.fc_crc = cpu_to_le32(crc);
686697 ext4_fc_memcpy(sb, dst, &tail.fc_crc, sizeof(tail.fc_crc), NULL);
698
+ dst += sizeof(tail.fc_crc);
699
+ memset(dst, 0, bsize - off); /* Don't leak uninitialized memory. */
687700
688701 ext4_fc_submit_bh(sb);
689702
....@@ -1287,7 +1300,7 @@
12871300 return 0;
12881301 }
12891302
1290
- ret = __ext4_unlink(NULL, old_parent, &entry, inode);
1303
+ ret = __ext4_unlink(old_parent, &entry, inode, NULL);
12911304 /* -ENOENT ok coz it might not exist anymore. */
12921305 if (ret == -ENOENT)
12931306 ret = 0;
....@@ -2137,17 +2150,17 @@
21372150 journal->j_fc_cleanup_callback = ext4_fc_cleanup;
21382151 }
21392152
2140
-static const char *fc_ineligible_reasons[] = {
2141
- "Extended attributes changed",
2142
- "Cross rename",
2143
- "Journal flag changed",
2144
- "Insufficient memory",
2145
- "Swap boot",
2146
- "Resize",
2147
- "Dir renamed",
2148
- "Falloc range op",
2149
- "Data journalling",
2150
- "FC Commit Failed"
2153
+static const char * const fc_ineligible_reasons[] = {
2154
+ [EXT4_FC_REASON_XATTR] = "Extended attributes changed",
2155
+ [EXT4_FC_REASON_CROSS_RENAME] = "Cross rename",
2156
+ [EXT4_FC_REASON_JOURNAL_FLAG_CHANGE] = "Journal flag changed",
2157
+ [EXT4_FC_REASON_NOMEM] = "Insufficient memory",
2158
+ [EXT4_FC_REASON_SWAP_BOOT] = "Swap boot",
2159
+ [EXT4_FC_REASON_RESIZE] = "Resize",
2160
+ [EXT4_FC_REASON_RENAME_DIR] = "Dir renamed",
2161
+ [EXT4_FC_REASON_FALLOC_RANGE] = "Falloc range op",
2162
+ [EXT4_FC_REASON_INODE_JOURNAL_DATA] = "Data journalling",
2163
+ [EXT4_FC_REASON_ENCRYPTED_FILENAME] = "Encrypted filename",
21512164 };
21522165
21532166 int ext4_fc_info_show(struct seq_file *seq, void *v)