From: Jan Kara <jack@suse.cz>
To: Yu Kuai <yukuai1@huaweicloud.com>
Cc: jack@suse.cz, hch@lst.de, brauner@kernel.org, axboe@kernel.dk,
linux-fsdevel@vger.kernel.org, linux-block@vger.kernel.org,
yukuai3@huawei.com, yi.zhang@huawei.com, yangerkun@huawei.com
Subject: Re: [RFC v4 linux-next 04/19] block: prevent direct access of bd_inode
Date: Fri, 15 Mar 2024 15:44:48 +0100 [thread overview]
Message-ID: <20240315144448.lxfiebfs2cxckrjc@quack3> (raw)
In-Reply-To: <20240222124555.2049140-5-yukuai1@huaweicloud.com>
On Thu 22-02-24 20:45:40, Yu Kuai wrote:
> From: Yu Kuai <yukuai3@huawei.com>
>
> 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 <yukuai3@huawei.com>
Looks good. Feel free to add:
Reviewed-by: Jan Kara <jack@suse.cz>
Honza
> ---
> 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)) {
> --
> 2.39.2
>
--
Jan Kara <jack@suse.com>
SUSE Labs, CR
next prev parent reply other threads:[~2024-03-15 14:44 UTC|newest]
Thread overview: 97+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-02-22 12:45 [RFC v4 linux-next 00/19] fs & block: remove bdev->bd_inode Yu Kuai
2024-02-22 12:45 ` [RFC v4 linux-next 01/19] block: move two helpers into bdev.c Yu Kuai
2024-03-15 14:31 ` Jan Kara
2024-03-17 21:19 ` Christoph Hellwig
2024-02-22 12:45 ` [RFC v4 linux-next 02/19] block: remove sync_blockdev_nowait() Yu Kuai
2024-03-15 14:34 ` Jan Kara
2024-03-17 21:19 ` Christoph Hellwig
2024-02-22 12:45 ` [RFC v4 linux-next 03/19] block: remove sync_blockdev_range() Yu Kuai
2024-03-15 14:37 ` Jan Kara
2024-03-17 21:21 ` Christoph Hellwig
2024-02-22 12:45 ` [RFC v4 linux-next 04/19] block: prevent direct access of bd_inode Yu Kuai
2024-03-15 14:44 ` Jan Kara [this message]
2024-03-17 21:23 ` Christoph Hellwig
2024-03-22 5:44 ` Al Viro
2024-02-22 12:45 ` [RFC v4 linux-next 05/19] bcachefs: remove dead function bdev_sectors() Yu Kuai
2024-03-15 14:42 ` Jan Kara
2024-03-17 21:23 ` Christoph Hellwig
2024-02-22 12:45 ` [RFC v4 linux-next 06/19] cramfs: prevent direct access of bd_inode Yu Kuai
2024-03-15 14:44 ` Jan Kara
2024-03-17 21:23 ` Christoph Hellwig
2024-02-22 12:45 ` [RFC v4 linux-next 07/19] erofs: " Yu Kuai
2024-03-15 14:45 ` Jan Kara
2024-03-17 21:24 ` Christoph Hellwig
2024-03-18 2:39 ` Gao Xiang
2024-02-22 12:45 ` [RFC v4 linux-next 08/19] nilfs2: " Yu Kuai
2024-03-15 14:49 ` Jan Kara
2024-03-17 21:24 ` Christoph Hellwig
2024-02-22 12:45 ` [RFC v4 linux-next 09/19] gfs2: " Yu Kuai
2024-03-15 14:54 ` Jan Kara
2024-03-17 21:24 ` Christoph Hellwig
2024-02-22 12:45 ` [RFC v4 linux-next 10/19] s390/dasd: use bdev api in dasd_format() Yu Kuai
2024-03-15 14:55 ` Jan Kara
2024-03-17 21:25 ` Christoph Hellwig
2024-02-22 12:45 ` [RFC v4 linux-next 11/19] btrfs: prevent direct access of bd_inode Yu Kuai
2024-03-15 15:09 ` Jan Kara
2024-03-17 21:25 ` Christoph Hellwig
2024-02-22 12:45 ` [RFC v4 linux-next 12/19] ext4: remove block_device_ejected() Yu Kuai
2024-02-22 12:45 ` [RFC v4 linux-next 13/19] ext4: prevent direct access of bd_inode Yu Kuai
2024-03-15 14:58 ` Jan Kara
2024-03-17 21:25 ` Christoph Hellwig
2024-02-22 12:45 ` [RFC v4 linux-next 14/19] jbd2: " Yu Kuai
2024-03-15 15:06 ` Jan Kara
2024-03-17 21:26 ` Christoph Hellwig
2024-03-18 1:10 ` Yu Kuai
2024-02-22 12:45 ` [RFC v4 linux-next 15/19] bcache: " Yu Kuai
2024-03-15 15:11 ` Jan Kara
2024-03-17 21:34 ` Christoph Hellwig
2024-02-22 12:45 ` [RFC v4 linux-next 16/19] block2mtd: " Yu Kuai
2024-03-15 15:12 ` Jan Kara
2024-03-17 21:36 ` Christoph Hellwig
2024-02-22 12:45 ` [RFC v4 linux-next 17/19] dm-vdo: " Yu Kuai
2024-02-28 13:41 ` Christoph Hellwig
2024-03-18 9:11 ` Jan Kara
2024-03-18 9:19 ` Jan Kara
2024-03-18 13:38 ` Yu Kuai
2024-03-19 2:00 ` Matthew Sakai
2024-02-22 12:45 ` [RFC v4 linux-next 18/19] scsi: factor out a helper bdev_read_folio() from scsi_bios_ptable() Yu Kuai
2024-03-17 21:36 ` Christoph Hellwig
2024-03-18 1:12 ` Yu Kuai
2024-03-18 9:22 ` Jan Kara
2024-02-22 12:45 ` [RFC v4 linux-next 19/19] fs & block: remove bdev->bd_inode Yu Kuai
2024-03-17 21:38 ` Christoph Hellwig
2024-03-18 1:26 ` Yu Kuai
2024-03-18 1:32 ` Christoph Hellwig
2024-03-18 1:51 ` Yu Kuai
2024-03-18 7:19 ` Yu Kuai
2024-03-18 10:07 ` Christian Brauner
2024-03-18 10:29 ` Christian Brauner
2024-03-18 10:46 ` Christian Brauner
2024-03-18 11:57 ` Yu Kuai
2024-03-18 23:35 ` Christoph Hellwig
2024-03-18 23:22 ` Christoph Hellwig
2024-03-19 8:26 ` Yu Kuai
2024-03-21 11:27 ` Jan Kara
2024-03-21 12:15 ` Yu Kuai
2024-03-22 6:37 ` Al Viro
2024-03-22 6:39 ` Al Viro
2024-03-22 6:52 ` Yu Kuai
2024-03-22 12:57 ` Jan Kara
2024-03-22 13:57 ` Christian Brauner
2024-03-22 15:43 ` Al Viro
2024-03-22 16:16 ` Al Viro
2024-03-22 6:33 ` Al Viro
2024-03-22 7:09 ` Yu Kuai
2024-03-22 16:01 ` Al Viro
2024-03-22 13:10 ` Jan Kara
2024-03-22 14:57 ` Al Viro
2024-03-25 1:06 ` Christoph Hellwig
2024-02-28 13:42 ` [RFC v4 linux-next 00/19] " Christoph Hellwig
2024-03-15 12:08 ` Yu Kuai
2024-03-15 13:54 ` Christian Brauner
2024-03-16 2:49 ` Yu Kuai
2024-03-18 9:39 ` Christian Brauner
2024-03-19 1:18 ` Yu Kuai
2024-03-19 1:43 ` Yu Kuai
2024-03-19 2:13 ` Matthew Sakai
2024-03-19 2:27 ` Yu Kuai
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240315144448.lxfiebfs2cxckrjc@quack3 \
--to=jack@suse.cz \
--cc=axboe@kernel.dk \
--cc=brauner@kernel.org \
--cc=hch@lst.de \
--cc=linux-block@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=yangerkun@huawei.com \
--cc=yi.zhang@huawei.com \
--cc=yukuai1@huaweicloud.com \
--cc=yukuai3@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).