From: Matthew Auld <matthew.auld@intel.com>
To: intel-gfx@lists.freedesktop.org
Cc: "Joonas Lahtinen" <joonas.lahtinen@linux.intel.com>,
"Chris Wilson" <chris@chris-wilson.co.uk>,
"Daniel Vetter" <daniel.vetter@intel.com>,
"Dave Hansen" <dave.hansen@intel.com>,
"Kirill A . Shutemov" <kirill@shutemov.name>,
"Andrew Morton" <akpm@linux-foundation.org>,
"Hugh Dickins" <hughd@google.com>,
"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
"Arve Hjønnevåg" <arve@android.com>,
"Riley Andrews" <riandrews@android.com>,
dri-devel@lists.freedesktop.org, linux-mm@kvack.org,
devel@driverdev.osuosl.org
Subject: [PATCH 01/22] mm/shmem: support passing mnt to shmem_file_setup
Date: Mon, 25 Sep 2017 19:47:16 +0100 [thread overview]
Message-ID: <20170925184737.8807-2-matthew.auld@intel.com> (raw)
In-Reply-To: <20170925184737.8807-1-matthew.auld@intel.com>
We are planning to use our own tmpfs mnt in i915 in place of the
shm_mnt such that we can control the mount options, in particular
huge=, which we require to support huge-gtt-pages. So rather than roll
our own version of __shmem_file_setup, it would be preferred if we could
just give shmem our mnt, and let it do the rest.
Based on the patch: https://patchwork.freedesktop.org/patch/178433/
Suggested-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Kirill A. Shutemov <kirill@shutemov.name>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Hugh Dickins <hughd@google.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: "Arve Hjønnevåg" <arve@android.com>
Cc: Riley Andrews <riandrews@android.com>
Cc: dri-devel@lists.freedesktop.org
Cc: linux-mm@kvack.org
Cc: devel@driverdev.osuosl.org
---
drivers/gpu/drm/drm_gem.c | 2 +-
drivers/gpu/drm/ttm/ttm_tt.c | 2 +-
drivers/staging/android/ashmem.c | 3 ++-
include/linux/shmem_fs.h | 4 +++-
mm/shmem.c | 24 ++++++++++++++----------
5 files changed, 21 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 7199bba68c37..12e5fdc90a6f 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -138,7 +138,7 @@ int drm_gem_object_init(struct drm_device *dev,
drm_gem_private_object_init(dev, obj, size);
- filp = shmem_file_setup("drm mm object", size, VM_NORESERVE);
+ filp = shmem_file_setup(TMPFS_MNT, "drm mm object", size, VM_NORESERVE);
if (IS_ERR(filp))
return PTR_ERR(filp);
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
index 8ebc8d3560c3..4eef07d8b8ed 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -336,7 +336,7 @@ int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistent_swap_storage)
BUG_ON(ttm->caching_state != tt_cached);
if (!persistent_swap_storage) {
- swap_storage = shmem_file_setup("ttm swap",
+ swap_storage = shmem_file_setup(TMPFS_MNT, "ttm swap",
ttm->num_pages << PAGE_SHIFT,
0);
if (IS_ERR(swap_storage)) {
diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c
index 0f695df14c9d..184fcbb6d127 100644
--- a/drivers/staging/android/ashmem.c
+++ b/drivers/staging/android/ashmem.c
@@ -391,7 +391,8 @@ static int ashmem_mmap(struct file *file, struct vm_area_struct *vma)
name = asma->name;
/* ... and allocate the backing shmem file */
- vmfile = shmem_file_setup(name, asma->size, vma->vm_flags);
+ vmfile = shmem_file_setup(TMPFS_MNT, name, asma->size,
+ vma->vm_flags);
if (IS_ERR(vmfile)) {
ret = PTR_ERR(vmfile);
goto out;
diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h
index b6c3540e07bc..00b199d804ca 100644
--- a/include/linux/shmem_fs.h
+++ b/include/linux/shmem_fs.h
@@ -44,12 +44,14 @@ static inline struct shmem_inode_info *SHMEM_I(struct inode *inode)
return container_of(inode, struct shmem_inode_info, vfs_inode);
}
+#define TMPFS_MNT NULL
+
/*
* Functions in mm/shmem.c called directly from elsewhere:
*/
extern int shmem_init(void);
extern int shmem_fill_super(struct super_block *sb, void *data, int silent);
-extern struct file *shmem_file_setup(const char *name,
+extern struct file *shmem_file_setup(struct vfsmount *mnt, const char *name,
loff_t size, unsigned long flags);
extern struct file *shmem_kernel_file_setup(const char *name, loff_t size,
unsigned long flags);
diff --git a/mm/shmem.c b/mm/shmem.c
index 07a1d22807be..ae2e46291ffa 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -3715,7 +3715,7 @@ SYSCALL_DEFINE2(memfd_create,
(flags >> MFD_HUGE_SHIFT) &
MFD_HUGE_MASK);
} else
- file = shmem_file_setup(name, 0, VM_NORESERVE);
+ file = shmem_file_setup(TMPFS_MNT, name, 0, VM_NORESERVE);
if (IS_ERR(file)) {
error = PTR_ERR(file);
goto err_fd;
@@ -4183,7 +4183,7 @@ static const struct dentry_operations anon_ops = {
.d_dname = simple_dname
};
-static struct file *__shmem_file_setup(const char *name, loff_t size,
+static struct file *__shmem_file_setup(struct vfsmount *mnt, const char *name, loff_t size,
unsigned long flags, unsigned int i_flags)
{
struct file *res;
@@ -4192,8 +4192,11 @@ static struct file *__shmem_file_setup(const char *name, loff_t size,
struct super_block *sb;
struct qstr this;
- if (IS_ERR(shm_mnt))
- return ERR_CAST(shm_mnt);
+ if (mnt == TMPFS_MNT)
+ mnt = shm_mnt;
+
+ if (IS_ERR(mnt))
+ return ERR_CAST(mnt);
if (size < 0 || size > MAX_LFS_FILESIZE)
return ERR_PTR(-EINVAL);
@@ -4205,8 +4208,8 @@ static struct file *__shmem_file_setup(const char *name, loff_t size,
this.name = name;
this.len = strlen(name);
this.hash = 0; /* will go */
- sb = shm_mnt->mnt_sb;
- path.mnt = mntget(shm_mnt);
+ sb = mnt->mnt_sb;
+ path.mnt = mntget(mnt);
path.dentry = d_alloc_pseudo(sb, &this);
if (!path.dentry)
goto put_memory;
@@ -4251,18 +4254,19 @@ static struct file *__shmem_file_setup(const char *name, loff_t size,
*/
struct file *shmem_kernel_file_setup(const char *name, loff_t size, unsigned long flags)
{
- return __shmem_file_setup(name, size, flags, S_PRIVATE);
+ return __shmem_file_setup(TMPFS_MNT, name, size, flags, S_PRIVATE);
}
/**
* shmem_file_setup - get an unlinked file living in tmpfs
+ * @mnt: the tmpfs mount where the file will be created
* @name: name for dentry (to be seen in /proc/<pid>/maps
* @size: size to be set for the file
* @flags: VM_NORESERVE suppresses pre-accounting of the entire object size
*/
-struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags)
+struct file *shmem_file_setup(struct vfsmount *mnt, const char *name, loff_t size, unsigned long flags)
{
- return __shmem_file_setup(name, size, flags, 0);
+ return __shmem_file_setup(mnt, name, size, flags, 0);
}
EXPORT_SYMBOL_GPL(shmem_file_setup);
@@ -4281,7 +4285,7 @@ int shmem_zero_setup(struct vm_area_struct *vma)
* accessible to the user through its mapping, use S_PRIVATE flag to
* bypass file security, in the same way as shmem_kernel_file_setup().
*/
- file = __shmem_file_setup("dev/zero", size, vma->vm_flags, S_PRIVATE);
+ file = shmem_kernel_file_setup("dev/zero", size, vma->vm_flags);
if (IS_ERR(file))
return PTR_ERR(file);
--
2.13.5
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
WARNING: multiple messages have this Message-ID (diff)
From: Matthew Auld <matthew.auld@intel.com>
To: intel-gfx@lists.freedesktop.org
Cc: "Joonas Lahtinen" <joonas.lahtinen@linux.intel.com>,
"Chris Wilson" <chris@chris-wilson.co.uk>,
"Daniel Vetter" <daniel.vetter@intel.com>,
"Dave Hansen" <dave.hansen@intel.com>,
"Kirill A . Shutemov" <kirill@shutemov.name>,
"Andrew Morton" <akpm@linux-foundation.org>,
"Hugh Dickins" <hughd@google.com>,
"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
"Arve Hjønnevåg" <arve@android.com>,
"Riley Andrews" <riandrews@android.com>,
dri-devel@lists.freedesktop.org, linux-mm@kvack.org,
devel@driverdev.osuosl.org
Subject: [PATCH 01/22] mm/shmem: support passing mnt to shmem_file_setup
Date: Mon, 25 Sep 2017 19:47:16 +0100 [thread overview]
Message-ID: <20170925184737.8807-2-matthew.auld@intel.com> (raw)
In-Reply-To: <20170925184737.8807-1-matthew.auld@intel.com>
We are planning to use our own tmpfs mnt in i915 in place of the
shm_mnt such that we can control the mount options, in particular
huge=, which we require to support huge-gtt-pages. So rather than roll
our own version of __shmem_file_setup, it would be preferred if we could
just give shmem our mnt, and let it do the rest.
Based on the patch: https://patchwork.freedesktop.org/patch/178433/
Suggested-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Kirill A. Shutemov <kirill@shutemov.name>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Hugh Dickins <hughd@google.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: "Arve HjA,nnevAJPYg" <arve@android.com>
Cc: Riley Andrews <riandrews@android.com>
Cc: dri-devel@lists.freedesktop.org
Cc: linux-mm@kvack.org
Cc: devel@driverdev.osuosl.org
---
drivers/gpu/drm/drm_gem.c | 2 +-
drivers/gpu/drm/ttm/ttm_tt.c | 2 +-
drivers/staging/android/ashmem.c | 3 ++-
include/linux/shmem_fs.h | 4 +++-
mm/shmem.c | 24 ++++++++++++++----------
5 files changed, 21 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 7199bba68c37..12e5fdc90a6f 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -138,7 +138,7 @@ int drm_gem_object_init(struct drm_device *dev,
drm_gem_private_object_init(dev, obj, size);
- filp = shmem_file_setup("drm mm object", size, VM_NORESERVE);
+ filp = shmem_file_setup(TMPFS_MNT, "drm mm object", size, VM_NORESERVE);
if (IS_ERR(filp))
return PTR_ERR(filp);
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
index 8ebc8d3560c3..4eef07d8b8ed 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -336,7 +336,7 @@ int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistent_swap_storage)
BUG_ON(ttm->caching_state != tt_cached);
if (!persistent_swap_storage) {
- swap_storage = shmem_file_setup("ttm swap",
+ swap_storage = shmem_file_setup(TMPFS_MNT, "ttm swap",
ttm->num_pages << PAGE_SHIFT,
0);
if (IS_ERR(swap_storage)) {
diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c
index 0f695df14c9d..184fcbb6d127 100644
--- a/drivers/staging/android/ashmem.c
+++ b/drivers/staging/android/ashmem.c
@@ -391,7 +391,8 @@ static int ashmem_mmap(struct file *file, struct vm_area_struct *vma)
name = asma->name;
/* ... and allocate the backing shmem file */
- vmfile = shmem_file_setup(name, asma->size, vma->vm_flags);
+ vmfile = shmem_file_setup(TMPFS_MNT, name, asma->size,
+ vma->vm_flags);
if (IS_ERR(vmfile)) {
ret = PTR_ERR(vmfile);
goto out;
diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h
index b6c3540e07bc..00b199d804ca 100644
--- a/include/linux/shmem_fs.h
+++ b/include/linux/shmem_fs.h
@@ -44,12 +44,14 @@ static inline struct shmem_inode_info *SHMEM_I(struct inode *inode)
return container_of(inode, struct shmem_inode_info, vfs_inode);
}
+#define TMPFS_MNT NULL
+
/*
* Functions in mm/shmem.c called directly from elsewhere:
*/
extern int shmem_init(void);
extern int shmem_fill_super(struct super_block *sb, void *data, int silent);
-extern struct file *shmem_file_setup(const char *name,
+extern struct file *shmem_file_setup(struct vfsmount *mnt, const char *name,
loff_t size, unsigned long flags);
extern struct file *shmem_kernel_file_setup(const char *name, loff_t size,
unsigned long flags);
diff --git a/mm/shmem.c b/mm/shmem.c
index 07a1d22807be..ae2e46291ffa 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -3715,7 +3715,7 @@ SYSCALL_DEFINE2(memfd_create,
(flags >> MFD_HUGE_SHIFT) &
MFD_HUGE_MASK);
} else
- file = shmem_file_setup(name, 0, VM_NORESERVE);
+ file = shmem_file_setup(TMPFS_MNT, name, 0, VM_NORESERVE);
if (IS_ERR(file)) {
error = PTR_ERR(file);
goto err_fd;
@@ -4183,7 +4183,7 @@ static const struct dentry_operations anon_ops = {
.d_dname = simple_dname
};
-static struct file *__shmem_file_setup(const char *name, loff_t size,
+static struct file *__shmem_file_setup(struct vfsmount *mnt, const char *name, loff_t size,
unsigned long flags, unsigned int i_flags)
{
struct file *res;
@@ -4192,8 +4192,11 @@ static struct file *__shmem_file_setup(const char *name, loff_t size,
struct super_block *sb;
struct qstr this;
- if (IS_ERR(shm_mnt))
- return ERR_CAST(shm_mnt);
+ if (mnt == TMPFS_MNT)
+ mnt = shm_mnt;
+
+ if (IS_ERR(mnt))
+ return ERR_CAST(mnt);
if (size < 0 || size > MAX_LFS_FILESIZE)
return ERR_PTR(-EINVAL);
@@ -4205,8 +4208,8 @@ static struct file *__shmem_file_setup(const char *name, loff_t size,
this.name = name;
this.len = strlen(name);
this.hash = 0; /* will go */
- sb = shm_mnt->mnt_sb;
- path.mnt = mntget(shm_mnt);
+ sb = mnt->mnt_sb;
+ path.mnt = mntget(mnt);
path.dentry = d_alloc_pseudo(sb, &this);
if (!path.dentry)
goto put_memory;
@@ -4251,18 +4254,19 @@ static struct file *__shmem_file_setup(const char *name, loff_t size,
*/
struct file *shmem_kernel_file_setup(const char *name, loff_t size, unsigned long flags)
{
- return __shmem_file_setup(name, size, flags, S_PRIVATE);
+ return __shmem_file_setup(TMPFS_MNT, name, size, flags, S_PRIVATE);
}
/**
* shmem_file_setup - get an unlinked file living in tmpfs
+ * @mnt: the tmpfs mount where the file will be created
* @name: name for dentry (to be seen in /proc/<pid>/maps
* @size: size to be set for the file
* @flags: VM_NORESERVE suppresses pre-accounting of the entire object size
*/
-struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags)
+struct file *shmem_file_setup(struct vfsmount *mnt, const char *name, loff_t size, unsigned long flags)
{
- return __shmem_file_setup(name, size, flags, 0);
+ return __shmem_file_setup(mnt, name, size, flags, 0);
}
EXPORT_SYMBOL_GPL(shmem_file_setup);
@@ -4281,7 +4285,7 @@ int shmem_zero_setup(struct vm_area_struct *vma)
* accessible to the user through its mapping, use S_PRIVATE flag to
* bypass file security, in the same way as shmem_kernel_file_setup().
*/
- file = __shmem_file_setup("dev/zero", size, vma->vm_flags, S_PRIVATE);
+ file = shmem_kernel_file_setup("dev/zero", size, vma->vm_flags);
if (IS_ERR(file))
return PTR_ERR(file);
--
2.13.5
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
next prev parent reply other threads:[~2017-09-25 18:47 UTC|newest]
Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-09-25 18:47 [PATCH 00/22] huge gtt pages Matthew Auld
2017-09-25 18:47 ` Matthew Auld [this message]
2017-09-25 18:47 ` [PATCH 01/22] mm/shmem: support passing mnt to shmem_file_setup Matthew Auld
2017-09-25 18:58 ` Chris Wilson
2017-09-25 18:47 ` [PATCH 02/22] drm/i915: introduce simple gemfs Matthew Auld
2017-09-25 18:47 ` Matthew Auld
2017-09-25 19:01 ` Chris Wilson
2017-09-26 7:52 ` Greg Kroah-Hartman
2017-09-26 7:52 ` Greg Kroah-Hartman
2017-09-26 13:21 ` Joonas Lahtinen
2017-09-26 13:21 ` Joonas Lahtinen
2017-09-26 21:34 ` Greg Kroah-Hartman
2017-09-26 21:34 ` Greg Kroah-Hartman
2017-09-27 7:50 ` Joonas Lahtinen
2017-09-27 7:50 ` Joonas Lahtinen
2017-09-25 18:47 ` [PATCH 03/22] mm/shmem: parse mount options for MS_KERNMOUNT Matthew Auld
2017-09-25 18:47 ` Matthew Auld
2017-09-25 19:28 ` Chris Wilson
2017-09-25 18:47 ` [PATCH 04/22] drm/i915/gemfs: enable THP Matthew Auld
2017-09-25 18:47 ` Matthew Auld
2017-09-25 19:11 ` Chris Wilson
2017-09-25 18:47 ` [PATCH 05/22] drm/i915: introduce page_sizes field to dev_info Matthew Auld
2017-09-25 18:47 ` [PATCH 06/22] drm/i915: push set_pages down to the callers Matthew Auld
2017-09-25 18:47 ` [PATCH 07/22] drm/i915: introduce page_size members Matthew Auld
2017-09-25 18:47 ` [PATCH 08/22] drm/i915: introduce vm set_pages/clear_pages Matthew Auld
2017-09-25 18:47 ` [PATCH 09/22] drm/i915: align the vma start to the largest gtt page size Matthew Auld
2017-09-25 18:47 ` [PATCH 10/22] drm/i915: align 64K objects to 2M Matthew Auld
2017-09-25 18:47 ` [PATCH 11/22] drm/i915: enable IPS bit for 64K pages Matthew Auld
2017-09-25 18:47 ` [PATCH 12/22] drm/i915: disable GTT cache for 2M pages Matthew Auld
2017-09-25 18:47 ` [PATCH 13/22] drm/i915: support 2M pages for the 48b PPGTT Matthew Auld
2017-09-25 18:47 ` [PATCH 14/22] drm/i915: add support for 64K scratch page Matthew Auld
2017-09-25 18:47 ` [PATCH 15/22] drm/i915: support 64K pages for the 48b PPGTT Matthew Auld
2017-09-25 18:47 ` [PATCH 16/22] drm/i915: accurate page size tracking for the ppgtt Matthew Auld
2017-09-25 18:47 ` [PATCH 17/22] drm/i915/debugfs: include some gtt page size metrics Matthew Auld
2017-09-25 18:47 ` [PATCH 18/22] drm/i915/selftests: huge page tests Matthew Auld
2017-09-25 19:17 ` Chris Wilson
2017-09-25 18:47 ` [PATCH 19/22] drm/i915/selftests: mix huge pages Matthew Auld
2017-09-25 18:47 ` [PATCH 20/22] drm/i915: disable platform support for vGPU huge gtt pages Matthew Auld
2017-09-25 18:47 ` [PATCH 21/22] drm/i915: enable platform support for 64K pages Matthew Auld
2017-09-25 18:47 ` [PATCH 22/22] drm/i915: enable platform support for 2M pages Matthew Auld
2017-09-25 19:13 ` ✓ Fi.CI.BAT: success for huge gtt pages (rev9) Patchwork
2017-09-25 23:03 ` ✓ Fi.CI.IGT: " Patchwork
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=20170925184737.8807-2-matthew.auld@intel.com \
--to=matthew.auld@intel.com \
--cc=akpm@linux-foundation.org \
--cc=arve@android.com \
--cc=chris@chris-wilson.co.uk \
--cc=daniel.vetter@intel.com \
--cc=dave.hansen@intel.com \
--cc=devel@driverdev.osuosl.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=gregkh@linuxfoundation.org \
--cc=hughd@google.com \
--cc=intel-gfx@lists.freedesktop.org \
--cc=joonas.lahtinen@linux.intel.com \
--cc=kirill@shutemov.name \
--cc=linux-mm@kvack.org \
--cc=riandrews@android.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.