if (flags & ~FAN_ALL_MARK_FLAGS)
                return -EINVAL;
-       switch (flags & (FAN_MARK_ADD | FAN_MARK_REMOVE)) {
+       switch (flags & (FAN_MARK_ADD | FAN_MARK_REMOVE | FAN_MARK_FLUSH)) {
        case FAN_MARK_ADD:
        case FAN_MARK_REMOVE:
+       case FAN_MARK_FLUSH:
                break;
        default:
                return -EINVAL;
        group = filp->private_data;
 
        /* create/update an inode mark */
-       switch (flags & (FAN_MARK_ADD | FAN_MARK_REMOVE)) {
+       switch (flags & (FAN_MARK_ADD | FAN_MARK_REMOVE | FAN_MARK_FLUSH)) {
        case FAN_MARK_ADD:
                if (flags & FAN_MARK_MOUNT)
                        ret = fanotify_add_vfsmount_mark(group, mnt, mask, flags);
                else
                        ret = fanotify_remove_inode_mark(group, inode, mask, flags);
                break;
+       case FAN_MARK_FLUSH:
+               if (flags & FAN_MARK_MOUNT)
+                       fsnotify_clear_vfsmount_marks_by_group(group);
+               else
+                       fsnotify_clear_inode_marks_by_group(group);
+               fsnotify_recalc_group_mask(group);
+               break;
        default:
                ret = -EINVAL;
        }
 
        }
 }
 
+/*
+ * Given a group clear all of the inode marks associated with that group.
+ */
+void fsnotify_clear_inode_marks_by_group(struct fsnotify_group *group)
+{
+       fsnotify_clear_marks_by_group_flags(group, FSNOTIFY_MARK_FLAG_INODE);
+}
+
 /*
  * given a group and inode, find the mark associated with that combination.
  * if found take a reference to that mark and return it, else return NULL
 
 }
 
 /*
- * Given a group, destroy all of the marks associated with that group.
+ * clear any marks in a group in which mark->flags & flags is true
  */
-void fsnotify_clear_marks_by_group(struct fsnotify_group *group)
+void fsnotify_clear_marks_by_group_flags(struct fsnotify_group *group,
+                                        unsigned int flags)
 {
        struct fsnotify_mark *lmark, *mark;
        LIST_HEAD(free_list);
 
        spin_lock(&group->mark_lock);
        list_for_each_entry_safe(mark, lmark, &group->marks_list, g_list) {
-               list_add(&mark->free_g_list, &free_list);
-               list_del_init(&mark->g_list);
-               fsnotify_get_mark(mark);
+               if (mark->flags & flags) {
+                       list_add(&mark->free_g_list, &free_list);
+                       list_del_init(&mark->g_list);
+                       fsnotify_get_mark(mark);
+               }
        }
        spin_unlock(&group->mark_lock);
 
        }
 }
 
+/*
+ * Given a group, destroy all of the marks associated with that group.
+ */
+void fsnotify_clear_marks_by_group(struct fsnotify_group *group)
+{
+       fsnotify_clear_marks_by_group_flags(group, (unsigned int)-1);
+}
+
 void fsnotify_duplicate_mark(struct fsnotify_mark *new, struct fsnotify_mark *old)
 {
        assert_spin_locked(&old->lock);
 
        }
 }
 
+void fsnotify_clear_vfsmount_marks_by_group(struct fsnotify_group *group)
+{
+       fsnotify_clear_marks_by_group_flags(group, FSNOTIFY_MARK_FLAG_VFSMOUNT);
+}
+
 /*
  * Recalculate the mask of events relevant to a given vfsmount locked.
  */
 
 #define FAN_MARK_MOUNT         0x00000010
 #define FAN_MARK_IGNORED_MASK  0x00000020
 #define FAN_MARK_IGNORED_SURV_MODIFY   0x00000040
+#define FAN_MARK_FLUSH         0x00000080
 
 #define FAN_ALL_MARK_FLAGS     (FAN_MARK_ADD |\
                                 FAN_MARK_REMOVE |\
 
                             struct inode *inode, struct vfsmount *mnt, int allow_dups);
 /* given a mark, flag it to be freed when all references are dropped */
 extern void fsnotify_destroy_mark(struct fsnotify_mark *mark);
+/* run all the marks in a group, and clear all of the vfsmount marks */
+extern void fsnotify_clear_vfsmount_marks_by_group(struct fsnotify_group *group);
+/* run all the marks in a group, and clear all of the inode marks */
+extern void fsnotify_clear_inode_marks_by_group(struct fsnotify_group *group);
+/* run all the marks in a group, and clear all of the marks where mark->flags & flags is true*/
+extern void fsnotify_clear_marks_by_group_flags(struct fsnotify_group *group, unsigned int flags);
 /* run all the marks in a group, and flag them to be freed */
 extern void fsnotify_clear_marks_by_group(struct fsnotify_group *group);
 extern void fsnotify_get_mark(struct fsnotify_mark *mark);