mirror of https://gitee.com/openkylin/linux.git
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: fs/dcache: allow d_obtain_alias() to return unhashed dentries Check for immutable/append flag in fallocate path sysctl: the include of rcupdate.h is only needed in the kernel fat: fix d_revalidate oopsen on NFS exports jfs: fix d_revalidate oopsen on NFS exports ocfs2: fix d_revalidate oopsen on NFS exports gfs2: fix d_revalidate oopsen on NFS exports fuse: fix d_revalidate oopsen on NFS exports ceph: fix d_revalidate oopsen on NFS exports reiserfs xattr ->d_revalidate() shouldn't care about RCU /proc/self is never going to be invalidated...
This commit is contained in:
commit
4afcc10a65
|
@ -993,7 +993,7 @@ static int ceph_d_revalidate(struct dentry *dentry, struct nameidata *nd)
|
||||||
{
|
{
|
||||||
struct inode *dir;
|
struct inode *dir;
|
||||||
|
|
||||||
if (nd->flags & LOOKUP_RCU)
|
if (nd && nd->flags & LOOKUP_RCU)
|
||||||
return -ECHILD;
|
return -ECHILD;
|
||||||
|
|
||||||
dir = dentry->d_parent->d_inode;
|
dir = dentry->d_parent->d_inode;
|
||||||
|
|
26
fs/dcache.c
26
fs/dcache.c
|
@ -1523,6 +1523,28 @@ struct dentry * d_alloc_root(struct inode * root_inode)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(d_alloc_root);
|
EXPORT_SYMBOL(d_alloc_root);
|
||||||
|
|
||||||
|
static struct dentry * __d_find_any_alias(struct inode *inode)
|
||||||
|
{
|
||||||
|
struct dentry *alias;
|
||||||
|
|
||||||
|
if (list_empty(&inode->i_dentry))
|
||||||
|
return NULL;
|
||||||
|
alias = list_first_entry(&inode->i_dentry, struct dentry, d_alias);
|
||||||
|
__dget(alias);
|
||||||
|
return alias;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct dentry * d_find_any_alias(struct inode *inode)
|
||||||
|
{
|
||||||
|
struct dentry *de;
|
||||||
|
|
||||||
|
spin_lock(&inode->i_lock);
|
||||||
|
de = __d_find_any_alias(inode);
|
||||||
|
spin_unlock(&inode->i_lock);
|
||||||
|
return de;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* d_obtain_alias - find or allocate a dentry for a given inode
|
* d_obtain_alias - find or allocate a dentry for a given inode
|
||||||
* @inode: inode to allocate the dentry for
|
* @inode: inode to allocate the dentry for
|
||||||
|
@ -1552,7 +1574,7 @@ struct dentry *d_obtain_alias(struct inode *inode)
|
||||||
if (IS_ERR(inode))
|
if (IS_ERR(inode))
|
||||||
return ERR_CAST(inode);
|
return ERR_CAST(inode);
|
||||||
|
|
||||||
res = d_find_alias(inode);
|
res = d_find_any_alias(inode);
|
||||||
if (res)
|
if (res)
|
||||||
goto out_iput;
|
goto out_iput;
|
||||||
|
|
||||||
|
@ -1565,7 +1587,7 @@ struct dentry *d_obtain_alias(struct inode *inode)
|
||||||
|
|
||||||
|
|
||||||
spin_lock(&inode->i_lock);
|
spin_lock(&inode->i_lock);
|
||||||
res = __d_find_alias(inode, 0);
|
res = __d_find_any_alias(inode);
|
||||||
if (res) {
|
if (res) {
|
||||||
spin_unlock(&inode->i_lock);
|
spin_unlock(&inode->i_lock);
|
||||||
dput(tmp);
|
dput(tmp);
|
||||||
|
|
|
@ -43,7 +43,7 @@ static int vfat_revalidate_shortname(struct dentry *dentry)
|
||||||
|
|
||||||
static int vfat_revalidate(struct dentry *dentry, struct nameidata *nd)
|
static int vfat_revalidate(struct dentry *dentry, struct nameidata *nd)
|
||||||
{
|
{
|
||||||
if (nd->flags & LOOKUP_RCU)
|
if (nd && nd->flags & LOOKUP_RCU)
|
||||||
return -ECHILD;
|
return -ECHILD;
|
||||||
|
|
||||||
/* This is not negative dentry. Always valid. */
|
/* This is not negative dentry. Always valid. */
|
||||||
|
@ -54,7 +54,7 @@ static int vfat_revalidate(struct dentry *dentry, struct nameidata *nd)
|
||||||
|
|
||||||
static int vfat_revalidate_ci(struct dentry *dentry, struct nameidata *nd)
|
static int vfat_revalidate_ci(struct dentry *dentry, struct nameidata *nd)
|
||||||
{
|
{
|
||||||
if (nd->flags & LOOKUP_RCU)
|
if (nd && nd->flags & LOOKUP_RCU)
|
||||||
return -ECHILD;
|
return -ECHILD;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -158,7 +158,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
|
||||||
{
|
{
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
|
|
||||||
if (nd->flags & LOOKUP_RCU)
|
if (nd && nd->flags & LOOKUP_RCU)
|
||||||
return -ECHILD;
|
return -ECHILD;
|
||||||
|
|
||||||
inode = entry->d_inode;
|
inode = entry->d_inode;
|
||||||
|
|
|
@ -44,7 +44,7 @@ static int gfs2_drevalidate(struct dentry *dentry, struct nameidata *nd)
|
||||||
int error;
|
int error;
|
||||||
int had_lock = 0;
|
int had_lock = 0;
|
||||||
|
|
||||||
if (nd->flags & LOOKUP_RCU)
|
if (nd && nd->flags & LOOKUP_RCU)
|
||||||
return -ECHILD;
|
return -ECHILD;
|
||||||
|
|
||||||
parent = dget_parent(dentry);
|
parent = dget_parent(dentry);
|
||||||
|
|
|
@ -1600,7 +1600,7 @@ static int jfs_ci_compare(const struct dentry *parent,
|
||||||
|
|
||||||
static int jfs_ci_revalidate(struct dentry *dentry, struct nameidata *nd)
|
static int jfs_ci_revalidate(struct dentry *dentry, struct nameidata *nd)
|
||||||
{
|
{
|
||||||
if (nd->flags & LOOKUP_RCU)
|
if (nd && nd->flags & LOOKUP_RCU)
|
||||||
return -ECHILD;
|
return -ECHILD;
|
||||||
/*
|
/*
|
||||||
* This is not negative dentry. Always valid.
|
* This is not negative dentry. Always valid.
|
||||||
|
|
|
@ -56,7 +56,7 @@ static int ocfs2_dentry_revalidate(struct dentry *dentry,
|
||||||
int ret = 0; /* if all else fails, just return false */
|
int ret = 0; /* if all else fails, just return false */
|
||||||
struct ocfs2_super *osb;
|
struct ocfs2_super *osb;
|
||||||
|
|
||||||
if (nd->flags & LOOKUP_RCU)
|
if (nd && nd->flags & LOOKUP_RCU)
|
||||||
return -ECHILD;
|
return -ECHILD;
|
||||||
|
|
||||||
inode = dentry->d_inode;
|
inode = dentry->d_inode;
|
||||||
|
|
|
@ -233,6 +233,14 @@ int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
|
||||||
|
|
||||||
if (!(file->f_mode & FMODE_WRITE))
|
if (!(file->f_mode & FMODE_WRITE))
|
||||||
return -EBADF;
|
return -EBADF;
|
||||||
|
|
||||||
|
/* It's not possible punch hole on append only file */
|
||||||
|
if (mode & FALLOC_FL_PUNCH_HOLE && IS_APPEND(inode))
|
||||||
|
return -EPERM;
|
||||||
|
|
||||||
|
if (IS_IMMUTABLE(inode))
|
||||||
|
return -EPERM;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Revalidate the write permissions, in case security policy has
|
* Revalidate the write permissions, in case security policy has
|
||||||
* changed since the files were opened.
|
* changed since the files were opened.
|
||||||
|
|
|
@ -2620,35 +2620,6 @@ static const struct pid_entry proc_base_stuff[] = {
|
||||||
&proc_self_inode_operations, NULL, {}),
|
&proc_self_inode_operations, NULL, {}),
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* Exceptional case: normally we are not allowed to unhash a busy
|
|
||||||
* directory. In this case, however, we can do it - no aliasing problems
|
|
||||||
* due to the way we treat inodes.
|
|
||||||
*/
|
|
||||||
static int proc_base_revalidate(struct dentry *dentry, struct nameidata *nd)
|
|
||||||
{
|
|
||||||
struct inode *inode;
|
|
||||||
struct task_struct *task;
|
|
||||||
|
|
||||||
if (nd->flags & LOOKUP_RCU)
|
|
||||||
return -ECHILD;
|
|
||||||
|
|
||||||
inode = dentry->d_inode;
|
|
||||||
task = get_proc_task(inode);
|
|
||||||
if (task) {
|
|
||||||
put_task_struct(task);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
d_drop(dentry);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct dentry_operations proc_base_dentry_operations =
|
|
||||||
{
|
|
||||||
.d_revalidate = proc_base_revalidate,
|
|
||||||
.d_delete = pid_delete_dentry,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct dentry *proc_base_instantiate(struct inode *dir,
|
static struct dentry *proc_base_instantiate(struct inode *dir,
|
||||||
struct dentry *dentry, struct task_struct *task, const void *ptr)
|
struct dentry *dentry, struct task_struct *task, const void *ptr)
|
||||||
{
|
{
|
||||||
|
@ -2685,7 +2656,6 @@ static struct dentry *proc_base_instantiate(struct inode *dir,
|
||||||
if (p->fop)
|
if (p->fop)
|
||||||
inode->i_fop = p->fop;
|
inode->i_fop = p->fop;
|
||||||
ei->op = p->op;
|
ei->op = p->op;
|
||||||
d_set_d_op(dentry, &proc_base_dentry_operations);
|
|
||||||
d_add(dentry, inode);
|
d_add(dentry, inode);
|
||||||
error = NULL;
|
error = NULL;
|
||||||
out:
|
out:
|
||||||
|
|
|
@ -978,8 +978,6 @@ int reiserfs_permission(struct inode *inode, int mask, unsigned int flags)
|
||||||
|
|
||||||
static int xattr_hide_revalidate(struct dentry *dentry, struct nameidata *nd)
|
static int xattr_hide_revalidate(struct dentry *dentry, struct nameidata *nd)
|
||||||
{
|
{
|
||||||
if (nd->flags & LOOKUP_RCU)
|
|
||||||
return -ECHILD;
|
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue