diff options
-rw-r--r-- | fs/ceph/dir.c | 2 | ||||
-rw-r--r-- | fs/dcache.c | 26 | ||||
-rw-r--r-- | fs/fat/namei_vfat.c | 4 | ||||
-rw-r--r-- | fs/fuse/dir.c | 2 | ||||
-rw-r--r-- | fs/gfs2/dentry.c | 2 | ||||
-rw-r--r-- | fs/jfs/namei.c | 2 | ||||
-rw-r--r-- | fs/ocfs2/dcache.c | 2 | ||||
-rw-r--r-- | fs/open.c | 8 | ||||
-rw-r--r-- | fs/proc/base.c | 30 | ||||
-rw-r--r-- | fs/reiserfs/xattr.c | 2 |
10 files changed, 39 insertions, 41 deletions
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 099a58615b90..ebafa65a29b6 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c | |||
@@ -993,7 +993,7 @@ static int ceph_d_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
993 | { | 993 | { |
994 | struct inode *dir; | 994 | struct inode *dir; |
995 | 995 | ||
996 | if (nd->flags & LOOKUP_RCU) | 996 | if (nd && nd->flags & LOOKUP_RCU) |
997 | return -ECHILD; | 997 | return -ECHILD; |
998 | 998 | ||
999 | dir = dentry->d_parent->d_inode; | 999 | dir = dentry->d_parent->d_inode; |
diff --git a/fs/dcache.c b/fs/dcache.c index 2a6bd9a4ae97..611ffe928c03 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -1523,6 +1523,28 @@ struct dentry * d_alloc_root(struct inode * root_inode) | |||
1523 | } | 1523 | } |
1524 | EXPORT_SYMBOL(d_alloc_root); | 1524 | EXPORT_SYMBOL(d_alloc_root); |
1525 | 1525 | ||
1526 | static struct dentry * __d_find_any_alias(struct inode *inode) | ||
1527 | { | ||
1528 | struct dentry *alias; | ||
1529 | |||
1530 | if (list_empty(&inode->i_dentry)) | ||
1531 | return NULL; | ||
1532 | alias = list_first_entry(&inode->i_dentry, struct dentry, d_alias); | ||
1533 | __dget(alias); | ||
1534 | return alias; | ||
1535 | } | ||
1536 | |||
1537 | static struct dentry * d_find_any_alias(struct inode *inode) | ||
1538 | { | ||
1539 | struct dentry *de; | ||
1540 | |||
1541 | spin_lock(&inode->i_lock); | ||
1542 | de = __d_find_any_alias(inode); | ||
1543 | spin_unlock(&inode->i_lock); | ||
1544 | return de; | ||
1545 | } | ||
1546 | |||
1547 | |||
1526 | /** | 1548 | /** |
1527 | * d_obtain_alias - find or allocate a dentry for a given inode | 1549 | * d_obtain_alias - find or allocate a dentry for a given inode |
1528 | * @inode: inode to allocate the dentry for | 1550 | * @inode: inode to allocate the dentry for |
@@ -1552,7 +1574,7 @@ struct dentry *d_obtain_alias(struct inode *inode) | |||
1552 | if (IS_ERR(inode)) | 1574 | if (IS_ERR(inode)) |
1553 | return ERR_CAST(inode); | 1575 | return ERR_CAST(inode); |
1554 | 1576 | ||
1555 | res = d_find_alias(inode); | 1577 | res = d_find_any_alias(inode); |
1556 | if (res) | 1578 | if (res) |
1557 | goto out_iput; | 1579 | goto out_iput; |
1558 | 1580 | ||
@@ -1565,7 +1587,7 @@ struct dentry *d_obtain_alias(struct inode *inode) | |||
1565 | 1587 | ||
1566 | 1588 | ||
1567 | spin_lock(&inode->i_lock); | 1589 | spin_lock(&inode->i_lock); |
1568 | res = __d_find_alias(inode, 0); | 1590 | res = __d_find_any_alias(inode); |
1569 | if (res) { | 1591 | if (res) { |
1570 | spin_unlock(&inode->i_lock); | 1592 | spin_unlock(&inode->i_lock); |
1571 | dput(tmp); | 1593 | dput(tmp); |
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c index f88f752babd9..adae3fb7451a 100644 --- a/fs/fat/namei_vfat.c +++ b/fs/fat/namei_vfat.c | |||
@@ -43,7 +43,7 @@ static int vfat_revalidate_shortname(struct dentry *dentry) | |||
43 | 43 | ||
44 | static int vfat_revalidate(struct dentry *dentry, struct nameidata *nd) | 44 | static int vfat_revalidate(struct dentry *dentry, struct nameidata *nd) |
45 | { | 45 | { |
46 | if (nd->flags & LOOKUP_RCU) | 46 | if (nd && nd->flags & LOOKUP_RCU) |
47 | return -ECHILD; | 47 | return -ECHILD; |
48 | 48 | ||
49 | /* This is not negative dentry. Always valid. */ | 49 | /* This is not negative dentry. Always valid. */ |
@@ -54,7 +54,7 @@ static int vfat_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
54 | 54 | ||
55 | static int vfat_revalidate_ci(struct dentry *dentry, struct nameidata *nd) | 55 | static int vfat_revalidate_ci(struct dentry *dentry, struct nameidata *nd) |
56 | { | 56 | { |
57 | if (nd->flags & LOOKUP_RCU) | 57 | if (nd && nd->flags & LOOKUP_RCU) |
58 | return -ECHILD; | 58 | return -ECHILD; |
59 | 59 | ||
60 | /* | 60 | /* |
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 83543b5ff941..8bd0ef9286c3 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -158,7 +158,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd) | |||
158 | { | 158 | { |
159 | struct inode *inode; | 159 | struct inode *inode; |
160 | 160 | ||
161 | if (nd->flags & LOOKUP_RCU) | 161 | if (nd && nd->flags & LOOKUP_RCU) |
162 | return -ECHILD; | 162 | return -ECHILD; |
163 | 163 | ||
164 | inode = entry->d_inode; | 164 | inode = entry->d_inode; |
diff --git a/fs/gfs2/dentry.c b/fs/gfs2/dentry.c index 4a456338b873..0da8da2c991d 100644 --- a/fs/gfs2/dentry.c +++ b/fs/gfs2/dentry.c | |||
@@ -44,7 +44,7 @@ static int gfs2_drevalidate(struct dentry *dentry, struct nameidata *nd) | |||
44 | int error; | 44 | int error; |
45 | int had_lock = 0; | 45 | int had_lock = 0; |
46 | 46 | ||
47 | if (nd->flags & LOOKUP_RCU) | 47 | if (nd && nd->flags & LOOKUP_RCU) |
48 | return -ECHILD; | 48 | return -ECHILD; |
49 | 49 | ||
50 | parent = dget_parent(dentry); | 50 | parent = dget_parent(dentry); |
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 81ead850ddb6..5a2b269428a6 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c | |||
@@ -1600,7 +1600,7 @@ out: | |||
1600 | 1600 | ||
1601 | static int jfs_ci_revalidate(struct dentry *dentry, struct nameidata *nd) | 1601 | static int jfs_ci_revalidate(struct dentry *dentry, struct nameidata *nd) |
1602 | { | 1602 | { |
1603 | if (nd->flags & LOOKUP_RCU) | 1603 | if (nd && nd->flags & LOOKUP_RCU) |
1604 | return -ECHILD; | 1604 | return -ECHILD; |
1605 | /* | 1605 | /* |
1606 | * This is not negative dentry. Always valid. | 1606 | * This is not negative dentry. Always valid. |
diff --git a/fs/ocfs2/dcache.c b/fs/ocfs2/dcache.c index 6d80ecc7834f..7eb90403fc8a 100644 --- a/fs/ocfs2/dcache.c +++ b/fs/ocfs2/dcache.c | |||
@@ -56,7 +56,7 @@ static int ocfs2_dentry_revalidate(struct dentry *dentry, | |||
56 | int ret = 0; /* if all else fails, just return false */ | 56 | int ret = 0; /* if all else fails, just return false */ |
57 | struct ocfs2_super *osb; | 57 | struct ocfs2_super *osb; |
58 | 58 | ||
59 | if (nd->flags & LOOKUP_RCU) | 59 | if (nd && nd->flags & LOOKUP_RCU) |
60 | return -ECHILD; | 60 | return -ECHILD; |
61 | 61 | ||
62 | inode = dentry->d_inode; | 62 | inode = dentry->d_inode; |
@@ -233,6 +233,14 @@ int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len) | |||
233 | 233 | ||
234 | if (!(file->f_mode & FMODE_WRITE)) | 234 | if (!(file->f_mode & FMODE_WRITE)) |
235 | return -EBADF; | 235 | return -EBADF; |
236 | |||
237 | /* It's not possible punch hole on append only file */ | ||
238 | if (mode & FALLOC_FL_PUNCH_HOLE && IS_APPEND(inode)) | ||
239 | return -EPERM; | ||
240 | |||
241 | if (IS_IMMUTABLE(inode)) | ||
242 | return -EPERM; | ||
243 | |||
236 | /* | 244 | /* |
237 | * Revalidate the write permissions, in case security policy has | 245 | * Revalidate the write permissions, in case security policy has |
238 | * changed since the files were opened. | 246 | * changed since the files were opened. |
diff --git a/fs/proc/base.c b/fs/proc/base.c index 9d096e82b201..d49c4b5d2c3e 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -2620,35 +2620,6 @@ static const struct pid_entry proc_base_stuff[] = { | |||
2620 | &proc_self_inode_operations, NULL, {}), | 2620 | &proc_self_inode_operations, NULL, {}), |
2621 | }; | 2621 | }; |
2622 | 2622 | ||
2623 | /* | ||
2624 | * Exceptional case: normally we are not allowed to unhash a busy | ||
2625 | * directory. In this case, however, we can do it - no aliasing problems | ||
2626 | * due to the way we treat inodes. | ||
2627 | */ | ||
2628 | static int proc_base_revalidate(struct dentry *dentry, struct nameidata *nd) | ||
2629 | { | ||
2630 | struct inode *inode; | ||
2631 | struct task_struct *task; | ||
2632 | |||
2633 | if (nd->flags & LOOKUP_RCU) | ||
2634 | return -ECHILD; | ||
2635 | |||
2636 | inode = dentry->d_inode; | ||
2637 | task = get_proc_task(inode); | ||
2638 | if (task) { | ||
2639 | put_task_struct(task); | ||
2640 | return 1; | ||
2641 | } | ||
2642 | d_drop(dentry); | ||
2643 | return 0; | ||
2644 | } | ||
2645 | |||
2646 | static const struct dentry_operations proc_base_dentry_operations = | ||
2647 | { | ||
2648 | .d_revalidate = proc_base_revalidate, | ||
2649 | .d_delete = pid_delete_dentry, | ||
2650 | }; | ||
2651 | |||
2652 | static struct dentry *proc_base_instantiate(struct inode *dir, | 2623 | static struct dentry *proc_base_instantiate(struct inode *dir, |
2653 | struct dentry *dentry, struct task_struct *task, const void *ptr) | 2624 | struct dentry *dentry, struct task_struct *task, const void *ptr) |
2654 | { | 2625 | { |
@@ -2685,7 +2656,6 @@ static struct dentry *proc_base_instantiate(struct inode *dir, | |||
2685 | if (p->fop) | 2656 | if (p->fop) |
2686 | inode->i_fop = p->fop; | 2657 | inode->i_fop = p->fop; |
2687 | ei->op = p->op; | 2658 | ei->op = p->op; |
2688 | d_set_d_op(dentry, &proc_base_dentry_operations); | ||
2689 | d_add(dentry, inode); | 2659 | d_add(dentry, inode); |
2690 | error = NULL; | 2660 | error = NULL; |
2691 | out: | 2661 | out: |
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 3cfb2e933644..5c11ca82b782 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c | |||
@@ -978,8 +978,6 @@ int reiserfs_permission(struct inode *inode, int mask, unsigned int flags) | |||
978 | 978 | ||
979 | static int xattr_hide_revalidate(struct dentry *dentry, struct nameidata *nd) | 979 | static int xattr_hide_revalidate(struct dentry *dentry, struct nameidata *nd) |
980 | { | 980 | { |
981 | if (nd->flags & LOOKUP_RCU) | ||
982 | return -ECHILD; | ||
983 | return -EPERM; | 981 | return -EPERM; |
984 | } | 982 | } |
985 | 983 | ||