linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC] kref, a tiny, sane, reference count object
@ 2004-03-13  8:20 Greg KH
  2004-03-13  8:21 ` [PATCH] convert usb-serial core to use kref instead of kobject Greg KH
  2004-03-14  0:34 ` [RFC] kref, a tiny, sane, reference count object Andrew Morton
  0 siblings, 2 replies; 12+ messages in thread
From: Greg KH @ 2004-03-13  8:20 UTC (permalink / raw)
  To: linux-kernel

In thinking about people's complaints about the current kobject
interface, a lot of people don't like the "complexity" of what is
necessary to use a kobject.  If all you want is something to handle
reference counting properly, a kobject can seem a bit "large".

For all of those people, this patch is for you.  Introducing struct
kref.  A tiny (only 8 bytes on a 32bit platform) that will properly
handle reference counting any structure you want to use it for.  Note
that you will have to be careful around the cleanup period (but that can
be easily handled by the user with regards to not trying to grab a "new"
reference if you don't already have one, once the object is gone, just
like kobjects and sysfs today work.)

I've implemented kobjects using a kref to handle the reference counting
portion, but will leave that patch and change for 2.7, as it will add 4
more bytes (on a 32bit platform) to every kobject, and that wouldn't be
nice this early in the 2.6 series.  For now, krefs can stand on their
own.

I've already found loads of places in the kernel that can use this
structure to clean up their logic, and will probably be converting a
number of them over time to use them.  But no, Al, I will not say this
can be used to replace the atomic_t count you have in inodes, as that
count is horribly abused in ways I never really wanted to know about
(negative counts mean something "special"?  eeeeeek....)

Anyway, here's a patch against 2.6.4 that adds krefs to the kernel.
I'll follow up with a patch that converts the usb-serial core from using
kobjects to using krefs instead.

Comments are appreciated and welcomed.

thanks,

greg k-h


diff -Nru a/include/linux/kref.h b/include/linux/kref.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/kref.h	Sat Mar 13 00:04:46 2004
@@ -0,0 +1,32 @@
+/*
+ * kref.c - library routines for handling generic reference counted objects
+ *
+ * Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com>
+ * Copyright (C) 2004 IBM Corp.
+ *
+ * based on kobject.h which was:
+ * Copyright (C) 2002-2003 Patrick Mochel <mochel@osdl.org>
+ * Copyright (C) 2002-2003 Open Source Development Labs
+ *
+ * This file is released under the GPLv2.
+ *
+ */
+
+#if defined(__KERNEL__) && !defined(_KREF_H_)
+#define _KREF_H_
+
+#include <linux/types.h>
+#include <asm/atomic.h>
+
+
+struct kref {
+	atomic_t refcount;
+	void (*release)(struct kref *kref);
+};
+
+void kref_init(struct kref *kref, void (*release)(struct kref *));
+struct kref *kref_get(struct kref *kref);
+void kref_put(struct kref *kref);
+
+
+#endif /* _KREF_H_ */
diff -Nru a/lib/Makefile b/lib/Makefile
--- a/lib/Makefile	Sat Mar 13 00:04:42 2004
+++ b/lib/Makefile	Sat Mar 13 00:04:42 2004
@@ -8,6 +8,9 @@
 	 kobject.o idr.o div64.o parser.o int_sqrt.o \
 	 bitmap.o extable.o
 
+# hack for now till some static code uses krefs, then it can move up above...
+obj-y += kref.o
+
 lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o
 lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o
 
