From: Al Viro <viro@ZenIV.linux.org.uk>
To: Bob Copeland <me@bobcopeland.com>
Cc: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>,
linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org,
Linus Torvalds <torvalds@linux-foundation.org>
Subject: omfs fixes
Date: Fri, 4 Mar 2011 06:55:42 +0000 [thread overview]
Message-ID: <20110304065542.GT22723@ZenIV.linux.org.uk> (raw)
In-Reply-To: <20110303225702.GQ22723@ZenIV.linux.org.uk>
On Thu, Mar 03, 2011 at 10:57:02PM +0000, Al Viro wrote:
> BTW, I suspect that another exception among the local filesystems (affs)
> is actually leaking blocks on rmdir. Need to experiment to verify that,
> but it smells like another genuine bug.
affs turned out to be OK; it uses rather convoluted scheme for link counter
(and uses i_nlink == 0 as trigger for freeing inode), and it actually
works fine. Directories: 1 as long as they are alive, 0 once they are
doomed. Everything else: 1 if there's exactly one link, 0 once it's doomed,
2 when there's more than 1 link. It works.
omfs, however, is _not_ OK in several respects. There's no i_nlink races,
since everything has one parent and rename() gets away with its playing with
link count of old_inode (and it's more complicated than in case of ext*,
BTW). However,
a) it gives all live directories i_nlink == 2. Should be 1, since it's
really "can't tell how many".
b) it uses i_nlink == 0 as indication of doomed inode. And on
rmdir() it drives i_nlink to 0, so that works. On overwriting directory
rename(), OTOH, it leaves i_nlink at 1 and leaks the sucker. Blocks
are not freed.
c) readdir() is really not well. Directories on omfs are hash
tables - array of pointers to chains, indexed by hash function of name.
If we run into an entry that is too long for what remains in the buffer,
we keep scanning the chain. And if something past it will turn out to
be short enough, we'll advance file->f_pos and keep going. Moreover,
if the _last_ one in chain happens to be short enough, we'll spill over
to the next chain, completely forgetting what had been missed in the
previous one.
d) rename playing odd games with link count of old inode is not
a bug; it's too convoluted for no good reason, but at least it's correct.
Failing to mark old_inode dirty after updating ->i_ctime in there, OTOH,
is racy.
I've pushed fixes for (b), (c) and (d) into #i_nlink and I think that (a)
needs to be dealt with as well, but that one is less nasty. Bob, do you
prefer that to go through your tree or should it go straight to Linus?
It's in git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6.git/ i_nlink,
Al Viro (4):
omfs: rename() needs to mark old_inode dirty after ctime update
omfs: stop playing silly buggers with omfs_unlink() in ->rename()
omfs: merge unlink() and rmdir(), close leak in rename()
omfs: make readdir stop when filldir says so
fs/omfs/dir.c | 66 +++++++++++++++++---------------------------------------
1 files changed, 20 insertions(+), 46 deletions(-)
next prev parent reply other threads:[~2011-03-04 6:55 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-03-03 3:24 [RFC] st_nlink after rmdir() and rename() Al Viro
2011-03-03 4:42 ` Al Viro
2011-03-03 5:17 ` Linus Torvalds
2011-03-03 6:03 ` Al Viro
2011-03-03 20:05 ` Linus Torvalds
2011-03-03 20:46 ` OGAWA Hirofumi
2011-03-03 20:50 ` OGAWA Hirofumi
2011-03-03 21:02 ` Linus Torvalds
2011-03-03 21:30 ` Al Viro
2011-03-03 21:37 ` OGAWA Hirofumi
2011-03-03 21:52 ` Linus Torvalds
2011-03-03 22:26 ` OGAWA Hirofumi
2011-03-03 22:37 ` Linus Torvalds
2011-03-03 23:14 ` OGAWA Hirofumi
2011-03-03 23:12 ` Al Viro
2011-03-03 22:57 ` Al Viro
2011-03-03 23:07 ` Al Viro
2011-03-04 6:55 ` Al Viro [this message]
2011-03-04 15:24 ` omfs fixes Bob Copeland
2011-03-03 21:23 ` [RFC] st_nlink after rmdir() and rename() Al Viro
2011-03-03 14:34 ` Theodore Tso
2011-03-03 16:17 ` Andreas Schwab
2011-03-03 19:16 ` Al Viro
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=20110304065542.GT22723@ZenIV.linux.org.uk \
--to=viro@zeniv.linux.org.uk \
--cc=hirofumi@mail.parknet.co.jp \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=me@bobcopeland.com \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).