mirror of
https://github.com/torvalds/linux.git
synced 2024-11-15 00:21:59 +00:00
\n
-----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEq1nRK9aeMoq1VSgcnJ2qBz9kQNkFAmXx5UkACgkQnJ2qBz9k QNmq5gf+Nm5PB2EQKt3xDqfdK8huTyTPH418tHHMcUjVeWIeFviFMXb2FeuJArr4 TWYjrRzs8aC75SYpPk1LZ6+6OymqYqV+0fxI91BkNnvNpwCInG6h8x6AlG28RLi+ /vmat7qHTPhJ+iTWGU4W3aDXINdXUq1KcN7+8aNDeKy80eI+UhJaWePNe+IFsovX hSDzl6P8FbGqX8s/v52FsUJCXqHHcJYkiyQyUninY0yA/WNPVnzyK+RngP5p216d /Kdh11jbduu+xRObn+CTgsASRANqazQi7rddSVTFefUie2s7vUD7wcyzEHTPY5QS BEQypvCmOFNPFKmMy+e8iLXtYRgTeg== =kQX5 -----END PGP SIGNATURE----- Merge tag 'fsnotify_for_v6.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs Pull fsnotify updates from Jan Kara: - fsnotify optimizations to reduce cost of fsnotify when nobody is watching - fix longstanding wart that system could not be suspended when some process was waiting for response to fanotify permission event - some spelling fixes * tag 'fsnotify_for_v6.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs: fanotify: allow freeze when waiting response for permission events fanotify: Fix misspelling of "writable" fsnotify: Fix misspelling of "writable" inotify: Fix misspelling of "writable" fsnotify: Add fsnotify_sb_has_watchers() helper fsnotify: optimize the case of no parent watcher
This commit is contained in:
commit
1715f710e7
@ -228,8 +228,10 @@ static int fanotify_get_response(struct fsnotify_group *group,
|
||||
|
||||
pr_debug("%s: group=%p event=%p\n", __func__, group, event);
|
||||
|
||||
ret = wait_event_killable(group->fanotify_data.access_waitq,
|
||||
event->state == FAN_EVENT_ANSWERED);
|
||||
ret = wait_event_state(group->fanotify_data.access_waitq,
|
||||
event->state == FAN_EVENT_ANSWERED,
|
||||
(TASK_KILLABLE|TASK_FREEZABLE));
|
||||
|
||||
/* Signal pending? */
|
||||
if (ret < 0) {
|
||||
spin_lock(&group->notification_lock);
|
||||
|
@ -141,7 +141,7 @@ void __fsnotify_update_child_dentry_flags(struct inode *inode)
|
||||
}
|
||||
|
||||
/* Are inode/sb/mount interested in parent and name info with this event? */
|
||||
static bool fsnotify_event_needs_parent(struct inode *inode, struct mount *mnt,
|
||||
static bool fsnotify_event_needs_parent(struct inode *inode, __u32 mnt_mask,
|
||||
__u32 mask)
|
||||
{
|
||||
__u32 marks_mask = 0;
|
||||
@ -160,13 +160,22 @@ static bool fsnotify_event_needs_parent(struct inode *inode, struct mount *mnt,
|
||||
/* Did either inode/sb/mount subscribe for events with parent/name? */
|
||||
marks_mask |= fsnotify_parent_needed_mask(inode->i_fsnotify_mask);
|
||||
marks_mask |= fsnotify_parent_needed_mask(inode->i_sb->s_fsnotify_mask);
|
||||
if (mnt)
|
||||
marks_mask |= fsnotify_parent_needed_mask(mnt->mnt_fsnotify_mask);
|
||||
marks_mask |= fsnotify_parent_needed_mask(mnt_mask);
|
||||
|
||||
/* Did they subscribe for this event with parent/name info? */
|
||||
return mask & marks_mask;
|
||||
}
|
||||
|
||||
/* Are there any inode/mount/sb objects that are interested in this event? */
|
||||
static inline bool fsnotify_object_watched(struct inode *inode, __u32 mnt_mask,
|
||||
__u32 mask)
|
||||
{
|
||||
__u32 marks_mask = inode->i_fsnotify_mask | mnt_mask |
|
||||
inode->i_sb->s_fsnotify_mask;
|
||||
|
||||
return mask & marks_mask & ALL_FSNOTIFY_EVENTS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Notify this dentry's parent about a child's events with child name info
|
||||
* if parent is watching or if inode/sb/mount are interested in events with
|
||||
@ -179,7 +188,7 @@ int __fsnotify_parent(struct dentry *dentry, __u32 mask, const void *data,
|
||||
int data_type)
|
||||
{
|
||||
const struct path *path = fsnotify_data_path(data, data_type);
|
||||
struct mount *mnt = path ? real_mount(path->mnt) : NULL;
|
||||
__u32 mnt_mask = path ? real_mount(path->mnt)->mnt_fsnotify_mask : 0;
|
||||
struct inode *inode = d_inode(dentry);
|
||||
struct dentry *parent;
|
||||
bool parent_watched = dentry->d_flags & DCACHE_FSNOTIFY_PARENT_WATCHED;
|
||||
@ -190,16 +199,13 @@ int __fsnotify_parent(struct dentry *dentry, __u32 mask, const void *data,
|
||||
struct qstr *file_name = NULL;
|
||||
int ret = 0;
|
||||
|
||||
/*
|
||||
* Do inode/sb/mount care about parent and name info on non-dir?
|
||||
* Do they care about any event at all?
|
||||
*/
|
||||
if (!inode->i_fsnotify_marks && !inode->i_sb->s_fsnotify_marks &&
|
||||
(!mnt || !mnt->mnt_fsnotify_marks) && !parent_watched)
|
||||
/* Optimize the likely case of nobody watching this path */
|
||||
if (likely(!parent_watched &&
|
||||
!fsnotify_object_watched(inode, mnt_mask, mask)))
|
||||
return 0;
|
||||
|
||||
parent = NULL;
|
||||
parent_needed = fsnotify_event_needs_parent(inode, mnt, mask);
|
||||
parent_needed = fsnotify_event_needs_parent(inode, mnt_mask, mask);
|
||||
if (!parent_watched && !parent_needed)
|
||||
goto notify;
|
||||
|
||||
|
@ -17,6 +17,12 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/bug.h>
|
||||
|
||||
/* Are there any inode/mount/sb objects that are being watched at all? */
|
||||
static inline bool fsnotify_sb_has_watchers(struct super_block *sb)
|
||||
{
|
||||
return atomic_long_read(&sb->s_fsnotify_connectors);
|
||||
}
|
||||
|
||||
/*
|
||||
* Notify this @dir inode about a change in a child directory entry.
|
||||
* The directory entry may have turned positive or negative or its inode may
|
||||
@ -30,7 +36,7 @@ static inline int fsnotify_name(__u32 mask, const void *data, int data_type,
|
||||
struct inode *dir, const struct qstr *name,
|
||||
u32 cookie)
|
||||
{
|
||||
if (atomic_long_read(&dir->i_sb->s_fsnotify_connectors) == 0)
|
||||
if (!fsnotify_sb_has_watchers(dir->i_sb))
|
||||
return 0;
|
||||
|
||||
return fsnotify(mask, data, data_type, dir, name, NULL, cookie);
|
||||
@ -44,7 +50,7 @@ static inline void fsnotify_dirent(struct inode *dir, struct dentry *dentry,
|
||||
|
||||
static inline void fsnotify_inode(struct inode *inode, __u32 mask)
|
||||
{
|
||||
if (atomic_long_read(&inode->i_sb->s_fsnotify_connectors) == 0)
|
||||
if (!fsnotify_sb_has_watchers(inode->i_sb))
|
||||
return;
|
||||
|
||||
if (S_ISDIR(inode->i_mode))
|
||||
@ -59,7 +65,7 @@ static inline int fsnotify_parent(struct dentry *dentry, __u32 mask,
|
||||
{
|
||||
struct inode *inode = d_inode(dentry);
|
||||
|
||||
if (atomic_long_read(&inode->i_sb->s_fsnotify_connectors) == 0)
|
||||
if (!fsnotify_sb_has_watchers(inode->i_sb))
|
||||
return 0;
|
||||
|
||||
if (S_ISDIR(inode->i_mode)) {
|
||||
|
@ -31,8 +31,8 @@
|
||||
#define FS_ACCESS 0x00000001 /* File was accessed */
|
||||
#define FS_MODIFY 0x00000002 /* File was modified */
|
||||
#define FS_ATTRIB 0x00000004 /* Metadata changed */
|
||||
#define FS_CLOSE_WRITE 0x00000008 /* Writtable file was closed */
|
||||
#define FS_CLOSE_NOWRITE 0x00000010 /* Unwrittable file closed */
|
||||
#define FS_CLOSE_WRITE 0x00000008 /* Writable file was closed */
|
||||
#define FS_CLOSE_NOWRITE 0x00000010 /* Unwritable file closed */
|
||||
#define FS_OPEN 0x00000020 /* File was opened */
|
||||
#define FS_MOVED_FROM 0x00000040 /* File was moved from X */
|
||||
#define FS_MOVED_TO 0x00000080 /* File was moved to Y */
|
||||
|
@ -8,8 +8,8 @@
|
||||
#define FAN_ACCESS 0x00000001 /* File was accessed */
|
||||
#define FAN_MODIFY 0x00000002 /* File was modified */
|
||||
#define FAN_ATTRIB 0x00000004 /* Metadata changed */
|
||||
#define FAN_CLOSE_WRITE 0x00000008 /* Writtable file closed */
|
||||
#define FAN_CLOSE_NOWRITE 0x00000010 /* Unwrittable file closed */
|
||||
#define FAN_CLOSE_WRITE 0x00000008 /* Writable file closed */
|
||||
#define FAN_CLOSE_NOWRITE 0x00000010 /* Unwritable file closed */
|
||||
#define FAN_OPEN 0x00000020 /* File was opened */
|
||||
#define FAN_MOVED_FROM 0x00000040 /* File was moved from X */
|
||||
#define FAN_MOVED_TO 0x00000080 /* File was moved to Y */
|
||||
|
@ -30,8 +30,8 @@ struct inotify_event {
|
||||
#define IN_ACCESS 0x00000001 /* File was accessed */
|
||||
#define IN_MODIFY 0x00000002 /* File was modified */
|
||||
#define IN_ATTRIB 0x00000004 /* Metadata changed */
|
||||
#define IN_CLOSE_WRITE 0x00000008 /* Writtable file was closed */
|
||||
#define IN_CLOSE_NOWRITE 0x00000010 /* Unwrittable file closed */
|
||||
#define IN_CLOSE_WRITE 0x00000008 /* Writable file was closed */
|
||||
#define IN_CLOSE_NOWRITE 0x00000010 /* Unwritable file closed */
|
||||
#define IN_OPEN 0x00000020 /* File was opened */
|
||||
#define IN_MOVED_FROM 0x00000040 /* File was moved from X */
|
||||
#define IN_MOVED_TO 0x00000080 /* File was moved to Y */
|
||||
|
Loading…
Reference in New Issue
Block a user