Skip to content

Commit 2645b9d

Browse files
committed
Merge tag 'fsnotify_for_v4.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
Pull fsnotify updates from Jan Kara: "fsnotify cleanups from Amir and a small inotify improvement" * tag 'fsnotify_for_v4.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs: inotify: Add flag IN_MASK_CREATE for inotify_add_watch() fanotify: factor out helpers to add/remove mark fsnotify: add helper to get mask from connector fsnotify: let connector point to an abstract object fsnotify: pass connp and object type to fsnotify_add_mark() fsnotify: use typedef fsnotify_connp_t for brevity
2 parents 46e62a0 + 4d97f7d commit 2645b9d

File tree

9 files changed

+157
-138
lines changed

9 files changed

+157
-138
lines changed

fs/notify/fanotify/fanotify_user.c

Lines changed: 37 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -524,65 +524,50 @@ static __u32 fanotify_mark_remove_from_mask(struct fsnotify_mark *fsn_mark,
524524
return mask & oldmask;
525525
}
526526

527-
static int fanotify_remove_vfsmount_mark(struct fsnotify_group *group,
528-
struct vfsmount *mnt, __u32 mask,
529-
unsigned int flags)
527+
static int fanotify_remove_mark(struct fsnotify_group *group,
528+
fsnotify_connp_t *connp, __u32 mask,
529+
unsigned int flags)
530530
{
531531
struct fsnotify_mark *fsn_mark = NULL;
532532
__u32 removed;
533533
int destroy_mark;
534534

535535
mutex_lock(&group->mark_mutex);
536-
fsn_mark = fsnotify_find_mark(&real_mount(mnt)->mnt_fsnotify_marks,
537-
group);
536+
fsn_mark = fsnotify_find_mark(connp, group);
538537
if (!fsn_mark) {
539538
mutex_unlock(&group->mark_mutex);
540539
return -ENOENT;
541540
}
542541

543542
removed = fanotify_mark_remove_from_mask(fsn_mark, mask, flags,
544543
&destroy_mark);
545-
if (removed & real_mount(mnt)->mnt_fsnotify_mask)
546-
fsnotify_recalc_mask(real_mount(mnt)->mnt_fsnotify_marks);
544+
if (removed & fsnotify_conn_mask(fsn_mark->connector))
545+
fsnotify_recalc_mask(fsn_mark->connector);
547546
if (destroy_mark)
548547
fsnotify_detach_mark(fsn_mark);
549548
mutex_unlock(&group->mark_mutex);
550549
if (destroy_mark)
551550
fsnotify_free_mark(fsn_mark);
552551

552+
/* matches the fsnotify_find_mark() */
553553
fsnotify_put_mark(fsn_mark);
554554
return 0;
555555
}
556556

557+
static int fanotify_remove_vfsmount_mark(struct fsnotify_group *group,
558+
struct vfsmount *mnt, __u32 mask,
559+
unsigned int flags)
560+
{
561+
return fanotify_remove_mark(group, &real_mount(mnt)->mnt_fsnotify_marks,
562+
mask, flags);
563+
}
564+
557565
static int fanotify_remove_inode_mark(struct fsnotify_group *group,
558566
struct inode *inode, __u32 mask,
559567
unsigned int flags)
560568
{
561-
struct fsnotify_mark *fsn_mark = NULL;
562-
__u32 removed;
563-
int destroy_mark;
564-
565-
mutex_lock(&group->mark_mutex);
566-
fsn_mark = fsnotify_find_mark(&inode->i_fsnotify_marks, group);
567-
if (!fsn_mark) {
568-
mutex_unlock(&group->mark_mutex);
569-
return -ENOENT;
570-
}
571-
572-
removed = fanotify_mark_remove_from_mask(fsn_mark, mask, flags,
573-
&destroy_mark);
574-
if (removed & inode->i_fsnotify_mask)
575-
fsnotify_recalc_mask(inode->i_fsnotify_marks);
576-
if (destroy_mark)
577-
fsnotify_detach_mark(fsn_mark);
578-
mutex_unlock(&group->mark_mutex);
579-
if (destroy_mark)
580-
fsnotify_free_mark(fsn_mark);
581-
582-
/* matches the fsnotify_find_mark() */
583-
fsnotify_put_mark(fsn_mark);
584-
585-
return 0;
569+
return fanotify_remove_mark(group, &inode->i_fsnotify_marks, mask,
570+
flags);
586571
}
587572

