<feed xmlns='http://www.w3.org/2005/Atom'>
<title>user/sven/linux.git/include/linux/kernfs.h, branch v3.16.68</title>
<subtitle>Linux Kernel
</subtitle>
<id>https://git.stealer.net/cgit.cgi/user/sven/linux.git/atom?h=v3.16.68</id>
<link rel='self' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/atom?h=v3.16.68'/>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/'/>
<updated>2015-07-15T09:01:07Z</updated>
<entry>
<title>kernfs: Add support for always empty directories.</title>
<updated>2015-07-15T09:01:07Z</updated>
<author>
<name>Eric W. Biederman</name>
<email>ebiederm@xmission.com</email>
</author>
<published>2015-05-13T21:09:29Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=4e6378f17c02560f052a0fae6e7c2fc1647d06ba'/>
<id>urn:sha1:4e6378f17c02560f052a0fae6e7c2fc1647d06ba</id>
<content type='text'>
commit ea015218f2f7ace2dad9cedd21ed95bdba2886d7 upstream.

Add a new function kernfs_create_empty_dir that can be used to create
directory that can not be modified.

Update the code to use make_empty_dir_inode when reporting a
permanently empty directory to the vfs.

Update the code to not allow adding to permanently empty directories.

Signed-off-by: "Eric W. Biederman" &lt;ebiederm@xmission.com&gt;
Signed-off-by: Luis Henriques &lt;luis.henriques@canonical.com&gt;
</content>
</entry>
<entry>
<title>Merge branch 'for-3.16-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup</title>
<updated>2014-07-10T18:38:23Z</updated>
<author>
<name>Linus Torvalds</name>
<email>torvalds@linux-foundation.org</email>
</author>
<published>2014-07-10T18:38:23Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=40f6123737d45b94ae0e4c89252a695ba6794e59'/>
<id>urn:sha1:40f6123737d45b94ae0e4c89252a695ba6794e59</id>
<content type='text'>
Pull cgroup fixes from Tejun Heo:
 "Mostly fixes for the fallouts from the recent cgroup core changes.

  The decoupled nature of cgroup dynamic hierarchy management
  (hierarchies are created dynamically on mount but may or may not be
  reused once unmounted depending on remaining usages) led to more
  ugliness being added to kernfs.

  Hopefully, this is the last of it"

* 'for-3.16-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup:
  cpuset: break kernfs active protection in cpuset_write_resmask()
  cgroup: fix a race between cgroup_mount() and cgroup_kill_sb()
  kernfs: introduce kernfs_pin_sb()
  cgroup: fix mount failure in a corner case
  cpuset,mempolicy: fix sleeping function called from invalid context
  cgroup: fix broken css_has_online_children()
