* [PATCH 0/2] loop: LOOP_FLAGS_BLOCKSIZE fixes
@ 2017-08-18 6:15 Omar Sandoval
2017-08-18 6:15 ` [PATCH 1/2] loop: always return block size in LOOP_GET_STATUS Omar Sandoval
` (2 more replies)
0 siblings, 3 replies; 17+ messages in thread
From: Omar Sandoval @ 2017-08-18 6:15 UTC (permalink / raw)
To: linux-block; +Cc: kernel-team, Hannes Reinecke, Ming Lei
From: Omar Sandoval <osandov@fb.com>
A couple of bugs I found while adding blktests for the new loop block
size feature. Based on v4.13-rc5, we should get these in for 4.13.
Thanks!
Omar Sandoval (2):
loop: always return block size in LOOP_GET_STATUS
loop: fix hang if LOOP_SET_STATUS gets invalid blocksize or encrypt
type
drivers/block/loop.c | 53 ++++++++++++++++++++++++++++++----------------------
1 file changed, 31 insertions(+), 22 deletions(-)
--
2.14.1
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 1/2] loop: always return block size in LOOP_GET_STATUS
2017-08-18 6:15 [PATCH 0/2] loop: LOOP_FLAGS_BLOCKSIZE fixes Omar Sandoval
@ 2017-08-18 6:15 ` Omar Sandoval
2017-08-18 7:18 ` Hannes Reinecke
2017-08-18 6:15 ` [PATCH 2/2] loop: fix hang if LOOP_SET_STATUS gets invalid blocksize or encrypt type Omar Sandoval
2017-08-18 6:51 ` [PATCH 0/2] loop: LOOP_FLAGS_BLOCKSIZE fixes Omar Sandoval
2 siblings, 1 reply; 17+ messages in thread
From: Omar Sandoval @ 2017-08-18 6:15 UTC (permalink / raw)
To: linux-block; +Cc: kernel-team, Hannes Reinecke, Ming Lei
From: Omar Sandoval <osandov@fb.com>
When I was writing a test for the new loop device block size
functionality, I realized that the interface is kind of dumb:
- lo_init[0] is never filled in with the logical block size we
previously set
- lo_flags returned from LOOP_GET_STATUS will have LO_FLAGS_BLOCKSIZE
set if we previously called LOOP_SET_STATUS with LO_FLAGS_BLOCKSIZE
set, which doesn't really mean anything
Instead, for LOOP_GET_STATUS, let's always fill in lo_init[0] and set
the LO_FLAGS_BLOCKSIZE flag to indicate we support it.
Signed-off-by: Omar Sandoval <osandov@fb.com>
---
drivers/block/loop.c | 33 +++++++++++++++++----------------
1 file changed, 17 insertions(+), 16 deletions(-)
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index ef8334949b42..39fa7f48e0c7 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -234,7 +234,7 @@ figure_loop_size(struct loop_device *lo, loff_t offset, loff_t sizelimit,
lo->lo_offset = offset;
if (lo->lo_sizelimit != sizelimit)
lo->lo_sizelimit = sizelimit;
- if (lo->lo_flags & LO_FLAGS_BLOCKSIZE) {
+ if (lo->lo_logical_blocksize != logical_blocksize) {
lo->lo_logical_blocksize = logical_blocksize;
blk_queue_physical_block_size(lo->lo_queue, lo->lo_blocksize);
blk_queue_logical_block_size(lo->lo_queue,
@@ -820,7 +820,7 @@ static void loop_config_discard(struct loop_device *lo)
struct file *file = lo->lo_backing_file;
struct inode *inode = file->f_mapping->host;
struct request_queue *q = lo->lo_queue;
- int lo_bits = 9;
+ int lo_bits = blksize_bits(lo->lo_logical_blocksize);
/*
* We use punch hole to reclaim the free space used by the
@@ -840,8 +840,6 @@ static void loop_config_discard(struct loop_device *lo)
q->limits.discard_granularity = inode->i_sb->s_blocksize;
q->limits.discard_alignment = 0;
- if (lo->lo_flags & LO_FLAGS_BLOCKSIZE)
- lo_bits = blksize_bits(lo->lo_logical_blocksize);
blk_queue_max_discard_sectors(q, UINT_MAX >> lo_bits);
blk_queue_max_write_zeroes_sectors(q, UINT_MAX >> lo_bits);
@@ -1061,6 +1059,7 @@ static int loop_clr_fd(struct loop_device *lo)
lo->lo_offset = 0;
lo->lo_sizelimit = 0;
lo->lo_encrypt_key_size = 0;
+ lo->lo_logical_blocksize = 512;
memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE);
memset(lo->lo_crypt_name, 0, LO_NAME_SIZE);
memset(lo->lo_file_name, 0, LO_NAME_SIZE);
@@ -1105,6 +1104,7 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
struct loop_func_table *xfer;
kuid_t uid = current_uid();
int lo_flags = lo->lo_flags;
+ unsigned lo_logical_blocksize;
if (lo->lo_encrypt_key_size &&
!uid_eq(lo->lo_key_owner, uid) &&
@@ -1138,25 +1138,24 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
goto exit;
if (info->lo_flags & LO_FLAGS_BLOCKSIZE) {
- if (!(lo->lo_flags & LO_FLAGS_BLOCKSIZE))
- lo->lo_logical_blocksize = 512;
- lo->lo_flags |= LO_FLAGS_BLOCKSIZE;
- if (LO_INFO_BLOCKSIZE(info) != 512 &&
- LO_INFO_BLOCKSIZE(info) != 1024 &&
- LO_INFO_BLOCKSIZE(info) != 2048 &&
- LO_INFO_BLOCKSIZE(info) != 4096)
+ lo_logical_blocksize = LO_INFO_BLOCKSIZE(info);
+ if (lo_logical_blocksize != 512 &&
+ lo_logical_blocksize != 1024 &&
+ lo_logical_blocksize != 2048 &&
+ lo_logical_blocksize != 4096)
return -EINVAL;
- if (LO_INFO_BLOCKSIZE(info) > lo->lo_blocksize)
+ if (lo_logical_blocksize > lo->lo_blocksize)
return -EINVAL;
+ } else {
+ lo_logical_blocksize = lo->lo_logical_blocksize;
}
if (lo->lo_offset != info->lo_offset ||
lo->lo_sizelimit != info->lo_sizelimit ||
lo->lo_flags != lo_flags ||
- ((lo->lo_flags & LO_FLAGS_BLOCKSIZE) &&
- lo->lo_logical_blocksize != LO_INFO_BLOCKSIZE(info))) {
+ lo->lo_logical_blocksize != lo_logical_blocksize) {
if (figure_loop_size(lo, info->lo_offset, info->lo_sizelimit,
- LO_INFO_BLOCKSIZE(info))) {
+ lo_logical_blocksize)) {
err = -EFBIG;
goto exit;
}
@@ -1223,7 +1222,7 @@ loop_get_status(struct loop_device *lo, struct loop_info64 *info)
info->lo_rdevice = huge_encode_dev(lo->lo_device ? stat.rdev : stat.dev);
info->lo_offset = lo->lo_offset;
info->lo_sizelimit = lo->lo_sizelimit;
- info->lo_flags = lo->lo_flags;
+ info->lo_flags = lo->lo_flags | LO_FLAGS_BLOCKSIZE;
memcpy(info->lo_file_name, lo->lo_file_name, LO_NAME_SIZE);
memcpy(info->lo_crypt_name, lo->lo_crypt_name, LO_NAME_SIZE);
info->lo_encrypt_type =
@@ -1233,6 +1232,7 @@ loop_get_status(struct loop_device *lo, struct loop_info64 *info)
memcpy(info->lo_encrypt_key, lo->lo_encrypt_key,
lo->lo_encrypt_key_size);
}
+ LO_INFO_BLOCKSIZE(info) = lo->lo_logical_blocksize;
return 0;
}
@@ -1835,6 +1835,7 @@ static int loop_add(struct loop_device **l, int i)
mutex_init(&lo->lo_ctl_mutex);
atomic_set(&lo->lo_refcnt, 0);
lo->lo_number = i;
+ lo->lo_logical_blocksize = 512;
spin_lock_init(&lo->lo_lock);
disk->major = LOOP_MAJOR;
disk->first_minor = i << part_shift;
--
2.14.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 2/2] loop: fix hang if LOOP_SET_STATUS gets invalid blocksize or encrypt type
2017-08-18 6:15 [PATCH 0/2] loop: LOOP_FLAGS_BLOCKSIZE fixes Omar Sandoval
2017-08-18 6:15 ` [PATCH 1/2] loop: always return block size in LOOP_GET_STATUS Omar Sandoval
@ 2017-08-18 6:15 ` Omar Sandoval
2017-08-18 7:20 ` Hannes Reinecke
2017-08-18 6:51 ` [PATCH 0/2] loop: LOOP_FLAGS_BLOCKSIZE fixes Omar Sandoval
2 siblings, 1 reply; 17+ messages in thread
From: Omar Sandoval @ 2017-08-18 6:15 UTC (permalink / raw)
To: linux-block; +Cc: kernel-team, Hannes Reinecke, Ming Lei
From: Omar Sandoval <osandov@fb.com>
In both of these error cases, we need to make sure to unfreeze the queue
before we return.
Fixes: ecdd09597a57 ("block/loop: fix race between I/O and set_status")
Fixes: f2c6df7dbf9a ("loop: support 4k physical blocksize")
Signed-off-by: Omar Sandoval <osandov@fb.com>
---
drivers/block/loop.c | 24 ++++++++++++++++--------
1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 39fa7f48e0c7..6c7609b3305d 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -1125,11 +1125,15 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
if (info->lo_encrypt_type) {
unsigned int type = info->lo_encrypt_type;
- if (type >= MAX_LO_CRYPT)
- return -EINVAL;
+ if (type >= MAX_LO_CRYPT) {
+ err = -EINVAL;
+ goto exit;
+ }
xfer = xfer_funcs[type];
- if (xfer == NULL)
- return -EINVAL;
+ if (xfer == NULL) {
+ err = -EINVAL;
+ goto exit;
+ }
} else
xfer = NULL;
@@ -1142,10 +1146,14 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
if (lo_logical_blocksize != 512 &&
lo_logical_blocksize != 1024 &&
lo_logical_blocksize != 2048 &&
- lo_logical_blocksize != 4096)
- return -EINVAL;
- if (lo_logical_blocksize > lo->lo_blocksize)
- return -EINVAL;
+ lo_logical_blocksize != 4096) {
+ err = -EINVAL;
+ goto exit;
+ }
+ if (lo_logical_blocksize > lo->lo_blocksize) {
+ err = -EINVAL;
+ goto exit;
+ }
} else {
lo_logical_blocksize = lo->lo_logical_blocksize;
}
--
2.14.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH 0/2] loop: LOOP_FLAGS_BLOCKSIZE fixes
2017-08-18 6:15 [PATCH 0/2] loop: LOOP_FLAGS_BLOCKSIZE fixes Omar Sandoval
2017-08-18 6:15 ` [PATCH 1/2] loop: always return block size in LOOP_GET_STATUS Omar Sandoval
2017-08-18 6:15 ` [PATCH 2/2] loop: fix hang if LOOP_SET_STATUS gets invalid blocksize or encrypt type Omar Sandoval
@ 2017-08-18 6:51 ` Omar Sandoval
2 siblings, 0 replies; 17+ messages in thread
From: Omar Sandoval @ 2017-08-18 6:51 UTC (permalink / raw)
To: linux-block; +Cc: kernel-team, Hannes Reinecke, Ming Lei
On Thu, Aug 17, 2017 at 11:15:24PM -0700, Omar Sandoval wrote:
> From: Omar Sandoval <osandov@fb.com>
>
> A couple of bugs I found while adding blktests for the new loop block
> size feature. Based on v4.13-rc5, we should get these in for 4.13.
Just pushed the test: https://github.com/osandov/blktests/commit/7320725134cc0b65588bf03259201d74a0ee8226
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/2] loop: always return block size in LOOP_GET_STATUS
2017-08-18 6:15 ` [PATCH 1/2] loop: always return block size in LOOP_GET_STATUS Omar Sandoval
@ 2017-08-18 7:18 ` Hannes Reinecke
2017-08-18 7:38 ` Omar Sandoval
0 siblings, 1 reply; 17+ messages in thread
From: Hannes Reinecke @ 2017-08-18 7:18 UTC (permalink / raw)
To: Omar Sandoval, linux-block; +Cc: kernel-team, Ming Lei
On 08/18/2017 08:15 AM, Omar Sandoval wrote:
> From: Omar Sandoval <osandov@fb.com>
>
> When I was writing a test for the new loop device block size
> functionality, I realized that the interface is kind of dumb:
>
> - lo_init[0] is never filled in with the logical block size we
> previously set
> - lo_flags returned from LOOP_GET_STATUS will have LO_FLAGS_BLOCKSIZE
> set if we previously called LOOP_SET_STATUS with LO_FLAGS_BLOCKSIZE
> set, which doesn't really mean anything
>
> Instead, for LOOP_GET_STATUS, let's always fill in lo_init[0] and set
> the LO_FLAGS_BLOCKSIZE flag to indicate we support it.
>
> Signed-off-by: Omar Sandoval <osandov@fb.com>
> ---
> drivers/block/loop.c | 33 +++++++++++++++++----------------
> 1 file changed, 17 insertions(+), 16 deletions(-)
>
Phew. 'Dumb interface'.
'tis wasn't me who designed the interface;
Backwards compability are the watchwords here.
Personally, I would have loved to design a new interface.
I've got quite some flak for daring to break existing interfaces, most
notably setting logical and physical blocksize per default (which I
would _love_ to have done, seeing that it really makes sense here).
But as this would change the behaviour I've gone through pains (and
several _years_ of iterations) to get this sorted.
So if you design a blocktest for that ensure that
a) the sysfs attributes before and after the patch are _identical_
b) the sysfs attributes will only change if the 'LO_FLAGS_BLOCKSIZE'
flag has been set
and
c) validate the written blocksizes; this is required to be able to
install bootloaders there
This whole interface was designed such that you can prepare bootable
diskimages for S/390 DASDs, which use a native 4k blocksize.
Cheers,
Hannes
--
Dr. Hannes Reinecke Teamlead Storage & Networking
hare@suse.de +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 2/2] loop: fix hang if LOOP_SET_STATUS gets invalid blocksize or encrypt type
2017-08-18 6:15 ` [PATCH 2/2] loop: fix hang if LOOP_SET_STATUS gets invalid blocksize or encrypt type Omar Sandoval
@ 2017-08-18 7:20 ` Hannes Reinecke
0 siblings, 0 replies; 17+ messages in thread
From: Hannes Reinecke @ 2017-08-18 7:20 UTC (permalink / raw)
To: Omar Sandoval, linux-block; +Cc: kernel-team, Ming Lei
On 08/18/2017 08:15 AM, Omar Sandoval wrote:
> From: Omar Sandoval <osandov@fb.com>
>
> In both of these error cases, we need to make sure to unfreeze the queue
> before we return.
>
> Fixes: ecdd09597a57 ("block/loop: fix race between I/O and set_status")
> Fixes: f2c6df7dbf9a ("loop: support 4k physical blocksize")
> Signed-off-by: Omar Sandoval <osandov@fb.com>
> ---
> drivers/block/loop.c | 24 ++++++++++++++++--------
> 1 file changed, 16 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/block/loop.c b/drivers/block/loop.c
> index 39fa7f48e0c7..6c7609b3305d 100644
> --- a/drivers/block/loop.c
> +++ b/drivers/block/loop.c
> @@ -1125,11 +1125,15 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
> if (info->lo_encrypt_type) {
> unsigned int type = info->lo_encrypt_type;
>
> - if (type >= MAX_LO_CRYPT)
> - return -EINVAL;
> + if (type >= MAX_LO_CRYPT) {
> + err = -EINVAL;
> + goto exit;
> + }
> xfer = xfer_funcs[type];
> - if (xfer == NULL)
> - return -EINVAL;
> + if (xfer == NULL) {
> + err = -EINVAL;
> + goto exit;
> + }
> } else
> xfer = NULL;
>
> @@ -1142,10 +1146,14 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
> if (lo_logical_blocksize != 512 &&
> lo_logical_blocksize != 1024 &&
> lo_logical_blocksize != 2048 &&
> - lo_logical_blocksize != 4096)
> - return -EINVAL;
> - if (lo_logical_blocksize > lo->lo_blocksize)
> - return -EINVAL;
> + lo_logical_blocksize != 4096) {
> + err = -EINVAL;
> + goto exit;
> + }
> + if (lo_logical_blocksize > lo->lo_blocksize) {
> + err = -EINVAL;
> + goto exit;
> + }
> } else {
> lo_logical_blocksize = lo->lo_logical_blocksize;
> }
> Reviewed-by: Hannes Reinecke <hare@suse.com>
Cheers,
Hannes
--
Dr. Hannes Reinecke Teamlead Storage & Networking
hare@suse.de +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/2] loop: always return block size in LOOP_GET_STATUS
2017-08-18 7:18 ` Hannes Reinecke
@ 2017-08-18 7:38 ` Omar Sandoval
2017-08-18 7:43 ` Hannes Reinecke
0 siblings, 1 reply; 17+ messages in thread
From: Omar Sandoval @ 2017-08-18 7:38 UTC (permalink / raw)
To: Hannes Reinecke; +Cc: linux-block, kernel-team, Ming Lei
On Fri, Aug 18, 2017 at 09:18:52AM +0200, Hannes Reinecke wrote:
> On 08/18/2017 08:15 AM, Omar Sandoval wrote:
> > From: Omar Sandoval <osandov@fb.com>
> >
> > When I was writing a test for the new loop device block size
> > functionality, I realized that the interface is kind of dumb:
> >
> > - lo_init[0] is never filled in with the logical block size we
> > previously set
> > - lo_flags returned from LOOP_GET_STATUS will have LO_FLAGS_BLOCKSIZE
> > set if we previously called LOOP_SET_STATUS with LO_FLAGS_BLOCKSIZE
> > set, which doesn't really mean anything
> >
> > Instead, for LOOP_GET_STATUS, let's always fill in lo_init[0] and set
> > the LO_FLAGS_BLOCKSIZE flag to indicate we support it.
> >
> > Signed-off-by: Omar Sandoval <osandov@fb.com>
> > ---
> > drivers/block/loop.c | 33 +++++++++++++++++----------------
> > 1 file changed, 17 insertions(+), 16 deletions(-)
> >
> Phew. 'Dumb interface'.
> 'tis wasn't me who designed the interface;
> Backwards compability are the watchwords here.
> Personally, I would have loved to design a new interface.
>
> I've got quite some flak for daring to break existing interfaces, most
> notably setting logical and physical blocksize per default (which I
> would _love_ to have done, seeing that it really makes sense here).
> But as this would change the behaviour I've gone through pains (and
> several _years_ of iterations) to get this sorted.
>
> So if you design a blocktest for that ensure that
> a) the sysfs attributes before and after the patch are _identical_
> b) the sysfs attributes will only change if the 'LO_FLAGS_BLOCKSIZE'
> flag has been set
> and
> c) validate the written blocksizes; this is required to be able to
> install bootloaders there
>
> This whole interface was designed such that you can prepare bootable
> diskimages for S/390 DASDs, which use a native 4k blocksize.
Hi, Hannes,
Wasn't insulting you at all, the only part of the interface I'm
complaining about is LOOP_GET_STATUS missing information :)
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/2] loop: always return block size in LOOP_GET_STATUS
2017-08-18 7:38 ` Omar Sandoval
@ 2017-08-18 7:43 ` Hannes Reinecke
2017-08-18 7:47 ` Omar Sandoval
0 siblings, 1 reply; 17+ messages in thread
From: Hannes Reinecke @ 2017-08-18 7:43 UTC (permalink / raw)
To: Omar Sandoval; +Cc: linux-block, kernel-team, Ming Lei
On 08/18/2017 09:38 AM, Omar Sandoval wrote:
> On Fri, Aug 18, 2017 at 09:18:52AM +0200, Hannes Reinecke wrote:
>> On 08/18/2017 08:15 AM, Omar Sandoval wrote:
>>> From: Omar Sandoval <osandov@fb.com>
>>>
>>> When I was writing a test for the new loop device block size
>>> functionality, I realized that the interface is kind of dumb:
>>>
>>> - lo_init[0] is never filled in with the logical block size we
>>> previously set
>>> - lo_flags returned from LOOP_GET_STATUS will have LO_FLAGS_BLOCKSIZE
>>> set if we previously called LOOP_SET_STATUS with LO_FLAGS_BLOCKSIZE
>>> set, which doesn't really mean anything
>>>
>>> Instead, for LOOP_GET_STATUS, let's always fill in lo_init[0] and set
>>> the LO_FLAGS_BLOCKSIZE flag to indicate we support it.
>>>
>>> Signed-off-by: Omar Sandoval <osandov@fb.com>
>>> ---
>>> drivers/block/loop.c | 33 +++++++++++++++++----------------
>>> 1 file changed, 17 insertions(+), 16 deletions(-)
>>>
>> Phew. 'Dumb interface'.
>> 'tis wasn't me who designed the interface;
>> Backwards compability are the watchwords here.
>> Personally, I would have loved to design a new interface.
>>
>> I've got quite some flak for daring to break existing interfaces, most
>> notably setting logical and physical blocksize per default (which I
>> would _love_ to have done, seeing that it really makes sense here).
>> But as this would change the behaviour I've gone through pains (and
>> several _years_ of iterations) to get this sorted.
>>
>> So if you design a blocktest for that ensure that
>> a) the sysfs attributes before and after the patch are _identical_
>> b) the sysfs attributes will only change if the 'LO_FLAGS_BLOCKSIZE'
>> flag has been set
>> and
>> c) validate the written blocksizes; this is required to be able to
>> install bootloaders there
>>
>> This whole interface was designed such that you can prepare bootable
>> diskimages for S/390 DASDs, which use a native 4k blocksize.
>
> Hi, Hannes,
>
> Wasn't insulting you at all, the only part of the interface I'm
> complaining about is LOOP_GET_STATUS missing information :)
>
Sure. Just saying.
But please make sure only to return that information if the
LO_FLAGS_BLOCKSIZE flag is set; otherwise there's a rick of confusing
losetup.
Cheers,
Hannes
--
Dr. Hannes Reinecke Teamlead Storage & Networking
hare@suse.de +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/2] loop: always return block size in LOOP_GET_STATUS
2017-08-18 7:43 ` Hannes Reinecke
@ 2017-08-18 7:47 ` Omar Sandoval
2017-08-18 7:56 ` Hannes Reinecke
0 siblings, 1 reply; 17+ messages in thread
From: Omar Sandoval @ 2017-08-18 7:47 UTC (permalink / raw)
To: Hannes Reinecke; +Cc: linux-block, kernel-team, Ming Lei
On Fri, Aug 18, 2017 at 09:43:19AM +0200, Hannes Reinecke wrote:
> On 08/18/2017 09:38 AM, Omar Sandoval wrote:
> > On Fri, Aug 18, 2017 at 09:18:52AM +0200, Hannes Reinecke wrote:
> >> On 08/18/2017 08:15 AM, Omar Sandoval wrote:
> >>> From: Omar Sandoval <osandov@fb.com>
> >>>
> >>> When I was writing a test for the new loop device block size
> >>> functionality, I realized that the interface is kind of dumb:
> >>>
> >>> - lo_init[0] is never filled in with the logical block size we
> >>> previously set
> >>> - lo_flags returned from LOOP_GET_STATUS will have LO_FLAGS_BLOCKSIZE
> >>> set if we previously called LOOP_SET_STATUS with LO_FLAGS_BLOCKSIZE
> >>> set, which doesn't really mean anything
> >>>
> >>> Instead, for LOOP_GET_STATUS, let's always fill in lo_init[0] and set
> >>> the LO_FLAGS_BLOCKSIZE flag to indicate we support it.
> >>>
> >>> Signed-off-by: Omar Sandoval <osandov@fb.com>
> >>> ---
> >>> drivers/block/loop.c | 33 +++++++++++++++++----------------
> >>> 1 file changed, 17 insertions(+), 16 deletions(-)
> >>>
> >> Phew. 'Dumb interface'.
> >> 'tis wasn't me who designed the interface;
> >> Backwards compability are the watchwords here.
> >> Personally, I would have loved to design a new interface.
> >>
> >> I've got quite some flak for daring to break existing interfaces, most
> >> notably setting logical and physical blocksize per default (which I
> >> would _love_ to have done, seeing that it really makes sense here).
> >> But as this would change the behaviour I've gone through pains (and
> >> several _years_ of iterations) to get this sorted.
> >>
> >> So if you design a blocktest for that ensure that
> >> a) the sysfs attributes before and after the patch are _identical_
> >> b) the sysfs attributes will only change if the 'LO_FLAGS_BLOCKSIZE'
> >> flag has been set
> >> and
> >> c) validate the written blocksizes; this is required to be able to
> >> install bootloaders there
> >>
> >> This whole interface was designed such that you can prepare bootable
> >> diskimages for S/390 DASDs, which use a native 4k blocksize.
> >
> > Hi, Hannes,
> >
> > Wasn't insulting you at all, the only part of the interface I'm
> > complaining about is LOOP_GET_STATUS missing information :)
> >
> Sure. Just saying.
> But please make sure only to return that information if the
> LO_FLAGS_BLOCKSIZE flag is set; otherwise there's a rick of confusing
> losetup.
I actually checked losetup, it works just fine with LO_FLAGS_BLOCKSIZE
always set and lo_init[0] always filled in.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/2] loop: always return block size in LOOP_GET_STATUS
2017-08-18 7:47 ` Omar Sandoval
@ 2017-08-18 7:56 ` Hannes Reinecke
2017-08-18 8:05 ` Omar Sandoval
0 siblings, 1 reply; 17+ messages in thread
From: Hannes Reinecke @ 2017-08-18 7:56 UTC (permalink / raw)
To: Omar Sandoval; +Cc: linux-block, kernel-team, Ming Lei
On 08/18/2017 09:47 AM, Omar Sandoval wrote:
> On Fri, Aug 18, 2017 at 09:43:19AM +0200, Hannes Reinecke wrote:
>> On 08/18/2017 09:38 AM, Omar Sandoval wrote:
>>> On Fri, Aug 18, 2017 at 09:18:52AM +0200, Hannes Reinecke wrote:
[ .. ]
>>>> I've got quite some flak for daring to break existing interfaces, most
>>>> notably setting logical and physical blocksize per default (which I
>>>> would _love_ to have done, seeing that it really makes sense here).
>>>> But as this would change the behaviour I've gone through pains (and
>>>> several _years_ of iterations) to get this sorted.
>>>>
>>>> So if you design a blocktest for that ensure that
>>>> a) the sysfs attributes before and after the patch are _identical_
>>>> b) the sysfs attributes will only change if the 'LO_FLAGS_BLOCKSIZE'
>>>> flag has been set
>>>> and
>>>> c) validate the written blocksizes; this is required to be able to
>>>> install bootloaders there
>>>>
>>>> This whole interface was designed such that you can prepare bootable
>>>> diskimages for S/390 DASDs, which use a native 4k blocksize.
>>>
>>> Hi, Hannes,
>>>
>>> Wasn't insulting you at all, the only part of the interface I'm
>>> complaining about is LOOP_GET_STATUS missing information :)
>>>
>> Sure. Just saying.
>> But please make sure only to return that information if the
>> LO_FLAGS_BLOCKSIZE flag is set; otherwise there's a rick of confusing
>> losetup.
>
> I actually checked losetup, it works just fine with LO_FLAGS_BLOCKSIZE
> always set and lo_init[0] always filled in.
>
The original argument I had with the util-linux maintainer did not
revolve so much around technical details :-)
Cheers,
Hannes
--
Dr. Hannes Reinecke Teamlead Storage & Networking
hare@suse.de +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/2] loop: always return block size in LOOP_GET_STATUS
2017-08-18 7:56 ` Hannes Reinecke
@ 2017-08-18 8:05 ` Omar Sandoval
2017-08-18 8:12 ` Hannes Reinecke
0 siblings, 1 reply; 17+ messages in thread
From: Omar Sandoval @ 2017-08-18 8:05 UTC (permalink / raw)
To: Hannes Reinecke, Karel Zak; +Cc: linux-block, kernel-team, Ming Lei
On Fri, Aug 18, 2017 at 09:56:26AM +0200, Hannes Reinecke wrote:
> On 08/18/2017 09:47 AM, Omar Sandoval wrote:
> > On Fri, Aug 18, 2017 at 09:43:19AM +0200, Hannes Reinecke wrote:
> >> On 08/18/2017 09:38 AM, Omar Sandoval wrote:
> >>> On Fri, Aug 18, 2017 at 09:18:52AM +0200, Hannes Reinecke wrote:
> [ .. ]
> >>>> I've got quite some flak for daring to break existing interfaces, most
> >>>> notably setting logical and physical blocksize per default (which I
> >>>> would _love_ to have done, seeing that it really makes sense here).
> >>>> But as this would change the behaviour I've gone through pains (and
> >>>> several _years_ of iterations) to get this sorted.
> >>>>
> >>>> So if you design a blocktest for that ensure that
> >>>> a) the sysfs attributes before and after the patch are _identical_
> >>>> b) the sysfs attributes will only change if the 'LO_FLAGS_BLOCKSIZE'
> >>>> flag has been set
> >>>> and
> >>>> c) validate the written blocksizes; this is required to be able to
> >>>> install bootloaders there
> >>>>
> >>>> This whole interface was designed such that you can prepare bootable
> >>>> diskimages for S/390 DASDs, which use a native 4k blocksize.
> >>>
> >>> Hi, Hannes,
> >>>
> >>> Wasn't insulting you at all, the only part of the interface I'm
> >>> complaining about is LOOP_GET_STATUS missing information :)
> >>>
> >> Sure. Just saying.
> >> But please make sure only to return that information if the
> >> LO_FLAGS_BLOCKSIZE flag is set; otherwise there's a rick of confusing
> >> losetup.
> >
> > I actually checked losetup, it works just fine with LO_FLAGS_BLOCKSIZE
> > always set and lo_init[0] always filled in.
> >
> The original argument I had with the util-linux maintainer did not
> revolve so much around technical details :-)
Karel, what were your concerns here?
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/2] loop: always return block size in LOOP_GET_STATUS
2017-08-18 8:05 ` Omar Sandoval
@ 2017-08-18 8:12 ` Hannes Reinecke
2017-08-18 8:22 ` Omar Sandoval
0 siblings, 1 reply; 17+ messages in thread
From: Hannes Reinecke @ 2017-08-18 8:12 UTC (permalink / raw)
To: Omar Sandoval, Karel Zak; +Cc: linux-block, kernel-team, Ming Lei
On 08/18/2017 10:05 AM, Omar Sandoval wrote:
> On Fri, Aug 18, 2017 at 09:56:26AM +0200, Hannes Reinecke wrote:
>> On 08/18/2017 09:47 AM, Omar Sandoval wrote:
[ .. ]
>>>
>>> I actually checked losetup, it works just fine with LO_FLAGS_BLOCKSIZE
>>> always set and lo_init[0] always filled in.
>>>
>> The original argument I had with the util-linux maintainer did not
>> revolve so much around technical details :-)
>
> Karel, what were your concerns here?
>
It wasn't Karel, it was our guy.
Doesn't make it any better, though...
Cheers,
Hannes
--
Dr. Hannes Reinecke Teamlead Storage & Networking
hare@suse.de +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/2] loop: always return block size in LOOP_GET_STATUS
2017-08-18 8:12 ` Hannes Reinecke
@ 2017-08-18 8:22 ` Omar Sandoval
2017-08-18 9:22 ` Karel Zak
2017-08-18 9:39 ` Karel Zak
0 siblings, 2 replies; 17+ messages in thread
From: Omar Sandoval @ 2017-08-18 8:22 UTC (permalink / raw)
To: Hannes Reinecke; +Cc: Karel Zak, linux-block, kernel-team, Ming Lei
On Fri, Aug 18, 2017 at 10:12:51AM +0200, Hannes Reinecke wrote:
> On 08/18/2017 10:05 AM, Omar Sandoval wrote:
> > On Fri, Aug 18, 2017 at 09:56:26AM +0200, Hannes Reinecke wrote:
> >> On 08/18/2017 09:47 AM, Omar Sandoval wrote:
> [ .. ]
> >>>
> >>> I actually checked losetup, it works just fine with LO_FLAGS_BLOCKSIZE
> >>> always set and lo_init[0] always filled in.
> >>>
> >> The original argument I had with the util-linux maintainer did not
> >> revolve so much around technical details :-)
> >
> > Karel, what were your concerns here?
> >
> It wasn't Karel, it was our guy.
> Doesn't make it any better, though...
I just went through the code and util-linux doesn't mention lo_init at
all except for the definition, and everywhere it's using lo_flags would
work fine with the behavior I implemented here. Unless there's an actual
issue someone can point out, I see no reason to not do it this way.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/2] loop: always return block size in LOOP_GET_STATUS
2017-08-18 8:22 ` Omar Sandoval
@ 2017-08-18 9:22 ` Karel Zak
2017-08-18 16:44 ` Omar Sandoval
2017-08-18 9:39 ` Karel Zak
1 sibling, 1 reply; 17+ messages in thread
From: Karel Zak @ 2017-08-18 9:22 UTC (permalink / raw)
To: Omar Sandoval; +Cc: Hannes Reinecke, linux-block, kernel-team, Ming Lei
On Fri, Aug 18, 2017 at 01:22:26AM -0700, Omar Sandoval wrote:
> On Fri, Aug 18, 2017 at 10:12:51AM +0200, Hannes Reinecke wrote:
> > On 08/18/2017 10:05 AM, Omar Sandoval wrote:
> > > On Fri, Aug 18, 2017 at 09:56:26AM +0200, Hannes Reinecke wrote:
> > >> On 08/18/2017 09:47 AM, Omar Sandoval wrote:
> > [ .. ]
> > >>>
> > >>> I actually checked losetup, it works just fine with LO_FLAGS_BLOCKSIZE
> > >>> always set and lo_init[0] always filled in.
> > >>>
> > >> The original argument I had with the util-linux maintainer did not
> > >> revolve so much around technical details :-)
> > >
> > > Karel, what were your concerns here?
> > >
> > It wasn't Karel, it was our guy.
> > Doesn't make it any better, though...
>
> I just went through the code and util-linux doesn't mention lo_init at
> all except for the definition, and everywhere it's using lo_flags would
> work fine with the behavior I implemented here. Unless there's an actual
> issue someone can point out, I see no reason to not do it this way.
Hmm.. we have loopdev API enhancement in Linus' tree and losetup
maintainer have no clue about it ;-)
Anyway, I like the idea with LO_FLAGS_BLOCKSIZE and lo_init[]. It
seems like a backwardly compatible way how to make loopdevs usable
for dd(1) images from non-512 devices, etc.
For now nothing uses lo_init[], so it seems no problem to use it for
LOOP_GET_STATUS64.
Note that we use LOOP_GET_STATUS64 and struct loop_info64 only, old API
around "struct loop_info" is no more used by util-linux.
The important detail is that for losetup (to show mapped devices) is
more important /sys than LOOP_GET_STATUS64. The /sys is better
because it does not require root permissions and it makes losetup
(and lsblk) usable for regular users.
I guess /sys/block/loopN/queue/minimum_io_size is affected by Hannes'
LO_FLAGS_BLOCKSIZE patches, so non-512 I/O sizes for loopdevs are
visible in "lsblk -t /dev/loopN" output, right?
I'll add --blocksize <size> to losetup, and BLKSZ column to output to
make the new feature usable also for end-users.
Thanks for CC:
Karel
--
Karel Zak <kzak@redhat.com>
http://karelzak.blogspot.com
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/2] loop: always return block size in LOOP_GET_STATUS
2017-08-18 8:22 ` Omar Sandoval
2017-08-18 9:22 ` Karel Zak
@ 2017-08-18 9:39 ` Karel Zak
1 sibling, 0 replies; 17+ messages in thread
From: Karel Zak @ 2017-08-18 9:39 UTC (permalink / raw)
To: Omar Sandoval; +Cc: Hannes Reinecke, linux-block, kernel-team, Ming Lei
On Fri, Aug 18, 2017 at 01:22:26AM -0700, Omar Sandoval wrote:
> On Fri, Aug 18, 2017 at 10:12:51AM +0200, Hannes Reinecke wrote:
> > On 08/18/2017 10:05 AM, Omar Sandoval wrote:
> > > On Fri, Aug 18, 2017 at 09:56:26AM +0200, Hannes Reinecke wrote:
> > >> On 08/18/2017 09:47 AM, Omar Sandoval wrote:
> > [ .. ]
> > >>>
> > >>> I actually checked losetup, it works just fine with LO_FLAGS_BLOCKSIZE
> > >>> always set and lo_init[0] always filled in.
> > >>>
> > >> The original argument I had with the util-linux maintainer did not
> > >> revolve so much around technical details :-)
> > >
> > > Karel, what were your concerns here?
> > >
> > It wasn't Karel, it was our guy.
> > Doesn't make it any better, though...
>
> I just went through the code and util-linux doesn't mention lo_init at
> all except for the definition, and everywhere it's using lo_flags would
> work fine with the behavior I implemented here. Unless there's an actual
> issue someone can point out, I see no reason to not do it this way.
BTW guys, it seems the current LO_FLAGS_BLOCKSIZE implementation does not
care about images from disks where is non-zero alignment offset. It
mean disks where is extra offset between logical and physical sectors
mapping. Something like:
modprobe scsi_debug dev_size_mb=100 sector_size=512 physblk_exp=3 lowest_aligned=7
...just pedantic note; IMHO it's fine to ignore this use-case ;-)
Karel
--
Karel Zak <kzak@redhat.com>
http://karelzak.blogspot.com
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/2] loop: always return block size in LOOP_GET_STATUS
2017-08-18 9:22 ` Karel Zak
@ 2017-08-18 16:44 ` Omar Sandoval
2017-08-18 17:25 ` Karel Zak
0 siblings, 1 reply; 17+ messages in thread
From: Omar Sandoval @ 2017-08-18 16:44 UTC (permalink / raw)
To: Karel Zak; +Cc: Hannes Reinecke, linux-block, kernel-team, Ming Lei
On Fri, Aug 18, 2017 at 11:22:39AM +0200, Karel Zak wrote:
> On Fri, Aug 18, 2017 at 01:22:26AM -0700, Omar Sandoval wrote:
> > On Fri, Aug 18, 2017 at 10:12:51AM +0200, Hannes Reinecke wrote:
> > > On 08/18/2017 10:05 AM, Omar Sandoval wrote:
> > > > On Fri, Aug 18, 2017 at 09:56:26AM +0200, Hannes Reinecke wrote:
> > > >> On 08/18/2017 09:47 AM, Omar Sandoval wrote:
> > > [ .. ]
> > > >>>
> > > >>> I actually checked losetup, it works just fine with LO_FLAGS_BLOCKSIZE
> > > >>> always set and lo_init[0] always filled in.
> > > >>>
> > > >> The original argument I had with the util-linux maintainer did not
> > > >> revolve so much around technical details :-)
> > > >
> > > > Karel, what were your concerns here?
> > > >
> > > It wasn't Karel, it was our guy.
> > > Doesn't make it any better, though...
> >
> > I just went through the code and util-linux doesn't mention lo_init at
> > all except for the definition, and everywhere it's using lo_flags would
> > work fine with the behavior I implemented here. Unless there's an actual
> > issue someone can point out, I see no reason to not do it this way.
>
> Hmm.. we have loopdev API enhancement in Linus' tree and losetup
> maintainer have no clue about it ;-)
Ha, glad you're hearing about it now before it's too late :)
> Anyway, I like the idea with LO_FLAGS_BLOCKSIZE and lo_init[]. It
> seems like a backwardly compatible way how to make loopdevs usable
> for dd(1) images from non-512 devices, etc.
>
> For now nothing uses lo_init[], so it seems no problem to use it for
> LOOP_GET_STATUS64.
Do you see any issues with the behavior I added in this patch? Namely,
LOOP_GET_STATUS{,64} will always return lo_flags with LO_FLAGS_BLOCKSIZE
set and lo_init[0] will always contain the blocksize. Older userspace
which doesn't know about LO_FLAGS_BLOCKSIZE will just ignore it and the
LOOP_GET_STATUS64; modify stuff; LOOP_SET_STATUS64 pattern will still
work.
> Note that we use LOOP_GET_STATUS64 and struct loop_info64 only, old API
> around "struct loop_info" is no more used by util-linux.
>
> The important detail is that for losetup (to show mapped devices) is
> more important /sys than LOOP_GET_STATUS64. The /sys is better
> because it does not require root permissions and it makes losetup
> (and lsblk) usable for regular users.
Ah, I'll spin a followup patch to add it to sysfs.
> I guess /sys/block/loopN/queue/minimum_io_size is affected by Hannes'
> LO_FLAGS_BLOCKSIZE patches, so non-512 I/O sizes for loopdevs are
> visible in "lsblk -t /dev/loopN" output, right?
Yup:
# lsblk -t /dev/loop0
NAME ALIGNMENT MIN-IO OPT-IO PHY-SEC LOG-SEC ROTA SCHED RQ-SIZE RA WSAME
loop0 0 4096 0 4096 4096 1 mq-deadline 256 128 0B
> I'll add --blocksize <size> to losetup, and BLKSZ column to output to
> make the new feature usable also for end-users.
Thank you!
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/2] loop: always return block size in LOOP_GET_STATUS
2017-08-18 16:44 ` Omar Sandoval
@ 2017-08-18 17:25 ` Karel Zak
0 siblings, 0 replies; 17+ messages in thread
From: Karel Zak @ 2017-08-18 17:25 UTC (permalink / raw)
To: Omar Sandoval; +Cc: Hannes Reinecke, linux-block, kernel-team, Ming Lei
On Fri, Aug 18, 2017 at 09:44:25AM -0700, Omar Sandoval wrote:
> On Fri, Aug 18, 2017 at 11:22:39AM +0200, Karel Zak wrote:
> > On Fri, Aug 18, 2017 at 01:22:26AM -0700, Omar Sandoval wrote:
> > > On Fri, Aug 18, 2017 at 10:12:51AM +0200, Hannes Reinecke wrote:
> > > > On 08/18/2017 10:05 AM, Omar Sandoval wrote:
> > > > > On Fri, Aug 18, 2017 at 09:56:26AM +0200, Hannes Reinecke wrote:
> > > > >> On 08/18/2017 09:47 AM, Omar Sandoval wrote:
> > > > [ .. ]
> > > > >>>
> > > > >>> I actually checked losetup, it works just fine with LO_FLAGS_BLOCKSIZE
> > > > >>> always set and lo_init[0] always filled in.
> > > > >>>
> > > > >> The original argument I had with the util-linux maintainer did not
> > > > >> revolve so much around technical details :-)
> > > > >
> > > > > Karel, what were your concerns here?
> > > > >
> > > > It wasn't Karel, it was our guy.
> > > > Doesn't make it any better, though...
> > >
> > > I just went through the code and util-linux doesn't mention lo_init at
> > > all except for the definition, and everywhere it's using lo_flags would
> > > work fine with the behavior I implemented here. Unless there's an actual
> > > issue someone can point out, I see no reason to not do it this way.
> >
> > Hmm.. we have loopdev API enhancement in Linus' tree and losetup
> > maintainer have no clue about it ;-)
>
> Ha, glad you're hearing about it now before it's too late :)
>
> > Anyway, I like the idea with LO_FLAGS_BLOCKSIZE and lo_init[]. It
> > seems like a backwardly compatible way how to make loopdevs usable
> > for dd(1) images from non-512 devices, etc.
> >
> > For now nothing uses lo_init[], so it seems no problem to use it for
> > LOOP_GET_STATUS64.
>
> Do you see any issues with the behavior I added in this patch? Namely,
> LOOP_GET_STATUS{,64} will always return lo_flags with LO_FLAGS_BLOCKSIZE
> set and lo_init[0] will always contain the blocksize. Older userspace
> which doesn't know about LO_FLAGS_BLOCKSIZE will just ignore it and the
> LOOP_GET_STATUS64; modify stuff; LOOP_SET_STATUS64 pattern will still
> work.
Yes, I think your idea is correct. All unknown flags should be ignored
by userspace. This is not the first time the API (lo_flags) is extended
by a new flag.
Karel
--
Karel Zak <kzak@redhat.com>
http://karelzak.blogspot.com
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2017-08-18 17:25 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-08-18 6:15 [PATCH 0/2] loop: LOOP_FLAGS_BLOCKSIZE fixes Omar Sandoval
2017-08-18 6:15 ` [PATCH 1/2] loop: always return block size in LOOP_GET_STATUS Omar Sandoval
2017-08-18 7:18 ` Hannes Reinecke
2017-08-18 7:38 ` Omar Sandoval
2017-08-18 7:43 ` Hannes Reinecke
2017-08-18 7:47 ` Omar Sandoval
2017-08-18 7:56 ` Hannes Reinecke
2017-08-18 8:05 ` Omar Sandoval
2017-08-18 8:12 ` Hannes Reinecke
2017-08-18 8:22 ` Omar Sandoval
2017-08-18 9:22 ` Karel Zak
2017-08-18 16:44 ` Omar Sandoval
2017-08-18 17:25 ` Karel Zak
2017-08-18 9:39 ` Karel Zak
2017-08-18 6:15 ` [PATCH 2/2] loop: fix hang if LOOP_SET_STATUS gets invalid blocksize or encrypt type Omar Sandoval
2017-08-18 7:20 ` Hannes Reinecke
2017-08-18 6:51 ` [PATCH 0/2] loop: LOOP_FLAGS_BLOCKSIZE fixes Omar Sandoval
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).