summaryrefslogtreecommitdiffstats
path: root/fs
Commit message (Collapse)AuthorAgeFilesLines
* clean statfs-like syscalls upAl Viro2011-03-142-133/+91
| | | | | | | | | | New helpers: user_statfs() and fd_statfs(), taking userland pathname and descriptor resp. and filling struct kstatfs. Syscalls of statfs family (native, compat and foreign - osf and hpux on alpha and parisc resp.) switched to those. Removes some boilerplate code, simplifies cleanup on errors... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* open-style analog of vfs_path_lookup()Al Viro2011-03-144-45/+72
| | | | | | | | | | | | | new function: file_open_root(dentry, mnt, name, flags) opens the file vfs_path_lookup would arrive to. Note that name can be empty; in that case the usual requirement that dentry should be a directory is lifted. open-coded equivalents switched to it, may_open() got down exactly one caller and became static. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* reduce vfs_path_lookup() to do_path_lookup()Al Viro2011-03-141-52/+43
| | | | | | | | | | | | | | | New lookup flag: LOOKUP_ROOT. nd->root is set (and held) by caller, path_init() starts walking from that place and all pathname resolution machinery never drops nd->root if that flag is set. That turns vfs_path_lookup() into a special case of do_path_lookup() *and* gets us down to 3 callers of link_path_walk(), making it finally feasible to rip the handling of trailing symlink out of link_path_walk(). That will not only simply the living hell out of it, but make life much simpler for unionfs merge. Trailing symlink handling will become iterative, which is a good thing for stack footprint in a lot of situations as well. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* untangle do_lookup()Al Viro2011-03-141-85/+56
| | | | | | | | | | | | | | | | | | | | | | That thing has devolved into rats nest of gotos; sane use of unlikely() gets rid of that horror and gives much more readable structure: * make a fast attempt to find a dentry; false negatives are OK. In RCU mode if everything went fine, we are done, otherwise just drop out of RCU. If we'd done (RCU) ->d_revalidate() and it had not refused outright (i.e. didn't give us -ECHILD), remember its result. * now we are not in RCU mode and hopefully have a dentry. If we do not, lock parent, do full d_lookup() and if that has not found anything, allocate and call ->lookup(). If we'd done that ->lookup(), remember that dentry is good and we don't need to revalidate it. * now we have a dentry. If it has ->d_revalidate() and we can't skip it, call it. * hopefully dentry is good; if not, either fail (in case of error) or try to invalidate it. If d_invalidate() has succeeded, drop it and retry everything as if original attempt had not found a dentry. * now we can finish it up - deal with mountpoint crossing and automount. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* path_openat: clean ELOOP handling a bitAl Viro2011-03-141-8/+6
| | | | Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* do_last: kill a rudiment of old ->d_revalidate() workaroundAl Viro2011-03-141-5/+0
| | | | | | | | | | | | There used to be time when ->d_revalidate() couldn't return an error. So intents code had lookup_instantiate_filp() stash ERR_PTR(error) in nd->intent.open.filp and had it checked after lookup_hash(), to catch the otherwise silent failures. That had been introduced by commit 4af4c52f34606bdaab6930a845550c6fb02078a4. These days ->d_revalidate() can and does propagate errors back to callers explicitly, so this check isn't needed anymore. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* fold __open_namei_create() and open_will_truncate() into do_last()Al Viro2011-03-141-48/+26
| | | | | | ... and clean up a bit more Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* do_last: unify may_open() call and everyting after itAl Viro2011-03-141-37/+22
| | | | | | | | | We have a bunch of diverging codepaths in do_last(); some of them converge, but the case of having to create a new file duplicates large part of common tail of the rest and exits separately. Massage them so that they could be merged. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* move may_open() from __open_name_create() to do_last()Al Viro2011-03-141-5/+7
| | | | Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* expand finish_open() in its only callerAl Viro2011-03-141-52/+38
| | | | Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* sanitize pathname component hash calculationAl Viro2011-03-141-23/+19
| | | | | | | | Lift it to lookup_one_len() and link_path_walk() resp. into the same place where we calculated default hash function of the same name. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* kill __lookup_one_len()Al Viro2011-03-141-26/+15
| | | | | | only one caller left Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* switch non-create side of open() to use of do_last()Al Viro2011-03-141-33/+67
| | | | | | | | | | | | | | | | | | | | Instead of path_lookupat() doing trailing symlink resolution, use the same scheme as on the O_CREAT side. Walk with LOOKUP_PARENT, then (in do_last()) look the final component up, then either open it or return error or, if it's a symlink, give the symlink back to path_openat() to be resolved there. The really messy complication here is RCU. We don't want to drop out of RCU mode before the final lookup, since we don't want to bounce parent directory ->d_count without a good reason. Result is _not_ pretty; later in the series we'll clean it up. For now we are roughly back where we'd been before the revert done by Nick's series - top-level logics of path_openat() is cleaned up, do_last() does actual opening, symlink resolution is done uniformly. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* get rid of nd->fileAl Viro2011-03-141-8/+7
| | | | | | | Don't stash the struct file * used as starting point of walk in nameidata; pass file ** to path_init() instead. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* get rid of the last LOOKUP_RCU dependencies in link_path_walk()Al Viro2011-03-141-8/+13
| | | | | | | | | | | | New helper: terminate_walk(). An error has happened during pathname resolution and we either drop nd->path or terminate RCU, depending the mode we had been in. After that, nd is essentially empty. Switch link_path_walk() to using that for cleanup. Now the top-level logics in link_path_walk() is back to sanity. RCU dependencies are in the lower-level functions. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* make nameidata_dentry_drop_rcu_maybe() always leave RCU modeAl Viro2011-03-141-5/+11
| | | | | | | | Now we have do_follow_link() guaranteed to leave without dangling RCU and the next step will get LOOKUP_RCU logics completely out of link_path_walk(). Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* make handle_dots() leave RCU mode on errorAl Viro2011-03-141-11/+12
| | | | Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* clear RCU on all failure exits from link_path_walk()Al Viro2011-03-141-14/+16
| | | | Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* pull handling of . and .. into inlined helperAl Viro2011-03-141-14/+16
| | | | | | getting LOOKUP_RCU checks out of link_path_walk()... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* kill out_dput: in link_path_walk()Al Viro2011-03-141-11/+4
| | | | Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* separate -ESTALE/-ECHILD retries in do_filp_open() from real workAl Viro2011-03-141-29/+20
| | | | | | | | | | | new helper: path_openat(). Does what do_filp_open() does, except that it tries only the walk mode (RCU/normal/force revalidation) it had been told to. Both create and non-create branches are using path_lookupat() now. Fixed the double audit_inode() in non-create branch. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* switch do_filp_open() to struct open_flagsAl Viro2011-03-144-86/+101
| | | | | | | | | take calculation of open_flags by open(2) arguments into new helper in fs/open.c, move filp_open() over there, have it and do_sys_open() use that helper, switch exec.c callers of do_filp_open() to explicit (and constant) struct open_flags. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* Collect "operation mode" arguments of do_last() into a structureAl Viro2011-03-141-22/+35
| | | | | | | | | | | | No point messing with passing shitloads of "operation mode" arguments to do_open() one by one, especially since they are not going to change during do_filp_open(). Collect them into a struct, fill it and pass to do_last() by reference. Make sure that lookup intent flags are correctly set and removed - we want them for do_last(), but they make no sense for __do_follow_link(). Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* clean up the failure exits after __do_follow_link() in do_filp_open()Al Viro2011-03-141-8/+5
| | | | Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* pull security_inode_follow_link() into __do_follow_link()Al Viro2011-03-141-6/+7
| | | | Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* pull dropping RCU on success of link_path_walk() into path_lookupat()Al Viro2011-03-141-18/+12
| | | | Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* untangle the "need_reval_dot" messAl Viro2011-03-141-63/+44
| | | | | | | | | | | | | instead of ad-hackery around need_reval_dot(), do the following: set a flag (LOOKUP_JUMPED) in the beginning of path, on absolute symlink traversal, on ".." and on procfs-style symlinks. Clear on normal components, leave unchanged on ".". Non-nested callers of link_path_walk() call handle_reval_path(), which checks that flag is set and that fs does want the final revalidate thing, then does ->d_revalidate(). In link_path_walk() all the return_reval stuff is gone. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* merge component type recognitionAl Viro2011-03-141-26/+22
| | | | | | no need to do it in three places... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* merge path_init and path_init_rcuAl Viro2011-03-141-83/+35
| | | | | | | | | | Actual dependency on whether we want RCU or not is in 3 small areas (as it ought to be) and everything around those is the same in both versions. Since each function has only one caller and those callers are on two sides of if (flags & LOOKUP_RCU), it's easier and cleaner to merge them and pull the checks inside. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* sanitize path_walk() messAl Viro2011-03-141-92/+56
| | | | | | | | | New helper: path_lookupat(). Basically, what do_path_lookup() boils to modulo -ECHILD/-ESTALE handler. path_walk* family is gone; vfs_path_lookup() is using link_path_walk() directly, do_path_lookup() and do_filp_open() are using path_lookupat(). Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* take RCU-dependent stuff around exec_permission() into a new helperAl Viro2011-03-141-11/+14
| | | | Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* kill path_lookup()Al Viro2011-03-142-5/+4
| | | | | | | all remaining callers pass LOOKUP_PARENT to it, so flags argument can die; renamed to kern_path_parent() Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* compat breakage in preadv() and pwritev()Al Viro2011-03-131-2/+6
| | | | | | | | | | Fix for a dumb preadv()/pwritev() compat bug - unlike the native variants, compat_... ones forget to check FMODE_P{READ,WRITE}, so e.g. on pipe the native preadv() will fail with -ESPIPE and compat one will act as readv() and succeed. Not critical, but it's a clear bug with trivial fix. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* fs/dcache: allow d_obtain_alias() to return unhashed dentriesJ. Bruce Fields2011-03-101-2/+24
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Without this patch, inodes are not promptly freed on last close of an unlinked file by an nfs client: client$ mount -tnfs4 server:/export/ /mnt/ client$ tail -f /mnt/FOO ... server$ df -i /export server$ rm /export/FOO (^C the tail -f) server$ df -i /export server$ echo 2 >/proc/sys/vm/drop_caches server$ df -i /export the df's will show that the inode is not freed on the filesystem until the last step, when it could have been freed after killing the client's tail -f. On-disk data won't be deallocated either, leading to possible spurious ENOSPC. This occurs because when the client does the close, it arrives in a compound with a putfh and a close, processed like: - putfh: look up the filehandle.  The only alias found for the inode will be DCACHE_UNHASHED alias referenced by the filp this, so it creates a new DCACHE_DISCONECTED dentry and returns that instead. - close: closes the existing filp, which is destroyed immediately by dput() since it's DCACHE_UNHASHED. - end of the compound: release the reference to the current filehandle, and dput() the new DCACHE_DISCONECTED dentry, which gets put on the unused list instead of being destroyed immediately. Nick Piggin suggested fixing this by allowing d_obtain_alias to return the unhashed dentry that is referenced by the filp, instead of making it create a new dentry. Leave __d_find_alias() alone to avoid changing behavior of other callers. Also nfsd doesn't need all the checks of __d_find_alias(); any dentry, hashed or unhashed, disconnected or not, should work. Signed-off-by: J. Bruce Fields <bfields@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* Check for immutable/append flag in fallocate pathMarco Stornelli2011-03-101-0/+8
| | | | | | | | | | | | In the fallocate path the kernel doesn't check for the immutable/append flag. It's possible to have a race condition in this scenario: an application open a file in read/write and it does something, meanwhile root set the immutable flag on the file, the application at that point can call fallocate with success. In addition, we don't allow to do any unreserve operation on an append only file but only the reserve one. Signed-off-by: Marco Stornelli <marco.stornelli@gmail.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* fat: fix d_revalidate oopsen on NFS exportsAl Viro2011-03-101-2/+2
| | | | | | can't blindly check nd->flags in ->d_revalidate() Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* jfs: fix d_revalidate oopsen on NFS exportsAl Viro2011-03-101-1/+1
| | | | | | can't blindly check nd->flags in ->d_revalidate() Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* ocfs2: fix d_revalidate oopsen on NFS exportsAl Viro2011-03-101-1/+1
| | | | | | can't blindly check nd->flags in ->d_revalidate() Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* gfs2: fix d_revalidate oopsen on NFS exportsAl Viro2011-03-101-1/+1
| | | | | | can't blindly check nd->flags in ->d_revalidate() Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* fuse: fix d_revalidate oopsen on NFS exportsAl Viro2011-03-101-1/+1
| | | | | | can't blindly check nd->flags in ->d_revalidate() Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* ceph: fix d_revalidate oopsen on NFS exportsAl Viro2011-03-101-1/+1
| | | | | | can't blindly check nd->flags in ->d_revalidate() Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* reiserfs xattr ->d_revalidate() shouldn't care about RCUAl Viro2011-03-101-2/+0
| | | | | | ... it returns an error unconditionally Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* /proc/self is never going to be invalidated...Al Viro2011-03-101-30/+0
| | | | Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* Merge branch 'for-2.6.38' of git://linux-nfs.org/~bfields/linuxLinus Torvalds2011-03-093-9/+10
|\ | | | | | | | | | | | | * 'for-2.6.38' of git://linux-nfs.org/~bfields/linux: nfsd: wrong index used in inner loop nfsd4: fix bad pointer on failure to find delegation NFSD: fix decode_cb_sequence4resok
| * nfsd: wrong index used in inner looproel2011-03-081-2/+2
| | | | | | | | | | | | | | | | Index i was already used in the outer loop Cc: stable@kernel.org Signed-off-by: Roel Kluin <roel.kluin@gmail.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
| * nfsd4: fix bad pointer on failure to find delegationJ. Bruce Fields2011-03-071-6/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In case of a nonempty list, the return on error here is obviously bogus; it ends up being a pointer to the list head instead of to any valid delegation on the list. In particular, if nfsd4_delegreturn() hits this case, and you're quite unlucky, then renew_client may oops, and it may take an embarassingly long time to figure out why. Facepalm. BUG: unable to handle kernel NULL pointer dereference at 0000000000000090 IP: [<ffffffff81292965>] nfsd4_delegreturn+0x125/0x200 ... Cc: stable@kernel.org Signed-off-by: J. Bruce Fields <bfields@redhat.com>
| * NFSD: fix decode_cb_sequence4resokBenny Halevy2011-02-221-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | Fix bug introduced in patch 85a56480 NFSD: Update XDR decoders in NFSv4 callback client Although decode_cb_sequence4resok ignores highest slotid and target highest slotid it must account for their space in their xdr stream when calling xdr_inline_decode Cc: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Benny Halevy <bhalevy@panasas.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
* | Merge branch 'for-linus' of ↵Linus Torvalds2011-03-093-7/+22
|\ \ | | | | | | | | | | | | | | | | | | | | | | | | git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6 * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6: nd->inode is not set on the second attempt in path_walk() unfuck proc_sysctl ->d_compare() minimal fix for do_filp_open() race
| * | nd->inode is not set on the second attempt in path_walk()Al Viro2011-03-081-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | We leave it at whatever it had been pointing to after the first link_path_walk() had failed with -ESTALE. Things do not work well after that... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
| * | unfuck proc_sysctl ->d_compare()Al Viro2011-03-082-4/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | a) struct inode is not going to be freed under ->d_compare(); however, the thing PROC_I(inode)->sysctl points to just might. Fortunately, it's enough to make freeing that sucker delayed, provided that we don't step on its ->unregistering, clear the pointer to it in PROC_I(inode) before dropping the reference and check if it's NULL in ->d_compare(). b) I'm not sure that we *can* walk into NULL inode here (we recheck dentry->seq between verifying that it's still hashed / fetching dentry->d_inode and passing it to ->d_compare() and there's no negative hashed dentries in /proc/sys/*), but if we can walk into that, we really should not have ->d_compare() return 0 on it! Said that, I really suspect that this check can be simply killed. Nick? Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
OpenPOWER on IntegriCloud