-----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEq1nRK9aeMoq1VSgcnJ2qBz9kQNkFAmI7PPUACgkQnJ2qBz9k QNm1ygf/WcyxdM4+FTrhVVFGKPriqM8Ftx2r88/sod8CPUZrmCtLbCtO4rVBAEip c1eVRFEcZV+A/pt/UVvIklb+/Vlc1RmP1pEBzOcDaDvOMcnBoV43rTHxwxrX1YdX Ykr6C37d+51FQu/cuVC/LHx2+MhIkAe2ebHbBZNVpk+s98iY9xjo+0cRaDbzgkXq NqySxDghZnRO4wvYbYYrStJ/XLJePjrBU1n18T0m7wpJ5UuyAnXlVwTZgkVhdNLy EnBUIRvhXxr3WzfH6I6G7fOHTSbYuho9CSK3K49TdiqAtoxrlWgX2LWE5WRzhHWd nlTu64JWeSMTIFCxxinxSs7F9nUiDg== =6VY+ -----END PGP SIGNATURE----- Merge tag 'fsnotify_for_v5.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs Pull fsnotify updates from Jan Kara: "A few fsnotify improvements and cleanups" * tag 'fsnotify_for_v5.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs: fsnotify: remove redundant parameter judgment fsnotify: optimize FS_MODIFY events with no ignored masks fsnotify: fix merge with parent's ignored mask
This commit is contained in:
Коммит
a8988507e5
|
@ -1003,17 +1003,18 @@ static __u32 fanotify_mark_remove_from_mask(struct fsnotify_mark *fsn_mark,
|
|||
__u32 mask, unsigned int flags,
|
||||
__u32 umask, int *destroy)
|
||||
{
|
||||
__u32 oldmask = 0;
|
||||
__u32 oldmask, newmask;
|
||||
|
||||
/* umask bits cannot be removed by user */
|
||||
mask &= ~umask;
|
||||
spin_lock(&fsn_mark->lock);
|
||||
oldmask = fsnotify_calc_mask(fsn_mark);
|
||||
if (!(flags & FAN_MARK_IGNORED_MASK)) {
|
||||
oldmask = fsn_mark->mask;
|
||||
fsn_mark->mask &= ~mask;
|
||||
} else {
|
||||
fsn_mark->ignored_mask &= ~mask;
|
||||
}
|
||||
newmask = fsnotify_calc_mask(fsn_mark);
|
||||
/*
|
||||
* We need to keep the mark around even if remaining mask cannot
|
||||
* result in any events (e.g. mask == FAN_ONDIR) to support incremenal
|
||||
|
@ -1023,7 +1024,7 @@ static __u32 fanotify_mark_remove_from_mask(struct fsnotify_mark *fsn_mark,
|
|||
*destroy = !((fsn_mark->mask | fsn_mark->ignored_mask) & ~umask);
|
||||
spin_unlock(&fsn_mark->lock);
|
||||
|
||||
return mask & oldmask;
|
||||
return oldmask & ~newmask;
|
||||
}
|
||||
|
||||
static int fanotify_remove_mark(struct fsnotify_group *group,
|
||||
|
@ -1080,24 +1081,42 @@ static int fanotify_remove_inode_mark(struct fsnotify_group *group,
|
|||
flags, umask);
|
||||
}
|
||||
|
||||
static __u32 fanotify_mark_add_to_mask(struct fsnotify_mark *fsn_mark,
|
||||
__u32 mask,
|
||||
unsigned int flags)
|
||||
static void fanotify_mark_add_ignored_mask(struct fsnotify_mark *fsn_mark,
|
||||
__u32 mask, unsigned int flags,
|
||||
__u32 *removed)
|
||||
{
|
||||
__u32 oldmask = -1;
|
||||
fsn_mark->ignored_mask |= mask;
|
||||
|
||||
/*
|
||||
* Setting FAN_MARK_IGNORED_SURV_MODIFY for the first time may lead to
|
||||
* the removal of the FS_MODIFY bit in calculated mask if it was set
|
||||
* because of an ignored mask that is now going to survive FS_MODIFY.
|
||||
*/
|
||||
if ((flags & FAN_MARK_IGNORED_SURV_MODIFY) &&
|
||||
!(fsn_mark->flags & FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY)) {
|
||||
fsn_mark->flags |= FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY;
|
||||
if (!(fsn_mark->mask & FS_MODIFY))
|
||||
*removed = FS_MODIFY;
|
||||
}
|
||||
}
|
||||
|
||||
static __u32 fanotify_mark_add_to_mask(struct fsnotify_mark *fsn_mark,
|
||||
__u32 mask, unsigned int flags,
|
||||
__u32 *removed)
|
||||
{
|
||||
__u32 oldmask, newmask;
|
||||
|
||||
spin_lock(&fsn_mark->lock);
|
||||
oldmask = fsnotify_calc_mask(fsn_mark);
|
||||
if (!(flags & FAN_MARK_IGNORED_MASK)) {
|
||||
oldmask = fsn_mark->mask;
|
||||
fsn_mark->mask |= mask;
|
||||
} else {
|
||||
fsn_mark->ignored_mask |= mask;
|
||||
if (flags & FAN_MARK_IGNORED_SURV_MODIFY)
|
||||
fsn_mark->flags |= FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY;
|
||||
fanotify_mark_add_ignored_mask(fsn_mark, mask, flags, removed);
|
||||
}
|
||||
newmask = fsnotify_calc_mask(fsn_mark);
|
||||
spin_unlock(&fsn_mark->lock);
|
||||
|
||||
return mask & ~oldmask;
|
||||
return newmask & ~oldmask;
|
||||
}
|
||||
|
||||
static struct fsnotify_mark *fanotify_add_new_mark(struct fsnotify_group *group,
|
||||
|
@ -1155,7 +1174,7 @@ static int fanotify_add_mark(struct fsnotify_group *group,
|
|||
__kernel_fsid_t *fsid)
|
||||
{
|
||||
struct fsnotify_mark *fsn_mark;
|
||||
__u32 added;
|
||||
__u32 added, removed = 0;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&group->mark_mutex);
|
||||
|
@ -1178,8 +1197,8 @@ static int fanotify_add_mark(struct fsnotify_group *group,
|
|||
goto out;
|
||||
}
|
||||
|
||||
added = fanotify_mark_add_to_mask(fsn_mark, mask, flags);
|
||||
if (added & ~fsnotify_conn_mask(fsn_mark->connector))
|
||||
added = fanotify_mark_add_to_mask(fsn_mark, mask, flags, &removed);
|
||||
if (removed || (added & ~fsnotify_conn_mask(fsn_mark->connector)))
|
||||
fsnotify_recalc_mask(fsn_mark->connector);
|
||||
|
||||
out:
|
||||
|
|
|
@ -70,8 +70,7 @@ static void fsnotify_unmount_inodes(struct super_block *sb)
|
|||
spin_unlock(&inode->i_lock);
|
||||
spin_unlock(&sb->s_inode_list_lock);
|
||||
|
||||
if (iput_inode)
|
||||
iput(iput_inode);
|
||||
iput(iput_inode);
|
||||
|
||||
/* for each watch, send FS_UNMOUNT and then remove it */
|
||||
fsnotify_inode(inode, FS_UNMOUNT);
|
||||
|
@ -85,8 +84,7 @@ static void fsnotify_unmount_inodes(struct super_block *sb)
|
|||
}
|
||||
spin_unlock(&sb->s_inode_list_lock);
|
||||
|
||||
if (iput_inode)
|
||||
iput(iput_inode);
|
||||
iput(iput_inode);
|
||||
}
|
||||
|
||||
void fsnotify_sb_delete(struct super_block *sb)
|
||||
|
@ -531,11 +529,13 @@ int fsnotify(__u32 mask, const void *data, int data_type, struct inode *dir,
|
|||
|
||||
|
||||
/*
|
||||
* if this is a modify event we may need to clear the ignored masks
|
||||
* otherwise return if none of the marks care about this type of event.
|
||||
* If this is a modify event we may need to clear some ignored masks.
|
||||
* In that case, the object with ignored masks will have the FS_MODIFY
|
||||
* event in its mask.
|
||||
* Otherwise, return if none of the marks care about this type of event.
|
||||
*/
|
||||
test_mask = (mask & ALL_FSNOTIFY_EVENTS);
|
||||
if (!(mask & FS_MODIFY) && !(test_mask & marks_mask))
|
||||
if (!(test_mask & marks_mask))
|
||||
return 0;
|
||||
|
||||
iter_info.srcu_idx = srcu_read_lock(&fsnotify_mark_srcu);
|
||||
|
|
|
@ -127,7 +127,7 @@ static void __fsnotify_recalc_mask(struct fsnotify_mark_connector *conn)
|
|||
return;
|
||||
hlist_for_each_entry(mark, &conn->list, obj_list) {
|
||||
if (mark->flags & FSNOTIFY_MARK_FLAG_ATTACHED)
|
||||
new_mask |= mark->mask;
|
||||
new_mask |= fsnotify_calc_mask(mark);
|
||||
}
|
||||
*fsnotify_conn_mask_p(conn) = new_mask;
|
||||
}
|
||||
|
@ -692,7 +692,7 @@ int fsnotify_add_mark_locked(struct fsnotify_mark *mark,
|
|||
if (ret)
|
||||
goto err;
|
||||
|
||||
if (mark->mask)
|
||||
if (mark->mask || mark->ignored_mask)
|
||||
fsnotify_recalc_mask(mark->connector);
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -601,6 +601,25 @@ extern void fsnotify_remove_queued_event(struct fsnotify_group *group,
|
|||
|
||||
/* functions used to manipulate the marks attached to inodes */
|
||||
|
||||
/* Get mask for calculating object interest taking ignored mask into account */
|
||||
static inline __u32 fsnotify_calc_mask(struct fsnotify_mark *mark)
|
||||
{
|
||||
__u32 mask = mark->mask;
|
||||
|
||||
if (!mark->ignored_mask)
|
||||
return mask;
|
||||
|
||||
/* Interest in FS_MODIFY may be needed for clearing ignored mask */
|
||||
if (!(mark->flags & FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY))
|
||||
mask |= FS_MODIFY;
|
||||
|
||||
/*
|
||||
* If mark is interested in ignoring events on children, the object must
|
||||
* show interest in those events for fsnotify_parent() to notice it.
|
||||
*/
|
||||
return mask | (mark->ignored_mask & ALL_FSNOTIFY_EVENTS);
|
||||
}
|
||||
|
||||
/* Get mask of events for a list of marks */
|
||||
extern __u32 fsnotify_conn_mask(struct fsnotify_mark_connector *conn);
|
||||
/* Calculate mask of events for a list of marks */
|
||||
|
|
Загрузка…
Ссылка в новой задаче