From patchwork Thu Feb 22 12:45:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yu Kuai X-Patchwork-Id: 13567263 Received: from dggsgout11.his.huawei.com (dggsgout11.his.huawei.com [45.249.212.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8833312DD96; Thu, 22 Feb 2024 12:51:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708606302; cv=none; b=oc2PhAXFz/d57bVSpg4LLdeNv3NOico24quDl2HwGPRh9MgOFNs7ft1OT7r3lKX34IgioQVIe7oJlPD1OlxSyH3pN2niwepupRtGavhd6rAnm4RH5UPpIE7DIZvh2VbHIJ4hSICUalHrwCGy5237Ued23GxxsVbkS/NjPFaiJio= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708606302; c=relaxed/simple; bh=CDJ6i5JmDiXPfcjTMJH4sUY4xqN+OM3kexIiCBQifQc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=rHUbDjaTPl26HOQmkyG3r7oRN4qyGrTBG9k9R2Z/phy0F17GgIkgtb1WgJSxiB1hLfZBW58cKCzGNsGK9oTf3Ispf3VcuRud1JlHjwLuP38qwMuJR/ptS2qI7I/hLeAbH4oQcQ44xt7o4kbQBU9XalRcVKUlFFTRzSuSsQJ6OPk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.216]) by dggsgout11.his.huawei.com (SkyGuard) with ESMTP id 4TgY1C0VZGz4f3m76; Thu, 22 Feb 2024 20:51:27 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.112]) by mail.maildlp.com (Postfix) with ESMTP id 3A7AD1A09FA; Thu, 22 Feb 2024 20:51:34 +0800 (CST) Received: from huaweicloud.com (unknown [10.175.104.67]) by APP1 (Coremail) with SMTP id cCh0CgBHGBFSQ9dlQ382Ew--.47909S8; Thu, 22 Feb 2024 20:51:34 +0800 (CST) From: Yu Kuai To: jack@suse.cz, hch@lst.de, brauner@kernel.org, axboe@kernel.dk Cc: linux-fsdevel@vger.kernel.org, linux-block@vger.kernel.org, yukuai3@huawei.com, yukuai1@huaweicloud.com, yi.zhang@huawei.com, yangerkun@huawei.com Subject: [RFC v4 linux-next 04/19] block: prevent direct access of bd_inode Date: Thu, 22 Feb 2024 20:45:40 +0800 Message-Id: <20240222124555.2049140-5-yukuai1@huaweicloud.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240222124555.2049140-1-yukuai1@huaweicloud.com> References: <20240222124555.2049140-1-yukuai1@huaweicloud.com> Precedence: bulk X-Mailing-List: linux-block@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-CM-TRANSID: cCh0CgBHGBFSQ9dlQ382Ew--.47909S8 X-Coremail-Antispam: 1UD129KBjvAXoWfJFWkJw1rCr17tF4kWF1DAwb_yoW8JrWDWo W5Jr1fXrs5JrW5G3yxGas7AFyjq39rAws5CFn8Zr1Dua1Fyw1jkw17Ga15AFyru3WrKr1S vryxJFyrJFW5CFs3n29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjp_UUUOb7AC8VAFwI0_Wr0E3s1l1xkIjI8I6I8E6xAIw20EY4v20xva j40_Wr0E3s1l1IIY67AEw4v_Jr0_Jr4l82xGYIkIc2x26280x7IE14v26r126s0DM28Irc Ia0xkI8VCY1x0267AKxVW5JVCq3wA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK021l 84ACjcxK6xIIjxv20xvE14v26ryj6F1UM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26F4j6r 4UJwA2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq 3wAS0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7 IYx2IY67AKxVWUJVWUGwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4U M4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwACI402YVCY1x02628vn2 kIc2xKxwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E 14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_Jw0_GFylIx kGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUJVWUCwCI42IY6xIIjxv20xvEc7CjxVAF wI0_Gr0_Cr1lIxAIcVCF04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26r4j6F 4UMIIF0xvEx4A2jsIEc7CjxVAFwI0_Gr1j6F4UJbIYCTnIWIevJa73UjIFyTuYvjfUOBTY UUUUU X-CM-SenderInfo: 51xn3trlr6x35dzhxuhorxvhhfrp/ From: Yu Kuai Add helpers to access bd_inode, prepare to remove the field 'bd_inode' after removing all the access from filesystems and drivers. Signed-off-by: Yu Kuai Reviewed-by: Jan Kara Reviewed-by: Christoph Hellwig --- block/bdev.c | 58 +++++++++++++++++++++++++++-------------- block/blk-zoned.c | 4 +-- block/blk.h | 2 ++ block/fops.c | 2 +- block/genhd.c | 9 ++++--- block/ioctl.c | 8 +++--- block/partitions/core.c | 8 +++--- 7 files changed, 56 insertions(+), 35 deletions(-) diff --git a/block/bdev.c b/block/bdev.c index e493d5c72edb..60a1479eae83 100644 --- a/block/bdev.c +++ b/block/bdev.c @@ -43,6 +43,21 @@ static inline struct bdev_inode *BDEV_I(struct inode *inode) return container_of(inode, struct bdev_inode, vfs_inode); } +static inline struct bdev_inode *BDEV_B(struct block_device *bdev) +{ + return container_of(bdev, struct bdev_inode, bdev); +} + +struct inode *bdev_inode(struct block_device *bdev) +{ + return &BDEV_B(bdev)->vfs_inode; +} + +struct address_space *bdev_mapping(struct block_device *bdev) +{ + return BDEV_B(bdev)->vfs_inode.i_mapping; +} + struct block_device *I_BDEV(struct inode *inode) { return &BDEV_I(inode)->bdev; @@ -57,7 +72,7 @@ EXPORT_SYMBOL(file_bdev); static void bdev_write_inode(struct block_device *bdev) { - struct inode *inode = bdev->bd_inode; + struct inode *inode = bdev_inode(bdev); int ret; spin_lock(&inode->i_lock); @@ -76,7 +91,7 @@ static void bdev_write_inode(struct block_device *bdev) /* Kill _all_ buffers and pagecache , dirty or not.. */ static void kill_bdev(struct block_device *bdev) { - struct address_space *mapping = bdev->bd_inode->i_mapping; + struct address_space *mapping = bdev_mapping(bdev); if (mapping_empty(mapping)) return; @@ -88,7 +103,7 @@ static void kill_bdev(struct block_device *bdev) /* Invalidate clean unused buffers and pagecache. */ void invalidate_bdev(struct block_device *bdev) { - struct address_space *mapping = bdev->bd_inode->i_mapping; + struct address_space *mapping = bdev_mapping(bdev); if (mapping->nrpages) { invalidate_bh_lrus(); @@ -116,7 +131,7 @@ int truncate_bdev_range(struct block_device *bdev, blk_mode_t mode, goto invalidate; } - truncate_inode_pages_range(bdev->bd_inode->i_mapping, lstart, lend); + truncate_inode_pages_range(bdev_mapping(bdev), lstart, lend); if (!(mode & BLK_OPEN_EXCL)) bd_abort_claiming(bdev, truncate_bdev_range); return 0; @@ -126,7 +141,7 @@ int truncate_bdev_range(struct block_device *bdev, blk_mode_t mode, * Someone else has handle exclusively open. Try invalidating instead. * The 'end' argument is inclusive so the rounding is safe. */ - return invalidate_inode_pages2_range(bdev->bd_inode->i_mapping, + return invalidate_inode_pages2_range(bdev_mapping(bdev), lstart >> PAGE_SHIFT, lend >> PAGE_SHIFT); } @@ -134,14 +149,14 @@ int truncate_bdev_range(struct block_device *bdev, blk_mode_t mode, static void set_init_blocksize(struct block_device *bdev) { unsigned int bsize = bdev_logical_block_size(bdev); - loff_t size = i_size_read(bdev->bd_inode); + loff_t size = i_size_read(bdev_inode(bdev)); while (bsize < PAGE_SIZE) { if (size & bsize) break; bsize <<= 1; } - bdev->bd_inode->i_blkbits = blksize_bits(bsize); + bdev_inode(bdev)->i_blkbits = blksize_bits(bsize); } int set_blocksize(struct block_device *bdev, int size) @@ -155,9 +170,9 @@ int set_blocksize(struct block_device *bdev, int size) return -EINVAL; /* Don't change the size if it is same as current */ - if (bdev->bd_inode->i_blkbits != blksize_bits(size)) { + if (bdev_inode(bdev)->i_blkbits != blksize_bits(size)) { sync_blockdev(bdev); - bdev->bd_inode->i_blkbits = blksize_bits(size); + bdev_inode(bdev)->i_blkbits = blksize_bits(size); kill_bdev(bdev); } return 0; @@ -196,7 +211,7 @@ int sync_blockdev(struct block_device *bdev) { if (!bdev) return 0; - return filemap_write_and_wait(bdev->bd_inode->i_mapping); + return filemap_write_and_wait(bdev_mapping(bdev)); } EXPORT_SYMBOL(sync_blockdev); @@ -415,19 +430,22 @@ struct block_device *bdev_alloc(struct gendisk *disk, u8 partno) void bdev_set_nr_sectors(struct block_device *bdev, sector_t sectors) { spin_lock(&bdev->bd_size_lock); - i_size_write(bdev->bd_inode, (loff_t)sectors << SECTOR_SHIFT); + i_size_write(bdev_inode(bdev), (loff_t)sectors << SECTOR_SHIFT); bdev->bd_nr_sectors = sectors; spin_unlock(&bdev->bd_size_lock); } void bdev_add(struct block_device *bdev, dev_t dev) { + struct inode *inode; + if (bdev_stable_writes(bdev)) - mapping_set_stable_writes(bdev->bd_inode->i_mapping); + mapping_set_stable_writes(bdev_mapping(bdev)); bdev->bd_dev = dev; - bdev->bd_inode->i_rdev = dev; - bdev->bd_inode->i_ino = dev; - insert_inode_hash(bdev->bd_inode); + inode = bdev_inode(bdev); + inode->i_rdev = dev; + inode->i_ino = dev; + insert_inode_hash(inode); } long nr_blockdev_pages(void) @@ -885,7 +903,7 @@ int bdev_open(struct block_device *bdev, blk_mode_t mode, void *holder, bdev_file->f_mode |= FMODE_BUF_RASYNC | FMODE_CAN_ODIRECT; if (bdev_nowait(bdev)) bdev_file->f_mode |= FMODE_NOWAIT; - bdev_file->f_mapping = bdev->bd_inode->i_mapping; + bdev_file->f_mapping = bdev_mapping(bdev); bdev_file->f_wb_err = filemap_sample_wb_err(bdev_file->f_mapping); bdev_file->private_data = holder; @@ -947,13 +965,13 @@ struct file *bdev_file_open_by_dev(dev_t dev, blk_mode_t mode, void *holder, return ERR_PTR(-ENXIO); flags = blk_to_file_flags(mode); - bdev_file = alloc_file_pseudo_noaccount(bdev->bd_inode, + bdev_file = alloc_file_pseudo_noaccount(bdev_inode(bdev), blockdev_mnt, "", flags | O_LARGEFILE, &def_blk_fops); if (IS_ERR(bdev_file)) { blkdev_put_no_open(bdev); return bdev_file; } - ihold(bdev->bd_inode); + ihold(bdev_inode(bdev)); ret = bdev_open(bdev, mode, holder, hops, bdev_file); if (ret) { @@ -1183,13 +1201,13 @@ void bdev_statx_dioalign(struct inode *inode, struct kstat *stat) bool disk_live(struct gendisk *disk) { - return !inode_unhashed(disk->part0->bd_inode); + return !inode_unhashed(bdev_inode(disk->part0)); } EXPORT_SYMBOL_GPL(disk_live); unsigned int block_size(struct block_device *bdev) { - return 1 << bdev->bd_inode->i_blkbits; + return 1 << bdev_inode(bdev)->i_blkbits; } EXPORT_SYMBOL_GPL(block_size); diff --git a/block/blk-zoned.c b/block/blk-zoned.c index d4f4f8325eff..ab022d990703 100644 --- a/block/blk-zoned.c +++ b/block/blk-zoned.c @@ -399,7 +399,7 @@ int blkdev_zone_mgmt_ioctl(struct block_device *bdev, blk_mode_t mode, op = REQ_OP_ZONE_RESET; /* Invalidate the page cache, including dirty pages. */ - filemap_invalidate_lock(bdev->bd_inode->i_mapping); + filemap_invalidate_lock(bdev_mapping(bdev)); ret = blkdev_truncate_zone_range(bdev, mode, &zrange); if (ret) goto fail; @@ -421,7 +421,7 @@ int blkdev_zone_mgmt_ioctl(struct block_device *bdev, blk_mode_t mode, fail: if (cmd == BLKRESETZONE) - filemap_invalidate_unlock(bdev->bd_inode->i_mapping); + filemap_invalidate_unlock(bdev_mapping(bdev)); return ret; } diff --git a/block/blk.h b/block/blk.h index 72bc8d27cc70..b612538588cb 100644 --- a/block/blk.h +++ b/block/blk.h @@ -414,6 +414,8 @@ static inline int blkdev_zone_mgmt_ioctl(struct block_device *bdev, } #endif /* CONFIG_BLK_DEV_ZONED */ +struct inode *bdev_inode(struct block_device *bdev); +struct address_space *bdev_mapping(struct block_device *bdev); struct block_device *bdev_alloc(struct gendisk *disk, u8 partno); void bdev_add(struct block_device *bdev, dev_t dev); diff --git a/block/fops.c b/block/fops.c index f4dcb9dd148d..1fcbdb131a8f 100644 --- a/block/fops.c +++ b/block/fops.c @@ -666,7 +666,7 @@ static ssize_t blkdev_write_iter(struct kiocb *iocb, struct iov_iter *from) { struct file *file = iocb->ki_filp; struct block_device *bdev = I_BDEV(file->f_mapping->host); - struct inode *bd_inode = bdev->bd_inode; + struct inode *bd_inode = bdev_inode(bdev); loff_t size = bdev_nr_bytes(bdev); size_t shorted = 0; ssize_t ret; diff --git a/block/genhd.c b/block/genhd.c index 2f9834bdd14b..4f0f66b4798f 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -656,7 +656,7 @@ void del_gendisk(struct gendisk *disk) */ mutex_lock(&disk->open_mutex); xa_for_each(&disk->part_tbl, idx, part) - remove_inode_hash(part->bd_inode); + remove_inode_hash(bdev_inode(part)); mutex_unlock(&disk->open_mutex); /* @@ -745,7 +745,7 @@ void invalidate_disk(struct gendisk *disk) struct block_device *bdev = disk->part0; invalidate_bdev(bdev); - bdev->bd_inode->i_mapping->wb_err = 0; + bdev_mapping(bdev)->wb_err = 0; set_capacity(disk, 0); } EXPORT_SYMBOL(invalidate_disk); @@ -1191,7 +1191,8 @@ static void disk_release(struct device *dev) if (test_bit(GD_ADDED, &disk->state) && disk->fops->free_disk) disk->fops->free_disk(disk); - iput(disk->part0->bd_inode); /* frees the disk */ + /* frees the disk */ + iput(bdev_inode(disk->part0)); } static int block_uevent(const struct device *dev, struct kobj_uevent_env *env) @@ -1381,7 +1382,7 @@ struct gendisk *__alloc_disk_node(struct request_queue *q, int node_id, out_destroy_part_tbl: xa_destroy(&disk->part_tbl); disk->part0->bd_disk = NULL; - iput(disk->part0->bd_inode); + iput(bdev_inode(disk->part0)); out_free_bdi: bdi_put(disk->bdi); out_free_bioset: diff --git a/block/ioctl.c b/block/ioctl.c index 4c8aebee595f..cb5b378cff38 100644 --- a/block/ioctl.c +++ b/block/ioctl.c @@ -90,7 +90,7 @@ static int blk_ioctl_discard(struct block_device *bdev, blk_mode_t mode, { uint64_t range[2]; uint64_t start, len; - struct inode *inode = bdev->bd_inode; + struct inode *inode = bdev_inode(bdev); int err; if (!(mode & BLK_OPEN_WRITE)) @@ -144,12 +144,12 @@ static int blk_ioctl_secure_erase(struct block_device *bdev, blk_mode_t mode, if (start + len > bdev_nr_bytes(bdev)) return -EINVAL; - filemap_invalidate_lock(bdev->bd_inode->i_mapping); + filemap_invalidate_lock(bdev_mapping(bdev)); err = truncate_bdev_range(bdev, mode, start, start + len - 1); if (!err) err = blkdev_issue_secure_erase(bdev, start >> 9, len >> 9, GFP_KERNEL); - filemap_invalidate_unlock(bdev->bd_inode->i_mapping); + filemap_invalidate_unlock(bdev_mapping(bdev)); return err; } @@ -159,7 +159,7 @@ static int blk_ioctl_zeroout(struct block_device *bdev, blk_mode_t mode, { uint64_t range[2]; uint64_t start, end, len; - struct inode *inode = bdev->bd_inode; + struct inode *inode = bdev_inode(bdev); int err; if (!(mode & BLK_OPEN_WRITE)) diff --git a/block/partitions/core.c b/block/partitions/core.c index 5f5ed5c75f04..6e91a4660588 100644 --- a/block/partitions/core.c +++ b/block/partitions/core.c @@ -243,7 +243,7 @@ static const struct attribute_group *part_attr_groups[] = { static void part_release(struct device *dev) { put_disk(dev_to_bdev(dev)->bd_disk); - iput(dev_to_bdev(dev)->bd_inode); + iput(bdev_inode(dev_to_bdev(dev))); } static int part_uevent(const struct device *dev, struct kobj_uevent_env *env) @@ -480,7 +480,7 @@ int bdev_del_partition(struct gendisk *disk, int partno) * Just delete the partition and invalidate it. */ - remove_inode_hash(part->bd_inode); + remove_inode_hash(bdev_inode(part)); invalidate_bdev(part); drop_partition(part); ret = 0; @@ -666,7 +666,7 @@ int bdev_disk_changed(struct gendisk *disk, bool invalidate) * it cannot be looked up any more even when openers * still hold references. */ - remove_inode_hash(part->bd_inode); + remove_inode_hash(bdev_inode(part)); /* * If @disk->open_partitions isn't elevated but there's @@ -715,7 +715,7 @@ EXPORT_SYMBOL_GPL(bdev_disk_changed); void *read_part_sector(struct parsed_partitions *state, sector_t n, Sector *p) { - struct address_space *mapping = state->disk->part0->bd_inode->i_mapping; + struct address_space *mapping = bdev_mapping(state->disk->part0); struct folio *folio; if (n >= get_capacity(state->disk)) {