</content>
</entry>
<entry>
<title>kernfs: kernfs_notify() must be useable from non-sleepable contexts</title>
<updated>2014-07-02T16:32:09Z</updated>
<author>
<name>Tejun Heo</name>
<email>tj@kernel.org</email>
</author>
<published>2014-07-01T20:41:03Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=ecca47ce8294843045e7465d76fee84dbf07a004'/>
<id>urn:sha1:ecca47ce8294843045e7465d76fee84dbf07a004</id>
<content type='text'>
d911d9874801 ("kernfs: make kernfs_notify() trigger inotify events
too") added fsnotify triggering to kernfs_notify() which requires a
sleepable context.  There are already existing users of
kernfs_notify() which invoke it from an atomic context and in general
it's silly to require a sleepable context for triggering a
notification.

The following is an invalid context bug triggerd by md invoking
sysfs_notify() from IO completion path.

 BUG: sleeping function called from invalid context at kernel/locking/mutex.c:586
 in_atomic(): 1, irqs_disabled(): 1, pid: 0, name: swapper/1
 2 locks held by swapper/1/0:
  #0:  (&amp;(&amp;vblk-&gt;vq_lock)-&gt;rlock){-.-...}, at: [&lt;ffffffffa0039042&gt;] virtblk_done+0x42/0xe0 [virtio_blk]
  #1:  (&amp;(&amp;bitmap-&gt;counts.lock)-&gt;rlock){-.....}, at: [&lt;ffffffff81633718&gt;] bitmap_endwrite+0x68/0x240
 irq event stamp: 33518
 hardirqs last  enabled at (33515): [&lt;ffffffff8102544f&gt;] default_idle+0x1f/0x230
 hardirqs last disabled at (33516): [&lt;ffffffff818122ed&gt;] common_interrupt+0x6d/0x72
 softirqs last  enabled at (33518): [&lt;ffffffff810a1272&gt;] _local_bh_enable+0x22/0x50
 softirqs last disabled at (33517): [&lt;ffffffff810a29e0&gt;] irq_enter+0x60/0x80
 CPU: 1 PID: 0 Comm: swapper/1 Not tainted 3.16.0-0.rc2.git2.1.fc21.x86_64 #1
 Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
  0000000000000000 f90db13964f4ee05 ffff88007d403b80 ffffffff81807b4c
  0000000000000000 ffff88007d403ba8 ffffffff810d4f14 0000000000000000
  0000000000441800 ffff880078fa1780 ffff88007d403c38 ffffffff8180caf2
 Call Trace:
  &lt;IRQ&gt;  [&lt;ffffffff81807b4c&gt;] dump_stack+0x4d/0x66
  [&lt;ffffffff810d4f14&gt;] __might_sleep+0x184/0x240
  [&lt;ffffffff8180caf2&gt;] mutex_lock_nested+0x42/0x440
  [&lt;ffffffff812d76a0&gt;] kernfs_notify+0x90/0x150
  [&lt;ffffffff8163377c&gt;] bitmap_endwrite+0xcc/0x240
  [&lt;ffffffffa00de863&gt;] close_write+0x93/0xb0 [raid1]
  [&lt;ffffffffa00df029&gt;] r1_bio_write_done+0x29/0x50 [raid1]
  [&lt;ffffffffa00e0474&gt;] raid1_end_write_request+0xe4/0x260 [raid1]
  [&lt;ffffffff813acb8b&gt;] bio_endio+0x6b/0xa0
  [&lt;ffffffff813b46c4&gt;] blk_update_request+0x94/0x420
  [&lt;ffffffff813bf0ea&gt;] blk_mq_end_io+0x1a/0x70
  [&lt;ffffffffa00392c2&gt;] virtblk_request_done+0x32/0x80 [virtio_blk]
  [&lt;ffffffff813c0648&gt;] __blk_mq_complete_request+0x88/0x120
  [&lt;ffffffff813c070a&gt;] blk_mq_complete_request+0x2a/0x30
  [&lt;ffffffffa0039066&gt;] virtblk_done+0x66/0xe0 [virtio_blk]
  [&lt;ffffffffa002535a&gt;] vring_interrupt+0x3a/0xa0 [virtio_ring]
  [&lt;ffffffff81116177&gt;] handle_irq_event_percpu+0x77/0x340
  [&lt;ffffffff8111647d&gt;] handle_irq_event+0x3d/0x60
  [&lt;ffffffff81119436&gt;] handle_edge_irq+0x66/0x130
  [&lt;ffffffff8101c3e4&gt;] handle_irq+0x84/0x150
  [&lt;ffffffff818146ad&gt;] do_IRQ+0x4d/0xe0
  [&lt;ffffffff818122f2&gt;] common_interrupt+0x72/0x72
  &lt;EOI&gt;  [&lt;ffffffff8105f706&gt;] ? native_safe_halt+0x6/0x10
  [&lt;ffffffff81025454&gt;] default_idle+0x24/0x230
  [&lt;ffffffff81025f9f&gt;] arch_cpu_idle+0xf/0x20
  [&lt;ffffffff810f5adc&gt;] cpu_startup_entry+0x37c/0x7b0
  [&lt;ffffffff8104df1b&gt;] start_secondary+0x25b/0x300

This patch fixes it by punting the notification delivery through a
work item.  This ends up adding an extra pointer to kernfs_elem_attr
enlarging kernfs_node by a pointer, which is not ideal but not a very
big deal either.  If this turns out to be an actual issue, we can move
kernfs_elem_attr-&gt;size to kernfs_node-&gt;iattr later.

Signed-off-by: Tejun Heo &lt;tj@kernel.org&gt;
Reported-by: Josh Boyer &lt;jwboyer@fedoraproject.org&gt;
Cc: Jens Axboe &lt;axboe@kernel.dk&gt;
Reviewed-by: Michael S. Tsirkin &lt;mst@redhat.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>kernfs: introduce kernfs_pin_sb()</title>
<updated>2014-06-30T14:16:25Z</updated>
<author>
<name>Li Zefan</name>
<email>lizefan@huawei.com</email>
</author>
<published>2014-06-30T03:50:28Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=4e26445faad366d67d7723622bf6a60a6f0f5993'/>
<id>urn:sha1:4e26445faad366d67d7723622bf6a60a6f0f5993</id>
<content type='text'>
kernfs_pin_sb() tries to get a refcnt of the superblock.

This will be used by cgroupfs.

v2:
- make kernfs_pin_sb() return the superblock.
- drop kernfs_drop_sb().

tj: Updated the comment a bit.

[ This is a prerequisite for a bugfix. ]
Cc: &lt;stable@vger.kernel.org&gt; # 3.15
Acked-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
Signed-off-by: Li Zefan &lt;lizefan@huawei.com&gt;
Signed-off-by: Tejun Heo &lt;tj@kernel.org&gt;
</content>
</entry>
<entry>
<title>kernfs: move the last knowledge of sysfs out from kernfs</title>
<updated>2014-05-27T21:33:17Z</updated>
<author>
<name>Jianyu Zhan</name>
<email>nasa4836@gmail.com</email>
</author>
<published>2014-04-26T07:40:28Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=26fc9cd200ec839e0b3095e05ae018f27314e7aa'/>
<id>urn:sha1:26fc9cd200ec839e0b3095e05ae018f27314e7aa</id>
<content type='text'>
There is still one residue of sysfs remaining: the sb_magic
SYSFS_MAGIC. However this should be kernfs user specific,
so this patch moves it out. Kerrnfs user should specify their
magic number while mouting.

Signed-off-by: Jianyu Zhan &lt;nasa4836@gmail.com&gt;
Acked-by: Tejun Heo &lt;tj@kernel.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>Merge 3.15-rc6 into driver-core-next</title>
<updated>2014-05-23T01:13:53Z</updated>
<author>
<name>Greg Kroah-Hartman</name>
<email>gregkh@linuxfoundation.org</email>
</author>
<published>2014-05-23T01:13:53Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=cbfef53360ea88fa7ef9f80def778fba9b05d21e'/>
<id>urn:sha1:cbfef53360ea88fa7ef9f80def778fba9b05d21e</id>
<content type='text'>
We want the kernfs fixes in this branch as well for testing.

Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>kernfs, sysfs, cgroup: restrict extra perm check on open to sysfs</title>
<updated>2014-05-13T11:21:40Z</updated>
<author>
<name>Tejun Heo</name>
<email>tj@kernel.org</email>
</author>
<published>2014-05-12T17:56:27Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=555724a831b4a146e7bdf16ecc989cda032b076d'/>
<id>urn:sha1:555724a831b4a146e7bdf16ecc989cda032b076d</id>
<content type='text'>
The kernfs open method - kernfs_fop_open() - inherited extra
permission checks from sysfs.  While the vfs layer allows ignoring the
read/write permissions checks if the issuer has CAP_DAC_OVERRIDE,
sysfs explicitly denied open regardless of the cap if the file doesn't
have any of the UGO perms of the requested access or doesn't implement
the requested operation.  It can be debated whether this was a good
idea or not but the behavior is too subtle and dangerous to change at
this point.

After cgroup got converted to kernfs, this extra perm check also got
applied to cgroup breaking libcgroup which opens write-only files with
O_RDWR as root.  This patch gates the extra open permission check with
a new flag KERNFS_ROOT_EXTRA_OPEN_PERM_CHECK and enables it for sysfs.
For sysfs, nothing changes.  For cgroup, root now can perform any
operation regardless of the permissions as it was before kernfs
conversion.  Note that kernfs still fails unimplemented operations
with -EINVAL.

While at it, add comments explaining KERNFS_ROOT flags.

Signed-off-by: Tejun Heo &lt;tj@kernel.org&gt;
Reported-by: Andrey Wagin &lt;avagin@gmail.com&gt;
Tested-by: Andrey Wagin &lt;avagin@gmail.com&gt;
Cc: Li Zefan &lt;lizefan@huawei.com&gt;
References: http://lkml.kernel.org/g/CANaxB-xUm3rJ-Cbp72q-rQJO5mZe1qK6qXsQM=vh0U8upJ44+A@mail.gmail.com
Fixes: 2bd59d48ebfb ("cgroup: convert to kernfs")
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>kernfs: implement kernfs_root-&gt;supers list</title>
<updated>2014-04-25T18:43:31Z</updated>
<author>
<name>Tejun Heo</name>
<email>tj@kernel.org</email>
</author>
<published>2014-04-09T15:07:30Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=7d568a8383bbb9c1f5167781075906acb2bb1550'/>
<id>urn:sha1:7d568a8383bbb9c1f5167781075906acb2bb1550</id>
<content type='text'>
Currently, there's no way to find out which super_blocks are
associated with a given kernfs_root.  Let's implement it - the planned
inotify extension to kernfs_notify() needs it.

Make kernfs_super_info point back to the super_block and chain it at
kernfs_root-&gt;supers.

Signed-off-by: Tejun Heo &lt;tj@kernel.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>kernfs: cache atomic_write_len in kernfs_open_file</title>
<updated>2014-03-09T06:08:29Z</updated>
<author>
<name>Tejun Heo</name>
<email>tj@kernel.org</email>
</author>
<published>2014-03-04T20:38:46Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=b7ce40cff0b9f6597f8318fd761accd92727f61f'/>
<id>urn:sha1:b7ce40cff0b9f6597f8318fd761accd92727f61f</id>
<content type='text'>
While implementing atomic_write_len, 4d3773c4bb41 ("kernfs: implement
kernfs_ops-&gt;atomic_write_len") moved data copy from userland inside
kernfs_get_active() and kernfs_open_file-&gt;mutex so that
kernfs_ops-&gt;atomic_write_len can be accessed before copying buffer
from userland; unfortunately, this could lead to locking order
inversion involving mmap_sem if copy_from_user() takes a page fault.

  ======================================================
  [ INFO: possible circular locking dependency detected ]
  3.14.0-rc4-next-20140228-sasha-00011-g4077c67-dirty #26 Tainted: G        W
  -------------------------------------------------------
  trinity-c236/10658 is trying to acquire lock:
   (&amp;of-&gt;mutex#2){+.+.+.}, at: [&lt;fs/kernfs/file.c:487&gt;] kernfs_fop_mmap+0x54/0x120

  but task is already holding lock:
   (&amp;mm-&gt;mmap_sem){++++++}, at: [&lt;mm/util.c:397&gt;] vm_mmap_pgoff+0x6e/0xe0

  which lock already depends on the new lock.

  the existing dependency chain (in reverse order) is:

 -&gt; #1 (&amp;mm-&gt;mmap_sem){++++++}:
	 [&lt;kernel/locking/lockdep.c:1945 kernel/locking/lockdep.c:2131&gt;] validate_chain+0x6c5/0x7b0
	 [&lt;kernel/locking/lockdep.c:3182&gt;] __lock_acquire+0x4cd/0x5a0
	 [&lt;arch/x86/include/asm/current.h:14 kernel/locking/lockdep.c:3602&gt;] lock_acquire+0x182/0x1d0
	 [&lt;mm/memory.c:4188&gt;] might_fault+0x7e/0xb0
	 [&lt;arch/x86/include/asm/uaccess.h:713 fs/kernfs/file.c:291&gt;] kernfs_fop_write+0xd8/0x190
	 [&lt;fs/read_write.c:473&gt;] vfs_write+0xe3/0x1d0
	 [&lt;fs/read_write.c:523 fs/read_write.c:515&gt;] SyS_write+0x5d/0xa0
	 [&lt;arch/x86/kernel/entry_64.S:749&gt;] tracesys+0xdd/0xe2

 -&gt; #0 (&amp;of-&gt;mutex#2){+.+.+.}:
	 [&lt;kernel/locking/lockdep.c:1840&gt;] check_prev_add+0x13f/0x560
	 [&lt;kernel/locking/lockdep.c:1945 kernel/locking/lockdep.c:2131&gt;] validate_chain+0x6c5/0x7b0
	 [&lt;kernel/locking/lockdep.c:3182&gt;] __lock_acquire+0x4cd/0x5a0
	 [&lt;arch/x86/include/asm/current.h:14 kernel/locking/lockdep.c:3602&gt;] lock_acquire+0x182/0x1d0
	 [&lt;kernel/locking/mutex.c:470 kernel/locking/mutex.c:571&gt;] mutex_lock_nested+0x6a/0x510
	 [&lt;fs/kernfs/file.c:487&gt;] kernfs_fop_mmap+0x54/0x120
	 [&lt;mm/mmap.c:1573&gt;] mmap_region+0x310/0x5c0
	 [&lt;mm/mmap.c:1365&gt;] do_mmap_pgoff+0x385/0x430
	 [&lt;mm/util.c:399&gt;] vm_mmap_pgoff+0x8f/0xe0
	 [&lt;mm/mmap.c:1416 mm/mmap.c:1374&gt;] SyS_mmap_pgoff+0x1b0/0x210
	 [&lt;arch/x86/kernel/sys_x86_64.c:72&gt;] SyS_mmap+0x1d/0x20
	 [&lt;arch/x86/kernel/entry_64.S:749&gt;] tracesys+0xdd/0xe2

  other info that might help us debug this:

   Possible unsafe locking scenario:

	 CPU0                    CPU1
	 ----                    ----
    lock(&amp;mm-&gt;mmap_sem);
				 lock(&amp;of-&gt;mutex#2);
				 lock(&amp;mm-&gt;mmap_sem);
    lock(&amp;of-&gt;mutex#2);

   *** DEADLOCK ***

  1 lock held by trinity-c236/10658:
   #0:  (&amp;mm-&gt;mmap_sem){++++++}, at: [&lt;mm/util.c:397&gt;] vm_mmap_pgoff+0x6e/0xe0

  stack backtrace:
  CPU: 2 PID: 10658 Comm: trinity-c236 Tainted: G        W 3.14.0-rc4-next-20140228-sasha-00011-g4077c67-dirty #26
   0000000000000000 ffff88011911fa48 ffffffff8438e945 0000000000000000
   0000000000000000 ffff88011911fa98 ffffffff811a0109 ffff88011911fab8
   ffff88011911fab8 ffff88011911fa98 ffff880119128cc0 ffff880119128cf8
  Call Trace:
   [&lt;lib/dump_stack.c:52&gt;] dump_stack+0x52/0x7f
   [&lt;kernel/locking/lockdep.c:1213&gt;] print_circular_bug+0x129/0x160
   [&lt;kernel/locking/lockdep.c:1840&gt;] check_prev_add+0x13f/0x560
   [&lt;include/linux/spinlock.h:343 mm/slub.c:1933&gt;] ? deactivate_slab+0x511/0x550
   [&lt;kernel/locking/lockdep.c:1945 kernel/locking/lockdep.c:2131&gt;] validate_chain+0x6c5/0x7b0
   [&lt;kernel/locking/lockdep.c:3182&gt;] __lock_acquire+0x4cd/0x5a0
   [&lt;mm/mmap.c:1552&gt;] ? mmap_region+0x24a/0x5c0
   [&lt;arch/x86/include/asm/current.h:14 kernel/locking/lockdep.c:3602&gt;] lock_acquire+0x182/0x1d0
   [&lt;fs/kernfs/file.c:487&gt;] ? kernfs_fop_mmap+0x54/0x120
   [&lt;kernel/locking/mutex.c:470 kernel/locking/mutex.c:571&gt;] mutex_lock_nested+0x6a/0x510
   [&lt;fs/kernfs/file.c:487&gt;] ? kernfs_fop_mmap+0x54/0x120
   [&lt;kernel/sched/core.c:2477&gt;] ? get_parent_ip+0x11/0x50
   [&lt;fs/kernfs/file.c:487&gt;] ? kernfs_fop_mmap+0x54/0x120
   [&lt;fs/kernfs/file.c:487&gt;] kernfs_fop_mmap+0x54/0x120
   [&lt;mm/mmap.c:1573&gt;] mmap_region+0x310/0x5c0
   [&lt;mm/mmap.c:1365&gt;] do_mmap_pgoff+0x385/0x430
   [&lt;mm/util.c:397&gt;] ? vm_mmap_pgoff+0x6e/0xe0
   [&lt;mm/util.c:399&gt;] vm_mmap_pgoff+0x8f/0xe0
   [&lt;kernel/rcu/update.c:97&gt;] ? __rcu_read_unlock+0x44/0xb0
   [&lt;fs/file.c:641&gt;] ? dup_fd+0x3c0/0x3c0
   [&lt;mm/mmap.c:1416 mm/mmap.c:1374&gt;] SyS_mmap_pgoff+0x1b0/0x210
   [&lt;arch/x86/kernel/sys_x86_64.c:72&gt;] SyS_mmap+0x1d/0x20
   [&lt;arch/x86/kernel/entry_64.S:749&gt;] tracesys+0xdd/0xe2

Fix it by caching atomic_write_len in kernfs_open_file during open so
that it can be determined without accessing kernfs_ops in
kernfs_fop_write().  This restores the structure of kernfs_fop_write()
before 4d3773c4bb41 with updated @len determination logic.

Signed-off-by: Tejun Heo &lt;tj@kernel.org&gt;
Reported-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
References: http://lkml.kernel.org/g/53113485.2090407@oracle.com
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>Merge 3.14-rc5 into driver-core-next</title>
<updated>2014-03-03T04:09:08Z</updated>
<author>
<name>Greg Kroah-Hartman</name>
<email>gregkh@linuxfoundation.org</email>
</author>
<published>2014-03-03T04:09:08Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=13df7977431e3b906a23bb75f29e0f40a8d73f87'/>
<id>urn:sha1:13df7977431e3b906a23bb75f29e0f40a8d73f87</id>
<content type='text'>
We want the fixes in here.
</content>
</entry>
</feed>