diff -Nru a/lib/kref.c b/lib/kref.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/lib/kref.c	Sat Mar 13 00:04:46 2004
@@ -0,0 +1,76 @@
+/*
+ * kref.c - library routines for handling generic reference counted objects
+ *
+ * Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com>
+ * Copyright (C) 2004 IBM Corp.
+ *
+ * based on lib/kobject.c which was:
+ * Copyright (C) 2002-2003 Patrick Mochel <mochel@osdl.org>
+ *
+ * This file is released under the GPLv2.
+ *
+ */
+
+/* #define DEBUG */
+
+#include <linux/kref.h>
+#include <linux/module.h>
+
+
+/**
+ * kref_init - initialize object.
+ * @kref: object in question.
+ */
+void kref_init(struct kref *kref, void (*release)(struct kref *kref))
+{
+	atomic_set(&kref->refcount,1);
+	kref->release = release;
+}
+
+/**
+ * kref_get - increment refcount for object.
+ * @kref: object.
+ */
+struct kref * kref_get(struct kref *kref)
+{
+	if (kref) {
+		WARN_ON(!atomic_read(&kref->refcount));
+		atomic_inc(&kref->refcount);
+	}
+	return kref;
+}
+
+/**
+ * kref_cleanup - free kref resources. 
+ * @kref: object.
+ */
+void kref_cleanup(struct kref *kref)
+{
+	if (!kref)
+		return;
+
+	pr_debug("kref cleaning up\n");
+	if (kref->release)
+		kref->release(kref);
+	else {
+		printk(KERN_ERR "kref does not have a release() function, "
+			"it is broken and must be fixed.\n");
+		WARN_ON(1);
+	}
+}
+
+/**
+ * kref_put - decrement refcount for object.
+ * @kref: object.
+ *
+ * Decrement the refcount, and if 0, call kref_cleanup().
+ */
+void kref_put(struct kref *kref)
+{
+	if (atomic_dec_and_test(&kref->refcount))
+		kref_cleanup(kref);
+}
+
+EXPORT_SYMBOL(kref_init);
+EXPORT_SYMBOL(kref_get);
+EXPORT_SYMBOL(kref_put);

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH] convert usb-serial core to use kref instead of kobject
  2004-03-13  8:20 [RFC] kref, a tiny, sane, reference count object Greg KH
@ 2004-03-13  8:21 ` Greg KH
  2004-03-14  0:34 ` [RFC] kref, a tiny, sane, reference count object Andrew Morton
  1 sibling, 0 replies; 12+ messages in thread
From: Greg KH @ 2004-03-13  8:21 UTC (permalink / raw)
  To: linux-kernel

> I'll follow up with a patch that converts the usb-serial core from using
> kobjects to using krefs instead.

And here is that patch.

thanks,

greg k-h


diff -Nru a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
--- a/drivers/usb/serial/usb-serial.c	Sat Mar 13 00:04:44 2004
+++ b/drivers/usb/serial/usb-serial.c	Sat Mar 13 00:04:44 2004
@@ -391,7 +391,7 @@
 	struct usb_serial *serial = serial_table[index];
 
 	if (serial)
-		kobject_get (&serial->kobj);
+		kref_get(&serial->kref);
 	return serial;
 }
 
@@ -486,7 +486,7 @@
 		if (retval) {
 			port->open_count = 0;
 			module_put(serial->type->owner);
-			kobject_put(&serial->kobj);
+			kref_put(&serial->kref);
 		}
 	}
 bailout:
@@ -518,7 +518,7 @@
 	}
 
 	module_put(port->serial->type->owner);
-	kobject_put(&port->serial->kobj);
+	kref_put(&port->serial->kref);
 }
 
 static int serial_write (struct tty_struct * tty, int from_user, const unsigned char *buf, int count)
@@ -748,7 +748,7 @@
 			begin += length;
 			length = 0;
 		}
-		kobject_put(&serial->kobj);
+		kref_put(&serial->kref);
 	}
 	*eof = 1;
 done:
@@ -830,15 +830,15 @@
 	wake_up_interruptible(&tty->write_wait);
 }
 
