lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20080528154525.GA32634@atrey.karlin.mff.cuni.cz>
Date:	Wed, 28 May 2008 17:45:25 +0200
From:	Jan Kara <jack@...e.cz>
To:	Artem Bityutskiy <Artem.Bityutskiy@...ia.com>
Cc:	Christoph Hellwig <hch@...radead.org>,
	Hunter Adrian <ext-Adrian.Hunter@...ia.com>,
	David Woodhouse <dwmw2@...radead.org>,
	Linux Kernel Mailing List <linux-kernel@...r.kernel.org>
Subject: Re: UBIFS seekdir()/telldir() issue

  Hi,

> The problem
> ~~~~~~~~~~~
> 
> telldir() returns an opaque 32-bit value which should be enough
> to seek to the position later and continue readdir()-ing.
> 
> UBIFS stores direntries in a B-tree with 64-bit keys like:
> | Parent Ino (32-bit) | key type (3 bits) | name hash (29 bits) |
> 
> The name hash may have collisions. Obviously, this does not
> quite fit to the telldir()/seekdir() model.
> 
> Note, this is very similar to reiserfs and reiser4 approach.
> 
> Current UBIFS implementation
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 
> At the moment UBIFS stores the hash value in file->f_pos, so
> telldir() basically returns direntry name hash values. And this
> does not quite work in case of hash collisions - seekdir() may
> not always seek correctly, which is rare though.
  Yes, this is a classical problem of seekdir implementations :).

> However, consecutive readdir() calls work fine because we store
> full name in file->private_data which helps to deal with
> collisions.
> 
> Naturally, readdir() returns direntries in hash order.
> 
> It seems there are not much applications which depend on telldir()
> and seekdir(), so this does not look too bad, at least in embedded
> world. But this means NFS will not really work because it needs
> "absolute" seekdir() implementation.
> 
> Possible approach
> ~~~~~~~~~~~~~~~~~
> 
> Short investigation showed that other file-systems have separate
> trees which are needed just for the sake of seekdir(). Well, it is
> sad that FSes have to do this just because of not very good
> interface, but such is live.
> 
> In UBIFS we are very reluctant to maintain any additional on-flash
> tree which would emulate traditional Unix "directory is an array
> of direntries" view. It is just too much overhead for embedded
> systems. And it would add more complexity to an already complex
> file-system.
> 
> Instead, we would like to do the following.
> 
> 1. Assign a 32-bit unique id for each direntry. Each directory
> inode has its own space of the ids.
> 2. readdir() stores the id of the next direntry to return in
> file->f_pos, which means telldir() will return the unique ids,
> not hashes as it is currently done.
> 3. However, readdir() still walks direntries in hash, and
> it stores the key and full name of the next entry in
> file->private_data. This makes consecutive readdir() calls
> work correctly and efficiently.
> 4. When seeking, UBIFS havs to scan the main B-tree and
> look up direntry with the required ID. This is not efficient.
> 
> This approach gives full seekdir() support, except of one case
> described below.
> 
> Problems with this approach would be:
> 1. Slow seeks. But we think that actually rare applications do
> seekdir(), at least in embedded world. Comments?
> 
> 2. If the direntry we are trying to seek to was _deleted_, we'll be
> unable to gracefully start from the closest next one. This is simply
> because readdir() returns entries in hash order, not in id order.
> The best UBIFS would be able to do in this case is to seek to the
> beginning of the directory.
> 
> IOW, sequence like this would be problematic:
> 
> dir = opendir();
> pos = telldir(dir);
> dent = readdri(dir);
> unlink(dent->d_name);
> closedir(dir);
> dir = opendir();
> seekdir(pos); // Here we do not know where to seek
> 
> But we think this is also quite rare use-case and it should not
> hurt to seek to the beginning in these cases. Comments?
  The sequence you write above is actually incorrect I think. Noone
guarantees that the cookie returned by telldir() is valid after
closedir(). What is a bigger (and quite common) problem is, if somebody
uses readdir/telldir/seekdir while someone else creates/deletes files in
the directory. The standard implies in this case that subsequent
readdir should return all the files which were not touched (or all files
after position set by seekdir if used...).


									Honza
-- 
Jan Kara <jack@...e.cz>
SuSE CR Labs
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