.. | .. |
---|
66 | 66 | * Fast Commit Ineligibility |
---|
67 | 67 | * ------------------------- |
---|
68 | 68 | * 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 |
---|
70 | 70 | * two following functions: |
---|
71 | 71 | * |
---|
72 | 72 | * - ext4_fc_mark_ineligible(): This makes next fast commit operation to fall |
---|
.. | .. |
---|
371 | 371 | struct __track_dentry_update_args *dentry_update = |
---|
372 | 372 | (struct __track_dentry_update_args *)arg; |
---|
373 | 373 | 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); |
---|
375 | 377 | |
---|
376 | 378 | 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 | + |
---|
377 | 386 | node = kmem_cache_alloc(ext4_fc_dentry_cachep, GFP_NOFS); |
---|
378 | 387 | if (!node) { |
---|
379 | | - ext4_fc_mark_ineligible(inode->i_sb, EXT4_FC_REASON_NOMEM); |
---|
| 388 | + ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_NOMEM); |
---|
380 | 389 | mutex_lock(&ei->i_fc_lock); |
---|
381 | 390 | return -ENOMEM; |
---|
382 | 391 | } |
---|
383 | 392 | |
---|
384 | 393 | node->fcd_op = dentry_update->op; |
---|
385 | | - node->fcd_parent = dentry->d_parent->d_inode->i_ino; |
---|
| 394 | + node->fcd_parent = dir->i_ino; |
---|
386 | 395 | node->fcd_ino = inode->i_ino; |
---|
387 | 396 | if (dentry->d_name.len > DNAME_INLINE_LEN) { |
---|
388 | 397 | node->fcd_name.name = kmalloc(dentry->d_name.len, GFP_NOFS); |
---|
389 | 398 | if (!node->fcd_name.name) { |
---|
390 | 399 | 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); |
---|
393 | 401 | mutex_lock(&ei->i_fc_lock); |
---|
394 | 402 | return -ENOMEM; |
---|
395 | 403 | } |
---|
.. | .. |
---|
628 | 636 | *crc = ext4_chksum(sbi, *crc, tl, sizeof(*tl)); |
---|
629 | 637 | if (pad_len > 0) |
---|
630 | 638 | 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 | + |
---|
631 | 642 | ext4_fc_submit_bh(sb); |
---|
632 | 643 | |
---|
633 | 644 | ret = jbd2_fc_get_buf(EXT4_SB(sb)->s_journal, &bh); |
---|
.. | .. |
---|
684 | 695 | dst += sizeof(tail.fc_tid); |
---|
685 | 696 | tail.fc_crc = cpu_to_le32(crc); |
---|
686 | 697 | 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. */ |
---|
687 | 700 | |
---|
688 | 701 | ext4_fc_submit_bh(sb); |
---|
689 | 702 | |
---|
.. | .. |
---|
1287 | 1300 | return 0; |
---|
1288 | 1301 | } |
---|
1289 | 1302 | |
---|
1290 | | - ret = __ext4_unlink(NULL, old_parent, &entry, inode); |
---|
| 1303 | + ret = __ext4_unlink(old_parent, &entry, inode, NULL); |
---|
1291 | 1304 | /* -ENOENT ok coz it might not exist anymore. */ |
---|
1292 | 1305 | if (ret == -ENOENT) |
---|
1293 | 1306 | ret = 0; |
---|
.. | .. |
---|
2137 | 2150 | journal->j_fc_cleanup_callback = ext4_fc_cleanup; |
---|
2138 | 2151 | } |
---|
2139 | 2152 | |
---|
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", |
---|
2151 | 2164 | }; |
---|
2152 | 2165 | |
---|
2153 | 2166 | int ext4_fc_info_show(struct seq_file *seq, void *v) |
---|