-static void destroy_serial (struct kobject *kobj)
+static void destroy_serial(struct kref *kref)
 {
 	struct usb_serial *serial;
 	struct usb_serial_port *port;
 	int i;
 
-	dbg ("%s - %s", __FUNCTION__, kobj->name);
+	serial = to_usb_serial(kref);
 
-	serial = to_usb_serial(kobj);
+	dbg ("%s - %s", __FUNCTION__, serial->type->name);
 	serial_shutdown (serial);
 
 	/* return the minor range that this device had */
@@ -886,10 +886,6 @@
 	kfree (serial);
 }
 
-static struct kobj_type usb_serial_kobj_type = {
-	.release = destroy_serial,
-};
-
 static void port_release(struct device *dev)
 {
 	struct usb_serial_port *port = to_usb_serial_port(dev);
@@ -930,10 +926,7 @@
 	serial->interface = interface;
 	serial->vendor = dev->descriptor.idVendor;
 	serial->product = dev->descriptor.idProduct;
-
-	/* initialize the kobject portion of the usb_device */
-	kobject_init(&serial->kobj);
-	serial->kobj.ktype = &usb_serial_kobj_type;
+	kref_init(&serial->kref, destroy_serial);
 
 	return serial;
 }
@@ -1284,7 +1277,7 @@
 	if (serial) {
 		/* let the last holder of this object 
 		 * cause it to be cleaned up */
-		kobject_put (&serial->kobj);
+		kref_put(&serial->kref);
 	}
 	dev_info(dev, "device disconnected\n");
 }
diff -Nru a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h
--- a/drivers/usb/serial/usb-serial.h	Sat Mar 13 00:04:33 2004
+++ b/drivers/usb/serial/usb-serial.h	Sat Mar 13 00:04:33 2004
@@ -55,6 +55,7 @@
 #define __LINUX_USB_SERIAL_H
 
 #include <linux/config.h>
+#include <linux/kref.h>
 
 #define SERIAL_TTY_MAJOR	188	/* Nice legal number now */
 #define SERIAL_TTY_MINORS	255	/* loads of devices :) */
@@ -163,10 +164,10 @@
 	__u16				vendor;
 	__u16				product;
 	struct usb_serial_port *	port[MAX_NUM_PORTS];
-	struct kobject			kobj;
+	struct kref			kref;
 	void *				private;
 };
-#define to_usb_serial(d) container_of(d, struct usb_serial, kobj)
+#define to_usb_serial(d) container_of(d, struct usb_serial, kref)
 
 #define NUM_DONT_CARE	(-1)
 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFC] kref, a tiny, sane, reference count object
  2004-03-13  8:20 [RFC] kref, a tiny, sane, reference count object Greg KH
  2004-03-13  8:21 ` [PATCH] convert usb-serial core to use kref instead of kobject Greg KH
@ 2004-03-14  0:34 ` Andrew Morton
  2004-03-14  2:55   ` Greg KH
  2004-03-14  3:30   ` Nick Piggin
  1 sibling, 2 replies; 12+ messages in thread
From: Andrew Morton @ 2004-03-14  0:34 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-kernel

Greg KH <greg@kroah.com> wrote:
>
> For all of those people, this patch is for you.

It does rather neatly capture a common idiom.

> +struct kref * kref_get(struct kref *kref)
> +{
> +	if (kref) {
> +		WARN_ON(!atomic_read(&kref->refcount));
> +		atomic_inc(&kref->refcount);
> +	}
> +	return kref;
> +}

Why is a NULL arg permitted here?