588573
static __u32 fanotify_mark_add_to_mask(struct fsnotify_mark *fsn_mark,
@@ -615,8 +600,8 @@ static __u32 fanotify_mark_add_to_mask(struct fsnotify_mark *fsn_mark,
615600
}
616601

617602
static struct fsnotify_mark *fanotify_add_new_mark(struct fsnotify_group *group,
618-
struct inode *inode,
619-
struct vfsmount *mnt)
603+
fsnotify_connp_t *connp,
604+
unsigned int type)
620605
{
621606
struct fsnotify_mark *mark;
622607
int ret;
@@ -629,7 +614,7 @@ static struct fsnotify_mark *fanotify_add_new_mark(struct fsnotify_group *group,
629614
return ERR_PTR(-ENOMEM);
630615

631616
fsnotify_init_mark(mark, group);
632-
ret = fsnotify_add_mark_locked(mark, inode, mnt, 0);
617+
ret = fsnotify_add_mark_locked(mark, connp, type, 0);
633618
if (ret) {
634619
fsnotify_put_mark(mark);
635620
return ERR_PTR(ret);
@@ -639,39 +624,43 @@ static struct fsnotify_mark *fanotify_add_new_mark(struct fsnotify_group *group,
639624
}
640625

641626

642-
static int fanotify_add_vfsmount_mark(struct fsnotify_group *group,
643-
struct vfsmount *mnt, __u32 mask,
644-
unsigned int flags)
627+
static int fanotify_add_mark(struct fsnotify_group *group,
628+
fsnotify_connp_t *connp, unsigned int type,
629+
__u32 mask, unsigned int flags)
645630
{
646631
struct fsnotify_mark *fsn_mark;
647632
__u32 added;
648633

649634
mutex_lock(&group->mark_mutex);
650-
fsn_mark = fsnotify_find_mark(&real_mount(mnt)->mnt_fsnotify_marks,
651-
group);
635+
fsn_mark = fsnotify_find_mark(connp, group);
652636
if (!fsn_mark) {
653-
fsn_mark = fanotify_add_new_mark(group, NULL, mnt);
637+
fsn_mark = fanotify_add_new_mark(group, connp, type);
654638
if (IS_ERR(fsn_mark)) {
655639
mutex_unlock(&group->mark_mutex);
656640
return PTR_ERR(fsn_mark);
657641
}
658642
}
659643
added = fanotify_mark_add_to_mask(fsn_mark, mask, flags);
660-
if (added & ~real_mount(mnt)->mnt_fsnotify_mask)
661-
fsnotify_recalc_mask(real_mount(mnt)->mnt_fsnotify_marks);
644+
if (added & ~fsnotify_conn_mask(fsn_mark->connector))
645+
fsnotify_recalc_mask(fsn_mark->connector);
662646
mutex_unlock(&group->mark_mutex);
663647

664648
fsnotify_put_mark(fsn_mark);
665649
return 0;
666650
}
667651

652+
static int fanotify_add_vfsmount_mark(struct fsnotify_group *group,
653+
struct vfsmount *mnt, __u32 mask,
654+
unsigned int flags)
655+
{
656+
return fanotify_add_mark(group, &real_mount(mnt)->mnt_fsnotify_marks,
657+
FSNOTIFY_OBJ_TYPE_VFSMOUNT, mask, flags);
658+
}
659+
668660
static int fanotify_add_inode_mark(struct fsnotify_group *group,
669661
struct inode *inode, __u32 mask,
670662
unsigned int flags)
671663
{
672-
struct fsnotify_mark *fsn_mark;
673-
__u32 added;
674-
675664
pr_debug("%s: group=%p inode=%p\n", __func__, group, inode);
676665

677666
/*
@@ -684,22 +673,8 @@ static int fanotify_add_inode_mark(struct fsnotify_group *group,
684673
(atomic_read(&inode->i_writecount) > 0))
685674
return 0;
686675

687-
mutex_lock(&group->mark_mutex);
688-
fsn_mark = fsnotify_find_mark(&inode->i_fsnotify_marks, group);
689-
if (!fsn_mark) {
690-
fsn_mark = fanotify_add_new_mark(group, inode, NULL);
691-
if (IS_ERR(fsn_mark)) {
692-
mutex_unlock(&group->mark_mutex);
693-
return PTR_ERR(fsn_mark);
694-
}
695-
}
696-
added = fanotify_mark_add_to_mask(fsn_mark, mask, flags);
697-
if (added & ~inode->i_fsnotify_mask)
698-
fsnotify_recalc_mask(inode->i_fsnotify_marks);
699-
mutex_unlock(&group->mark_mutex);
700-
701-
fsnotify_put_mark(fsn_mark);
702-
return 0;
676+
return fanotify_add_mark(group, &inode->i_fsnotify_marks,
677+
FSNOTIFY_OBJ_TYPE_INODE, mask, flags);
703678
}
704679

705680
/* fanotify syscalls */

fs/notify/fdinfo.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
#include <linux/exportfs.h>
1616

1717
#include "inotify/inotify.h"
18-
#include "../fs/mount.h"
18+
#include "fsnotify.h"
1919

2020
#if defined(CONFIG_PROC_FS)
2121

@@ -81,7 +81,7 @@ static void inotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark)
8181
return;
8282

8383
inode_mark = container_of(mark, struct inotify_inode_mark, fsn_mark);
84-
inode = igrab(mark->connector->inode);
84+
inode = igrab(fsnotify_conn_inode(mark->connector));
8585
if (inode) {
8686
/*
8787
* IN_ALL_EVENTS represents all of the mask bits
@@ -117,7 +117,7 @@ static void fanotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark)
117117
mflags |= FAN_MARK_IGNORED_SURV_MODIFY;
118118

119119
if (mark->connector->type == FSNOTIFY_OBJ_TYPE_INODE) {
120-
inode = igrab(mark->connector->inode);
120+
inode = igrab(fsnotify_conn_inode(mark->connector));
121121
if (!inode)
122122
return;
123123
seq_printf(m, "fanotify ino:%lx sdev:%x mflags:%x mask:%x ignored_mask:%x ",
@@ -127,7 +127,7 @@ static void fanotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark)
127127
seq_putc(m, '\n');
128128
iput(inode);
129129
} else if (mark->connector->type == FSNOTIFY_OBJ_TYPE_VFSMOUNT) {
130-
struct mount *mnt = real_mount(mark->connector->mnt);
130+
struct mount *mnt = fsnotify_conn_mount(mark->connector);
131131

132132
seq_printf(m, "fanotify mnt_id:%x mflags:%x mask:%x ignored_mask:%x\n",
133133
mnt->mnt_id, mflags, mark->mask, mark->ignored_mask);

fs/notify/fsnotify.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,18 @@
99

1010
#include "../mount.h"
1111

12+
static inline struct inode *fsnotify_conn_inode(
13+
struct fsnotify_mark_connector *conn)
14+
{
15+
return container_of(conn->obj, struct inode, i_fsnotify_marks);
16+
}
17+
18+
static inline struct mount *fsnotify_conn_mount(
19+
struct fsnotify_mark_connector *conn)
20+
{
21+
return container_of(conn->obj, struct mount, mnt_fsnotify_marks);
22+
}
23+
1224
/* destroy all events sitting in this groups notification queue */
1325
extern void fsnotify_flush_notify(struct fsnotify_group *group);
1426

@@ -19,8 +31,8 @@ extern struct srcu_struct fsnotify_mark_srcu;
1931
extern int fsnotify_compare_groups(struct fsnotify_group *a,
2032
struct fsnotify_group *b);
2133

22-
/* Destroy all marks connected via given connector */
23-
extern void fsnotify_destroy_marks(struct fsnotify_mark_connector __rcu **connp);
34+
/* Destroy all marks attached to an object via connector */
35+
extern void fsnotify_destroy_marks(fsnotify_connp_t *connp);
2436
/* run the list of all marks associated with inode and destroy them */
2537
static inline void fsnotify_clear_marks_by_inode(struct inode *inode)
2638
{

fs/notify/inotify/inotify_user.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -510,13 +510,16 @@ static int inotify_update_existing_watch(struct fsnotify_group *group,
510510
__u32 old_mask, new_mask;
511511
__u32 mask;
512512
int add = (arg & IN_MASK_ADD);
513+
int create = (arg & IN_MASK_CREATE);
513514
int ret;
514515

515516
mask = inotify_arg_to_mask(arg);
516517

517518
fsn_mark = fsnotify_find_mark(&inode->i_fsnotify_marks, group);
518519
if (!fsn_mark)
519520
return -ENOENT;
521+
else if (create)
522+
return -EEXIST;
520523

521524
i_mark = container_of(fsn_mark, struct inotify_inode_mark, fsn_mark);
522525

@@ -718,6 +721,10 @@ SYSCALL_DEFINE3(inotify_add_watch, int, fd, const char __user *, pathname,
718721
if (unlikely(!f.file))
719722
return -EBADF;
720723

724+
/* IN_MASK_ADD and IN_MASK_CREATE don't make sense together */
725+
if (unlikely((mask & IN_MASK_ADD) && (mask & IN_MASK_CREATE)))
726+
return -EINVAL;
727+
721728
/* verify that this is indeed an inotify instance */
722729
if (unlikely(f.file->f_op != &inotify_fops)) {
723730
ret = -EINVAL;
@@ -806,7 +813,7 @@ static int __init inotify_user_setup(void)
806813
BUILD_BUG_ON(IN_ISDIR != FS_ISDIR);
807814
BUILD_BUG_ON(IN_ONESHOT != FS_IN_ONESHOT);
808815

809-
BUG_ON(hweight32(ALL_INOTIFY_BITS) != 21);
816+
BUG_ON(hweight32(ALL_INOTIFY_BITS) != 22);
810817

811818
inotify_inode_mark_cachep = KMEM_CACHE(inotify_inode_mark, SLAB_PANIC);
812819

0 commit comments

Comments
 (0)