Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ext4: perform dax_device lookup at mount

The ->iomap_begin() operation is a hot path, so cache the
fs_dax_get_by_host() result at mount time to avoid the incurring the
hash lookup overhead on a per-i/o basis.

Cc: "Theodore Ts'o" <tytso@mit.edu>
Cc: Andreas Dilger <adilger.kernel@dilger.ca>
Reviewed-by: Jan Kara <jack@suse.cz>
Reported-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>

+8 -8
+1
fs/ext4/ext4.h
··· 1528 1528 1529 1529 /* Barrier between changing inodes' journal flags and writepages ops. */ 1530 1530 struct percpu_rw_semaphore s_journal_flag_rwsem; 1531 + struct dax_device *s_daxdev; 1531 1532 }; 1532 1533 1533 1534 static inline struct ext4_sb_info *EXT4_SB(struct super_block *sb)
+3 -8
fs/ext4/inode.c
··· 3404 3404 static int ext4_iomap_begin(struct inode *inode, loff_t offset, loff_t length, 3405 3405 unsigned flags, struct iomap *iomap) 3406 3406 { 3407 - struct block_device *bdev; 3407 + struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); 3408 3408 unsigned int blkbits = inode->i_blkbits; 3409 3409 unsigned long first_block = offset >> blkbits; 3410 3410 unsigned long last_block = (offset + length - 1) >> blkbits; ··· 3473 3473 } 3474 3474 3475 3475 iomap->flags = 0; 3476 - bdev = inode->i_sb->s_bdev; 3477 - iomap->bdev = bdev; 3478 - if (blk_queue_dax(bdev->bd_queue)) 3479 - iomap->dax_dev = fs_dax_get_by_host(bdev->bd_disk->disk_name); 3480 - else 3481 - iomap->dax_dev = NULL; 3476 + iomap->bdev = inode->i_sb->s_bdev; 3477 + iomap->dax_dev = sbi->s_daxdev; 3482 3478 iomap->offset = first_block << blkbits; 3483 3479 3484 3480 if (ret == 0) { ··· 3507 3511 int blkbits = inode->i_blkbits; 3508 3512 bool truncate = false; 3509 3513 3510 - fs_put_dax(iomap->dax_dev); 3511 3514 if (!(flags & IOMAP_WRITE) || (flags & IOMAP_FAULT)) 3512 3515 return 0; 3513 3516
+4
fs/ext4/super.c
··· 951 951 if (sbi->s_chksum_driver) 952 952 crypto_free_shash(sbi->s_chksum_driver); 953 953 kfree(sbi->s_blockgroup_lock); 954 + fs_put_dax(sbi->s_daxdev); 954 955 kfree(sbi); 955 956 } 956 957 ··· 3378 3377 3379 3378 static int ext4_fill_super(struct super_block *sb, void *data, int silent) 3380 3379 { 3380 + struct dax_device *dax_dev = fs_dax_get_by_bdev(sb->s_bdev); 3381 3381 char *orig_data = kstrdup(data, GFP_KERNEL); 3382 3382 struct buffer_head *bh; 3383 3383 struct ext4_super_block *es = NULL; ··· 3401 3399 unsigned int journal_ioprio = DEFAULT_JOURNAL_IOPRIO; 3402 3400 ext4_group_t first_not_zeroed; 3403 3401 3402 + sbi->s_daxdev = dax_dev; 3404 3403 if ((data && !orig_data) || !sbi) 3405 3404 goto out_free_base; 3406 3405 ··· 4381 4378 out_free_base: 4382 4379 kfree(sbi); 4383 4380 kfree(orig_data); 4381 + fs_put_dax(dax_dev); 4384 4382 return err ? err : ret; 4385 4383 } 4386 4384