> +void kref_cleanup(struct kref *kref)
> +{
> +	if (!kref)
> +		return;

and here?

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFC] kref, a tiny, sane, reference count object
  2004-03-14  0:34 ` [RFC] kref, a tiny, sane, reference count object Andrew Morton
@ 2004-03-14  2:55   ` Greg KH
  2004-03-14  3:30   ` Nick Piggin
  1 sibling, 0 replies; 12+ messages in thread
From: Greg KH @ 2004-03-14  2:55 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel

On Sat, Mar 13, 2004 at 04:34:51PM -0800, Andrew Morton wrote:
> > +struct kref * kref_get(struct kref *kref)
> > +{
> > +	if (kref) {
> > +		WARN_ON(!atomic_read(&kref->refcount));
> > +		atomic_inc(&kref->refcount);
> > +	}
> > +	return kref;
> > +}
> 
> Why is a NULL arg permitted here?

Because kobjects permitted it?  :)

I think you are correct, if we are passing a NULL pointer to these
functions, we deserve the oops we get, as other, much worse things could
happen (as a kref lives inside another structure.)

I'll go take those checks out.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFC] kref, a tiny, sane, reference count object
  2004-03-14  0:34 ` [RFC] kref, a tiny, sane, reference count object Andrew Morton
  2004-03-14  2:55   ` Greg KH
@ 2004-03-14  3:30   ` Nick Piggin
  2004-03-14  4:10     ` Andrew Morton
  1 sibling, 1 reply; 12+ messages in thread
From: Nick Piggin @ 2004-03-14  3:30 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Greg KH, linux-kernel, Andi Kleen



Andrew Morton wrote:

>Greg KH <greg@kroah.com> wrote:
>
>>For all of those people, this patch is for you.
>>
>
>It does rather neatly capture a common idiom.
>

But as Andi said - look at all the crap involved when:

atomic_inc();
if (atomic_dec_and_test())
    release();
Also neatly captures that idiom.

And you get more flexibility by being able to use atomic_set
directly too.


But if you really like it, I agree it shouldn't allow NULL
pointers and probably get, put and cleanup should be inline.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFC] kref, a tiny, sane, reference count object
  2004-03-14  3:30   ` Nick Piggin
@ 2004-03-14  4:10     ` Andrew Morton
  2004-03-14  4:20       ` Nick Piggin
  0 siblings, 1 reply; 12+ messages in thread
From: Andrew Morton @ 2004-03-14  4:10 UTC (permalink / raw)
  To: Nick Piggin; +Cc: greg, linux-kernel, ak

Nick Piggin <piggin@cyberone.com.au> wrote:
>
> 
> 
> Andrew Morton wrote:
> 
> >Greg KH <greg@kroah.com> wrote:
> >
> >>For all of those people, this patch is for you.
> >>
> >
> >It does rather neatly capture a common idiom.
> >
> 
> But as Andi said - look at all the crap involved when:
> 
> atomic_inc();
> if (atomic_dec_and_test())
>     release();
> Also neatly captures that idiom.

Well it does more than that, such as trapping the hard-to-diagnose bug
of grabbing a refcount against a zero-ref object.

> And you get more flexibility by being able to use atomic_set
> directly too.

Do I care about that?  I care more about being able to say "ah, it uses
kref.  I understand that refcounting idiom, I know it's well debugged and I
know that it traps common errors".  That's better than "oh crap, this thing
implements its own refcounting - I need to review it for the usual
errors".



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFC] kref, a tiny, sane, reference count object
  2004-03-14  4:10     ` Andrew Morton
@ 2004-03-14  4:20       ` Nick Piggin
  0 siblings, 0 replies; 12+ messages in thread
From: Nick Piggin @ 2004-03-14  4:20 UTC (permalink / raw)
  To: Andrew Morton; +Cc: greg, linux-kernel, ak



Andrew Morton wrote:

>Nick Piggin <piggin@cyberone.com.au> wrote:
>
>>
>>
>>Andrew Morton wrote:
>>
>>
>>>Greg KH <greg@kroah.com> wrote:
>>>
>>>
>>>>For all of those people, this patch is for you.
>>>>
>>>>
>>>It does rather neatly capture a common idiom.
>>>
>>>
>>But as Andi said - look at all the crap involved when:
>>
>>atomic_inc();
>>if (atomic_dec_and_test())
>>    release();
>>Also neatly captures that idiom.
>>
>
>Well it does more than that, such as trapping the hard-to-diagnose bug
>of grabbing a refcount against a zero-ref object.
>
>
>>And you get more flexibility by being able to use atomic_set
>>directly too.
>>
>
>Do I care about that?  I care more about being able to say "ah, it uses
>kref.  I understand that refcounting idiom, I know it's well debugged and I
>know that it traps common errors".  That's better than "oh crap, this thing
>implements its own refcounting - I need to review it for the usual
>errors".
>
>

