Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/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...
  • Loading branch information
torvalds committed Mar 10, 2011
2 parents b5562c9 + d891eed commit 4afcc10
Show file tree
Hide file tree
Showing 10 changed files with 39 additions and 41 deletions.
2 changes: 1 addition & 1 deletion fs/ceph/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -993,7 +993,7 @@ static int ceph_d_revalidate(struct dentry *dentry, struct nameidata *nd)
{
struct inode *dir;

if (nd->flags & LOOKUP_RCU)
if (nd && nd->flags & LOOKUP_RCU)
return -ECHILD;

dir = dentry->d_parent->d_inode;
Expand Down
26 changes: 24 additions & 2 deletions fs/dcache.c
Original file line number Diff line number Diff line change
Expand Up @@ -1523,6 +1523,28 @@ struct dentry * d_alloc_root(struct inode * root_inode)
}
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
* @inode: inode to allocate the dentry for
Expand Down Expand Up @@ -1552,7 +1574,7 @@ struct dentry *d_obtain_alias(struct inode *inode)
if (IS_ERR(inode))
return ERR_CAST(inode);

res = d_find_alias(inode);
res = d_find_any_alias(inode);
if (res)
goto out_iput;

Expand All @@ -1565,7 +1587,7 @@ struct dentry *d_obtain_alias(struct inode *inode)


spin_lock(&inode->i_lock);
res = __d_find_alias(inode, 0);
res = __d_find_any_alias(inode);
if (res) {
spin_unlock(&inode->i_lock);
dput(tmp);
Expand Down
4 changes: 2 additions & 2 deletions fs/fat/namei_vfat.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ static int vfat_revalidate_shortname(struct dentry *dentry)

static int vfat_revalidate(struct dentry *dentry, struct nameidata *nd)
{
if (nd->flags & LOOKUP_RCU)
if (nd && nd->flags & LOOKUP_RCU)
return -ECHILD;

/* This is not negative dentry. Always valid. */
Expand All @@ -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)
{
if (nd->flags & LOOKUP_RCU)
if (nd && nd->flags & LOOKUP_RCU)
return -ECHILD;

/*
Expand Down
2 changes: 1 addition & 1 deletion fs/fuse/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
{
struct inode *inode;

if (nd->flags & LOOKUP_RCU)
if (nd && nd->flags & LOOKUP_RCU)
return -ECHILD;

inode = entry->d_inode;
Expand Down
2 changes: 1 addition & 1 deletion fs/gfs2/dentry.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ static int gfs2_drevalidate(struct dentry *dentry, struct nameidata *nd)
int error;
int had_lock = 0;

if (nd->flags & LOOKUP_RCU)
if (nd && nd->flags & LOOKUP_RCU)
return -ECHILD;

parent = dget_parent(dentry);
Expand Down
2 changes: 1 addition & 1 deletion fs/jfs/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -1600,7 +1600,7 @@ static int jfs_ci_compare(const struct dentry *parent,

static int jfs_ci_revalidate(struct dentry *dentry, struct nameidata *nd)
{
if (nd->flags & LOOKUP_RCU)
if (nd && nd->flags & LOOKUP_RCU)
return -ECHILD;
/*
* This is not negative dentry. Always valid.
Expand Down
2 changes: 1 addition & 1 deletion fs/ocfs2/dcache.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ static int ocfs2_dentry_revalidate(struct dentry *dentry,
int ret = 0; /* if all else fails, just return false */
struct ocfs2_super *osb;

if (nd->flags & LOOKUP_RCU)
if (nd && nd->flags & LOOKUP_RCU)
return -ECHILD;

inode = dentry->d_inode;
Expand Down
8 changes: 8 additions & 0 deletions fs/open.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,14 @@ int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len)

if (!(file->f_mode & FMODE_WRITE))
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
* changed since the files were opened.
Expand Down
30 changes: 0 additions & 30 deletions fs/proc/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -2620,35 +2620,6 @@ static const struct pid_entry proc_base_stuff[] = {
&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,
struct dentry *dentry, struct task_struct *task, const void *ptr)
{
Expand Down Expand Up @@ -2685,7 +2656,6 @@ static struct dentry *proc_base_instantiate(struct inode *dir,
if (p->fop)
inode->i_fop = p->fop;
ei->op = p->op;
d_set_d_op(dentry, &proc_base_dentry_operations);
d_add(dentry, inode);
error = NULL;
out:
Expand Down
2 changes: 0 additions & 2 deletions fs/reiserfs/xattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
if (nd->flags & LOOKUP_RCU)
return -ECHILD;
return -EPERM;
}

Expand Down

0 comments on commit 4afcc10

Please sign in to comment.