projects
/
firefly-linux-kernel-4.4.55.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[firefly-linux-kernel-4.4.55.git]
/
fs
/
namei.c
diff --git
a/fs/namei.c
b/fs/namei.c
index 215e44254c5328c1a992db483da80e27a1dbed6c..43927d14db67c68706ef8dd208c714ec2ec6addb 100644
(file)
--- a/
fs/namei.c
+++ b/
fs/namei.c
@@
-1306,7
+1306,8
@@
static struct dentry *lookup_dcache(struct qstr *name, struct dentry *dir,
if (error < 0) {
dput(dentry);
return ERR_PTR(error);
if (error < 0) {
dput(dentry);
return ERR_PTR(error);
- } else if (!d_invalidate(dentry)) {
+ } else {
+ d_invalidate(dentry);
dput(dentry);
dentry = NULL;
}
dput(dentry);
dentry = NULL;
}
@@
-1435,10
+1436,9
@@
unlazy:
dput(dentry);
return status;
}
dput(dentry);
return status;
}
- if (!d_invalidate(dentry)) {
- dput(dentry);
- goto need_lookup;
- }
+ d_invalidate(dentry);
+ dput(dentry);
+ goto need_lookup;
}
path->mnt = mnt;
}
path->mnt = mnt;
@@
-1674,14
+1674,13
@@
EXPORT_SYMBOL(full_name_hash);
/*
* Calculate the length and hash of the path component, and
/*
* Calculate the length and hash of the path component, and
- *
fill in the qstr. return the "
len" as the result.
+ *
return the "hash_
len" as the result.
*/
*/
-static inline u
nsigned long hash_name(const char *name, struct qstr *res
)
+static inline u
64 hash_name(const char *name
)
{
unsigned long a, b, adata, bdata, mask, hash, len;
const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS;
{
unsigned long a, b, adata, bdata, mask, hash, len;
const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS;
- res->name = name;
hash = a = 0;
len = -sizeof(unsigned long);
do {
hash = a = 0;
len = -sizeof(unsigned long);
do {
@@
-1698,9
+1697,7
@@
static inline unsigned long hash_name(const char *name, struct qstr *res)
hash += a & zero_bytemask(mask);
len += find_zero(mask);
hash += a & zero_bytemask(mask);
len += find_zero(mask);
- res->hash_len = hashlen_create(fold_hash(hash), len);
-
- return len;
+ return hashlen_create(fold_hash(hash), len);
}
#else
}
#else
@@
-1718,20
+1715,18
@@
EXPORT_SYMBOL(full_name_hash);
* We know there's a real path component here of at least
* one character.
*/
* We know there's a real path component here of at least
* one character.
*/
-static inline
long hash_name(const char *name, struct qstr *res
)
+static inline
u64 hash_name(const char *name
)
{
unsigned long hash = init_name_hash();
unsigned long len = 0, c;
{
unsigned long hash = init_name_hash();
unsigned long len = 0, c;
- res->name = name;
c = (unsigned char)*name;
do {
len++;
hash = partial_name_hash(c, hash);
c = (unsigned char)name[len];
} while (c && c != '/');
c = (unsigned char)*name;
do {
len++;
hash = partial_name_hash(c, hash);
c = (unsigned char)name[len];
} while (c && c != '/');
- res->hash_len = hashlen_create(end_name_hash(hash), len);
- return len;
+ return hashlen_create(end_name_hash(hash), len);
}
#endif
}
#endif
@@
-1756,18
+1751,17
@@
static int link_path_walk(const char *name, struct nameidata *nd)
/* At this point we know we have a real path component. */
for(;;) {
/* At this point we know we have a real path component. */
for(;;) {
- struct qstr this;
- long len;
+ u64 hash_len;
int type;
err = may_lookup(nd);
if (err)
break;
int type;
err = may_lookup(nd);
if (err)
break;
-
len = hash_name(name, &this
);
+
hash_len = hash_name(name
);
type = LAST_NORM;
type = LAST_NORM;
- if (name[0] == '.') switch (
len
) {
+ if (name[0] == '.') switch (
hashlen_len(hash_len)
) {
case 2:
if (name[1] == '.') {
type = LAST_DOTDOT;
case 2:
if (name[1] == '.') {
type = LAST_DOTDOT;
@@
-1781,29
+1775,32
@@
static int link_path_walk(const char *name, struct nameidata *nd)
struct dentry *parent = nd->path.dentry;
nd->flags &= ~LOOKUP_JUMPED;
if (unlikely(parent->d_flags & DCACHE_OP_HASH)) {
struct dentry *parent = nd->path.dentry;
nd->flags &= ~LOOKUP_JUMPED;
if (unlikely(parent->d_flags & DCACHE_OP_HASH)) {
+ struct qstr this = { { .hash_len = hash_len }, .name = name };
err = parent->d_op->d_hash(parent, &this);
if (err < 0)
break;
err = parent->d_op->d_hash(parent, &this);
if (err < 0)
break;
+ hash_len = this.hash_len;
+ name = this.name;
}
}
}
}
- nd->last = this;
+ nd->last.hash_len = hash_len;
+ nd->last.name = name;
nd->last_type = type;
nd->last_type = type;
- if (!name[len])
+ name += hashlen_len(hash_len);
+ if (!*name)
return 0;
/*
* If it wasn't NUL, we know it was '/'. Skip that
* slash, and continue until no more slashes.
*/
do {
return 0;
/*
* If it wasn't NUL, we know it was '/'. Skip that
* slash, and continue until no more slashes.
*/
do {
-
len
++;
- } while (unlikely(
name[len]
== '/'));
- if (!
name[len]
)
+
name
++;
+ } while (unlikely(
*name
== '/'));
+ if (!
*name
)
return 0;
return 0;
- name += len;
-
err = walk_component(nd, &next, LOOKUP_FOLLOW);
if (err < 0)
return err;
err = walk_component(nd, &next, LOOKUP_FOLLOW);
if (err < 0)
return err;
@@
-1953,7
+1950,7
@@
static int path_lookupat(int dfd, const char *name,
err = path_init(dfd, name, flags | LOOKUP_PARENT, nd, &base);
if (unlikely(err))
err = path_init(dfd, name, flags | LOOKUP_PARENT, nd, &base);
if (unlikely(err))
-
return err
;
+
goto out
;
current->total_link_count = 0;
err = link_path_walk(name, nd);
current->total_link_count = 0;
err = link_path_walk(name, nd);
@@
-1985,6
+1982,7
@@
static int path_lookupat(int dfd, const char *name,
}
}
}
}
+out:
if (base)
fput(base);
if (base)
fput(base);
@@
-2304,7
+2302,7
@@
path_mountpoint(int dfd, const char *name, struct path *path, unsigned int flags
err = path_init(dfd, name, flags | LOOKUP_PARENT, &nd, &base);
if (unlikely(err))
err = path_init(dfd, name, flags | LOOKUP_PARENT, &nd, &base);
if (unlikely(err))
-
return err
;
+
goto out
;
current->total_link_count = 0;
err = link_path_walk(name, &nd);
current->total_link_count = 0;
err = link_path_walk(name, &nd);
@@
-3077,7
+3075,7
@@
opened:
error = open_check_o_direct(file);
if (error)
goto exit_fput;
error = open_check_o_direct(file);
if (error)
goto exit_fput;
- error = ima_file_check(file, op->acc_mode);
+ error = ima_file_check(file, op->acc_mode
, *opened
);
if (error)
goto exit_fput;
if (error)
goto exit_fput;
@@
-3568,7
+3566,7
@@
int vfs_rmdir(struct inode *dir, struct dentry *dentry)
mutex_lock(&dentry->d_inode->i_mutex);
error = -EBUSY;
mutex_lock(&dentry->d_inode->i_mutex);
error = -EBUSY;
- if (
d
_mountpoint(dentry))
+ if (
is_local
_mountpoint(dentry))
goto out;
error = security_inode_rmdir(dir, dentry);
goto out;
error = security_inode_rmdir(dir, dentry);
@@
-3582,6
+3580,7
@@
int vfs_rmdir(struct inode *dir, struct dentry *dentry)
dentry->d_inode->i_flags |= S_DEAD;
dont_mount(dentry);
dentry->d_inode->i_flags |= S_DEAD;
dont_mount(dentry);
+ detach_mounts(dentry);
out:
mutex_unlock(&dentry->d_inode->i_mutex);
out:
mutex_unlock(&dentry->d_inode->i_mutex);
@@
-3684,7
+3683,7
@@
int vfs_unlink(struct inode *dir, struct dentry *dentry, struct inode **delegate
return -EPERM;
mutex_lock(&target->i_mutex);
return -EPERM;
mutex_lock(&target->i_mutex);
- if (
d
_mountpoint(dentry))
+ if (
is_local
_mountpoint(dentry))
error = -EBUSY;
else {
error = security_inode_unlink(dir, dentry);
error = -EBUSY;
else {
error = security_inode_unlink(dir, dentry);
@@
-3693,8
+3692,10
@@
int vfs_unlink(struct inode *dir, struct dentry *dentry, struct inode **delegate
if (error)
goto out;
error = dir->i_op->unlink(dir, dentry);
if (error)
goto out;
error = dir->i_op->unlink(dir, dentry);
- if (!error)
+ if (!error)
{
dont_mount(dentry);
dont_mount(dentry);
+ detach_mounts(dentry);
+ }
}
}
out:
}
}
out:
@@
-4129,7
+4130,7
@@
int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
mutex_lock(&target->i_mutex);
error = -EBUSY;
mutex_lock(&target->i_mutex);
error = -EBUSY;
- if (
d_mountpoint(old_dentry) || d
_mountpoint(new_dentry))
+ if (
is_local_mountpoint(old_dentry) || is_local
_mountpoint(new_dentry))
goto out;
if (max_links && new_dir != old_dir) {
goto out;
if (max_links && new_dir != old_dir) {
@@
-4167,6
+4168,7
@@
int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
if (is_dir)
target->i_flags |= S_DEAD;
dont_mount(new_dentry);
if (is_dir)
target->i_flags |= S_DEAD;
dont_mount(new_dentry);
+ detach_mounts(new_dentry);
}
if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE)) {
if (!(flags & RENAME_EXCHANGE))
}
if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE)) {
if (!(flags & RENAME_EXCHANGE))