OK good point.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFC] kref, a tiny, sane, reference count object
       [not found]   ` <1zm3F-2ex-7@gated-at.bofh.it>
@ 2004-03-13 20:43     ` Andi Kleen
  0 siblings, 0 replies; 12+ messages in thread
From: Andi Kleen @ 2004-03-13 20:43 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-kernel

Greg KH <greg@kroah.com> writes:

> But people do get it wrong (I've seen it happen).  Using this keeps you

If they cannot get a simple reference counter right it is doubtful
the rest of their code will do any good.

> from having to write your own get, and put functions.  Multiply that by
> every usb driver that wants to (and needs to) use this kind of logic,
> and you have a lot of duplicated code that is unnecessary.

Lots of duplicated one liners. Sounds like a big issue.
For me this thing smells more like overabstraction.

> So we write it once, get it correct, and let everyone use it.  Isn't
> that what the code in /lib is for?  :)

I would agree if it is significant code. But all you're replacing is a
few straight forward one/two liners, and that at the cost of less
efficient space usage (12 byte overhead on 64bit)

-Andi


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFC] kref, a tiny, sane, reference count object
  2004-03-13  9:10 Peter Kjellerstedt
@ 2004-03-13 18:15 ` Greg KH
  0 siblings, 0 replies; 12+ messages in thread
From: Greg KH @ 2004-03-13 18:15 UTC (permalink / raw)
  To: Peter Kjellerstedt; +Cc: linux-kernel

On Sat, Mar 13, 2004 at 10:10:36AM +0100, Peter Kjellerstedt wrote:
> Looks simple enough.  But I have a small question. 
> In kref_get() and kref_cleanup(), kref is verified 
> not to be NULL before being used.  However, this is 
> not done in kref_put().  An oversight, or as intended?

An oversight, thanks for pointing it out.  I'll go fix it up.

thanks again,

greg k-h

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFC] kref, a tiny, sane, reference count object
  2004-03-13 13:06 ` Andi Kleen
@ 2004-03-13 18:14   ` Greg KH
  0 siblings, 0 replies; 12+ messages in thread
From: Greg KH @ 2004-03-13 18:14 UTC (permalink / raw)
  To: Andi Kleen; +Cc: linux-kernel

On Sat, Mar 13, 2004 at 02:06:56PM +0100, Andi Kleen wrote:
> Greg KH <greg@kroah.com> writes:
> 
> > Comments are appreciated and welcomed.
> 
> I really don't see the advantage of this. Writing the same using
> atomic_inc/ atomic_dec_and_test() implicitely is basically as clean,
> and you will save the overhead of carrying a release() pointer
> around. And the "patterns" for that are easy enough that I doubt
> people will get it wrong.

But people do get it wrong (I've seen it happen).  Using this keeps you
from having to write your own get, and put functions.  Multiply that by
every usb driver that wants to (and needs to) use this kind of logic,
and you have a lot of duplicated code that is unnecessary.

So we write it once, get it correct, and let everyone use it.  Isn't
that what the code in /lib is for?  :)

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFC] kref, a tiny, sane, reference count object
       [not found] <1zcH2-KO-11@gated-at.bofh.it>
@ 2004-03-13 13:06 ` Andi Kleen
  2004-03-13 18:14   ` Greg KH
  0 siblings, 1 reply; 12+ messages in thread
From: Andi Kleen @ 2004-03-13 13:06 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-kernel

Greg KH <greg@kroah.com> writes:

> Comments are appreciated and welcomed.

I really don't see the advantage of this. Writing the same using
atomic_inc/ atomic_dec_and_test() implicitely is basically as clean,
and you will save the overhead of carrying a release() pointer
around. And the "patterns" for that are easy enough that I doubt
people will get it wrong.

-Andi



^ permalink raw reply	[flat|nested] 12+ messages in thread

* RE: [RFC] kref, a tiny, sane, reference count object
@ 2004-03-13  9:10 Peter Kjellerstedt
  2004-03-13 18:15 ` Greg KH
  0 siblings, 1 reply; 12+ messages in thread
