Merge branch 'for-linus' of 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: [PATCH] get stack footprint of pathname resolution back to relative sanity [PATCH] double iput() on failure exit in hugetlb [PATCH] double dput() on failure exit in tiny-shmem [PATCH] fix up new filp allocators [PATCH] check for null vfsmount in dentry_open() [PATCH] reiserfs: eliminate private use of struct file in xattr [PATCH] sanitize hppfs hppfs pass vfsmount to dentry_open() [PATCH] restore export of do_kern_mount()
This commit is contained in:
63
fs/namei.c
63
fs/namei.c
@@ -106,7 +106,7 @@
|
||||
* any extra contention...
|
||||
*/
|
||||
|
||||
static int link_path_walk(const char *name, struct nameidata *nd);
|
||||
static int __link_path_walk(const char *name, struct nameidata *nd);
|
||||
|
||||
/* In order to reduce some races, while at the same time doing additional
|
||||
* checking and hopefully speeding things up, we copy filenames to the
|
||||
@@ -563,6 +563,37 @@ walk_init_root(const char *name, struct nameidata *nd)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wrapper to retry pathname resolution whenever the underlying
|
||||
* file system returns an ESTALE.
|
||||
*
|
||||
* Retry the whole path once, forcing real lookup requests
|
||||
* instead of relying on the dcache.
|
||||
*/
|
||||
static __always_inline int link_path_walk(const char *name, struct nameidata *nd)
|
||||
{
|
||||
struct path save = nd->path;
|
||||
int result;
|
||||
|
||||
/* make sure the stuff we saved doesn't go away */
|
||||
dget(save.dentry);
|
||||
mntget(save.mnt);
|
||||
|
||||
result = __link_path_walk(name, nd);
|
||||
if (result == -ESTALE) {
|
||||
/* nd->path had been dropped */
|
||||
nd->path = save;
|
||||
dget(nd->path.dentry);
|
||||
mntget(nd->path.mnt);
|
||||
nd->flags |= LOOKUP_REVAL;
|
||||
result = __link_path_walk(name, nd);
|
||||
}
|
||||
|
||||
path_put(&save);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *link)
|
||||
{
|
||||
int res = 0;
|
||||
@@ -1020,36 +1051,6 @@ return_err:
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wrapper to retry pathname resolution whenever the underlying
|
||||
* file system returns an ESTALE.
|
||||
*
|
||||
* Retry the whole path once, forcing real lookup requests
|
||||
* instead of relying on the dcache.
|
||||
*/
|
||||
static int link_path_walk(const char *name, struct nameidata *nd)
|
||||
{
|
||||
struct nameidata save = *nd;
|
||||
int result;
|
||||
|
||||
/* make sure the stuff we saved doesn't go away */
|
||||
dget(save.path.dentry);
|
||||
mntget(save.path.mnt);
|
||||
|
||||
result = __link_path_walk(name, nd);
|
||||
if (result == -ESTALE) {
|
||||
*nd = save;
|
||||
dget(nd->path.dentry);
|
||||
mntget(nd->path.mnt);
|
||||
nd->flags |= LOOKUP_REVAL;
|
||||
result = __link_path_walk(name, nd);
|
||||
}
|
||||
|
||||
path_put(&save.path);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int path_walk(const char *name, struct nameidata *nd)
|
||||
{
|
||||
current->total_link_count = 0;
|
||||
|
Reference in New Issue
Block a user