| .. | .. | 
|---|
| 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) | 
|---|