09 Nov, 2013
40 commits
-
Suppose we're given the filehandle for a directory whose closest
ancestor in the dcache is its Nth ancestor.The main loop in reconnect_path searches for an IS_ROOT ancestor of
target_dir, reconnects that ancestor to its parent, then recommences the
search for an IS_ROOT ancestor from target_dir.This behavior is quadratic in N. And there's really no need to restart
the search from target_dir each time: once a directory has been looked
up, it won't become IS_ROOT again. So instead of starting from
target_dir each time, we can continue where we left off.This simplifies the code and improves performance on very deep directory
heirachies. (I can't think of any reason anyone should need heirarchies
a hundred or more deep, but the performance improvement may be valuable
if only to limit damage in case of abuse.)Reviewed-by: Christoph Hellwig
Signed-off-by: J. Bruce Fields
Signed-off-by: Al Viro -
Replace another unhelpful acronym.
Reviewed-by: Christoph Hellwig
Signed-off-by: J. Bruce Fields
Signed-off-by: Al Viro -
Also replace 3 easily-confused three-letter acronyms by more helpful
variable names.Just cleanup, no change in functionality, with one exception: the
dentry_connected() check in the "out_reconnected" case will now only
check the ancestors of the current dentry instead of checking all the
way from target_dir. Since we've already verified connectivity up to
this dentry, that should be sufficient.Reviewed-by: Christoph Hellwig
Signed-off-by: J. Bruce Fields
Signed-off-by: Al Viro -
Note this counter is now being set to 0 on every pass through the loop,
so it no longer serves any useful purpose.Reviewed-by: Christoph Hellwig
Signed-off-by: J. Bruce Fields
Signed-off-by: Al Viro -
There are two places here where we could race with a rename or remove:
- We could find the parent, but then be removed or renamed away
from that parent directory before finding our name in that
directory.
- We could find the parent, and find our name in that parent,
but then be renamed or removed before we look ourselves up by
that name in that parent.In both cases the concurrent rename or remove will take care of
reconnecting the directory that we're currently examining. Our target
directory should then also be connected. Check this and clear
DISCONNECTED in these cases instead of looping around again.Note: we *do* need to check that this actually happened if we want to be
robust in the face of corrupted filesystems: a corrupted filesystem
could just return a completely wrong parent, and we want to fail with an
error in that case before starting to clear DISCONNECTED on
non-DISCONNECTED filesystems.Reviewed-by: Christoph Hellwig
Signed-off-by: J. Bruce Fields
Signed-off-by: Al Viro -
Once we've found any connected parent, we know all our parents are
connected--that's true even if there's a concurrent rename. May as well
clear them all at once and be done with it.Reviewed-by: Cristoph Hellwig
Signed-off-by: J. Bruce Fields
Signed-off-by: Al Viro -
Reviewed-by: Christoph Hellwig
Signed-off-by: J. Bruce Fields
Signed-off-by: Al Viro -
This would indicate a nasty bug in the dcache and has never triggered in
the past 10 years as far as I know.Reviewed-by: Christoph Hellwig
Signed-off-by: J. Bruce Fields
Signed-off-by: Al Viro -
The DCACHE_NEED_LOOKUP case referred to here was removed with
39e3c9553f34381a1b664c27b0c696a266a5735e "vfs: remove
DCACHE_NEED_LOOKUP".There are only four real_lookup() callers and all of them pass in an
unhashed dentry just returned from d_alloc.Signed-off-by: J. Bruce Fields
Signed-off-by: Al Viro -
DCACHE_DISCONNECTED should not be cleared until we're sure the dentry is
connected all the way up to the root of the filesystem. It *shouldn't*
be cleared as soon as the dentry is connected to a parent. That will
cause bugs at least on exportable filesystems.Acked-by: Christoph Hellwig
Signed-off-by: J. Bruce Fields
Signed-off-by: Al Viro -
I can't for the life of me see any reason why anyone should care whether
a dentry that is never hooked into the dentry cache would need
DCACHE_DISCONNECTED set.This originates from 4b936885ab04dc6e0bb0ef35e0e23c1a7364d9e5 "fs:
improve scalability of pseudo filesystems", which probably just made the
false assumption the DCACHE_DISCONNECTED was meant to be set on anything
not connected to a parent somehow.So this is just confusing. Ideally the only uses of DCACHE_DISCONNECTED
would be in the filehandle-lookup code, which needs it to ensure
dentries are connected into the dentry tree before use.I left d_alloc_pseudo there even though it's now equivalent to
__d_alloc(), just on the theory the name is better documentation of its
intended use outside dcache.c.Cc: Nick Piggin
Acked-by: Christoph Hellwig
Signed-off-by: J. Bruce Fields
Signed-off-by: Al Viro -
Every hashed dentry is either hashed in the dentry_hashtable, or a
superblock's s_anon list.__d_drop() assumes it can determine which is the case by checking
DCACHE_DISCONNECTED; this is not true.It is true that when DCACHE_DISCONNECTED is cleared, the dentry is not
only hashed on dentry_hashtable, but is fully connected to its parents
back to the root.But the converse is *not* true: fs/exportfs/expfs.c:reconnect_path()
attempts to connect a directory (found by filehandle lookup) back to
root by ascending to parents and performing lookups one at a time. It
does not clear DCACHE_DISCONNECTED until it's done, and that is not at
all an atomic process.In particular, it is possible for DCACHE_DISCONNECTED to be set on a
dentry which is hashed on the dentry_hashtable.Instead, use IS_ROOT() to check which hash chain a dentry is on. This
*does* work:Dentries are hashed only by:
- d_obtain_alias, which adds an IS_ROOT() dentry to sb_anon.
- __d_rehash, called by _d_rehash: hashes to the dentry's
parent, and all callers of _d_rehash appear to have d_parent
set to a "real" parent.
- __d_rehash, called by __d_move: rehashes the moved dentry to
hash chain determined by target, and assigns target's d_parent
to its d_parent, before dropping the dentry's d_lock.Therefore I believe it's safe for a holder of a dentry's d_lock to
assume that it is hashed on sb_anon if and only if IS_ROOT(dentry) is
true.I believe the incorrect assumption about DCACHE_DISCONNECTED was
originally introduced by ceb5bdc2d246 "fs: dcache per-bucket dcache hash
locking".Also add a comment while we're here.
Cc: Nick Piggin
Acked-by: Christoph Hellwig
Reviewed-by: NeilBrown
Signed-off-by: J. Bruce Fields
Signed-off-by: Al Viro -
Signed-off-by: Al Viro
-
Signed-off-by: Al Viro
-
Symptoms were spurious -ENOENTs on stat of an NFS filesystem from a
32-bit NFS server exporting a very large XFS filesystem, when the
server's cache is cold (so the inodes in question are not in cache).Reviewed-by: Christoph Hellwig
Reported-by: Trevor Cordes
Signed-off-by: J. Bruce Fields
Signed-off-by: Al Viro -
The filehandle lookup code wants this version of getattr.
Reviewed-by: Christoph Hellwig
Signed-off-by: J. Bruce Fields
Signed-off-by: Al Viro -
Signed-off-by: Al Viro
-
Put a type field into struct dentry::d_flags to indicate if the dentry is one
of the following types that relate particularly to pathwalk:Miss (negative dentry)
Directory
"Automount" directory (defective - no i_op->lookup())
Symlink
Other (regular, socket, fifo, device)The type field is set to one of the first five types on a dentry by calls to
__d_instantiate() and d_obtain_alias() from information in the inode (if one is
given).The type is cleared by dentry_unlink_inode() when it reconstitutes an existing
dentry as a negative dentry.Accessors provided are:
d_set_type(dentry, type)
d_is_directory(dentry)
d_is_autodir(dentry)
d_is_symlink(dentry)
d_is_file(dentry)
d_is_negative(dentry)
d_is_positive(dentry)A bunch of checks in pathname resolution switched to those.
Signed-off-by: David Howells
Signed-off-by: Al Viro -
we can't get to do_coredump() if that condition isn't satisfied...
Signed-off-by: Al Viro
-
Signed-off-by: Al Viro
-
Signed-off-by: Al Viro
-
it's a seriously misguided API, now fortunately without users.
Signed-off-by: Al Viro
-
Don't abuse anon_inodes.c to host private files needed by aio;
we can bloody well declare a mini-fs of our own instead of
patching up what anon_inodes can create for us.Tested-by: Benjamin LaHaise
Acked-by: Benjamin LaHaise
Signed-off-by: Al Viro -
Signed-off-by: Al Viro
-
dump_skip to given alignment...
Signed-off-by: Al Viro
-
Signed-off-by: Al Viro
-
Signed-off-by: Al Viro
-
... and deal with short writes properly - the output might be to pipe, after
all; as it is, e.g. no-MMU case of elf_fdpic coredump can write a whole lot
more than a page worth of data at one call.Signed-off-by: Al Viro
-
Signed-off-by: Al Viro
-
Signed-off-by: Al Viro
-
Signed-off-by: Al Viro
-
Signed-off-by: Al Viro
-
Signed-off-by: Al Viro
-
Signed-off-by: Al Viro
-
Signed-off-by: Al Viro
-
dump_write() analog, takes core_dump_params instead of file,
keeps track of the amount written in cprm->written and checks for
cprm->limit. Start using it in binfmt_elf.c...Signed-off-by: Al Viro
-
just getting rid of bitrot
Signed-off-by: Al Viro
-
Signed-off-by: Al Viro
-
Signed-off-by: Al Viro
-
Signed-off-by: Al Viro