From: Peter Kjellerstedt @ 2004-03-13  9:10 UTC (permalink / raw)
  To: Greg KH, linux-kernel

> -----Original Message-----
> From: linux-kernel-owner@vger.kernel.org 
> [mailto:linux-kernel-owner@vger.kernel.org] On Behalf Of Greg KH
> Sent: Saturday, March 13, 2004 09:20
> To: linux-kernel@vger.kernel.org
> Subject: [RFC] kref, a tiny, sane, reference count object
> 
> In thinking about people's complaints about the current 
> kobject interface, a lot of people don't like the 
> "complexity" of what is necessary to use a kobject.
> If all you want is something to handle reference 
> counting properly, a kobject can seem a bit "large".
> 
> For all of those people, this patch is for you.  
> Introducing struct kref.  A tiny (only 8 bytes on a 
> 32bit platform) that will properly handle reference 
> counting any structure you want to use it for.  Note 
> that you will have to be careful around the cleanup 
> period (but that can be easily handled by the user 
> with regards to not trying to grab a "new" reference
> if you don't already have one, once the object is 
> gone, just like kobjects and sysfs today work.)
> 
> I've implemented kobjects using a kref to handle the 
> reference counting portion, but will leave that patch
> and change for 2.7, as it will add 4 more bytes (on a 
> 32bit platform) to every kobject, and that wouldn't 
> be nice this early in the 2.6 series.  For now, krefs 
> can stand on their own.
> 
> I've already found loads of places in the kernel that 
> can use this structure to clean up their logic, and 
> will probably be converting a number of them over time 
> to use them.  But no, Al, I will not say this can be 
> used to replace the atomic_t count you have in inodes, 
> as that count is horribly abused in ways I never really 
> wanted to know about (negative counts mean something 
> "special"?  eeeeeek....)
> 
> Anyway, here's a patch against 2.6.4 that adds krefs
> to the kernel.  I'll follow up with a patch that 
> converts the usb-serial core from using kobjects to 
> using krefs instead.
> 
> Comments are appreciated and welcomed.
> 
> thanks,
> 
> greg k-h

Looks simple enough.  But I have a small question. 
In kref_get() and kref_cleanup(), kref is verified 
not to be NULL before being used.  However, this is 
not done in kref_put().  An oversight, or as intended?

//Peter

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2004-03-14 17:00 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-03-13  8:20 [RFC] kref, a tiny, sane, reference count object Greg KH
2004-03-13  8:21 ` [PATCH] convert usb-serial core to use kref instead of kobject Greg KH
2004-03-14  0:34 ` [RFC] kref, a tiny, sane, reference count object Andrew Morton
2004-03-14  2:55   ` Greg KH
2004-03-14  3:30   ` Nick Piggin
2004-03-14  4:10     ` Andrew Morton
2004-03-14  4:20       ` Nick Piggin
2004-03-13  9:10 Peter Kjellerstedt
2004-03-13 18:15 ` Greg KH
     [not found] <1zcH2-KO-11@gated-at.bofh.it>
2004-03-13 13:06 ` Andi Kleen
2004-03-13 18:14   ` Greg KH
     [not found] <1zhdz-5uL-3@gated-at.bofh.it>
     [not found] ` <1zhdz-5uL-1@gated-at.bofh.it>
     [not found]   ` <1zm3F-2ex-7@gated-at.bofh.it>
2004-03-13 20:43     ` Andi Kleen

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).