Skip to content

Commit 870499b

Browse files
amir73iljankara
authored andcommitted
fanotify: report file range info with pre-content events
With group class FAN_CLASS_PRE_CONTENT, report offset and length info along with FAN_PRE_ACCESS pre-content events. This information is meant to be used by hierarchical storage managers that want to fill partial content of files on first access to range. Signed-off-by: Amir Goldstein <[email protected]> Signed-off-by: Jan Kara <[email protected]> Link: https://patch.msgid.link/b90a9e6c809dd3cad5684da90f23ea93ec6ce8c8.1731684329.git.josef@toxicpanda.com
1 parent 4f8afa3 commit 870499b

File tree

3 files changed

+54
-0
lines changed

3 files changed

+54
-0
lines changed

fs/notify/fanotify/fanotify.h

+8
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,14 @@ static inline bool fanotify_is_perm_event(u32 mask)
448448
mask & FANOTIFY_PERM_EVENTS;
449449
}
450450

451+
static inline bool fanotify_event_has_access_range(struct fanotify_event *event)
452+
{
453+
if (!(event->mask & FANOTIFY_PRE_CONTENT_EVENTS))
454+
return false;
455+
456+
return FANOTIFY_PERM(event)->ppos;
457+
}
458+
451459
static inline struct fanotify_event *FANOTIFY_E(struct fsnotify_event *fse)
452460
{
453461
return container_of(fse, struct fanotify_event, fse);

fs/notify/fanotify/fanotify_user.c

+38
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ struct kmem_cache *fanotify_perm_event_cachep __ro_after_init;
121121
sizeof(struct fanotify_event_info_pidfd)
122122
#define FANOTIFY_ERROR_INFO_LEN \
123123
(sizeof(struct fanotify_event_info_error))
124+
#define FANOTIFY_RANGE_INFO_LEN \
125+
(sizeof(struct fanotify_event_info_range))
124126

125127
static int fanotify_fid_info_len(int fh_len, int name_len)
126128
{
@@ -180,6 +182,9 @@ static size_t fanotify_event_len(unsigned int info_mode,
180182
if (info_mode & FAN_REPORT_PIDFD)
181183
event_len += FANOTIFY_PIDFD_INFO_LEN;
182184

185+
if (fanotify_event_has_access_range(event))
186+
event_len += FANOTIFY_RANGE_INFO_LEN;
187+
183188
return event_len;
184189
}
185190

@@ -516,6 +521,30 @@ static int copy_pidfd_info_to_user(int pidfd,
516521
return info_len;
517522
}
518523

524+
static size_t copy_range_info_to_user(struct fanotify_event *event,
525+
char __user *buf, int count)
526+
{
527+
struct fanotify_perm_event *pevent = FANOTIFY_PERM(event);
528+
struct fanotify_event_info_range info = { };
529+
size_t info_len = FANOTIFY_RANGE_INFO_LEN;
530+
531+
if (WARN_ON_ONCE(info_len > count))
532+
return -EFAULT;
533+
534+
if (WARN_ON_ONCE(!pevent->ppos))
535+
return -EINVAL;
536+
537+
info.hdr.info_type = FAN_EVENT_INFO_TYPE_RANGE;
538+
info.hdr.len = info_len;
539+
info.offset = *(pevent->ppos);
540+
info.count = pevent->count;
541+
542+
if (copy_to_user(buf, &info, info_len))
543+
return -EFAULT;
544+
545+
return info_len;
546+
}
547+
519548
static int copy_info_records_to_user(struct fanotify_event *event,
520549
struct fanotify_info *info,
521550
unsigned int info_mode, int pidfd,
@@ -637,6 +666,15 @@ static int copy_info_records_to_user(struct fanotify_event *event,
637666
total_bytes += ret;
638667
}
639668

669+
if (fanotify_event_has_access_range(event)) {
670+
ret = copy_range_info_to_user(event, buf, count);
671+
if (ret < 0)
672+
return ret;
673+
buf += ret;
674+
count -= ret;
675+
total_bytes += ret;
676+
}
677+
640678
return total_bytes;
641679
}
642680

include/uapi/linux/fanotify.h

+8
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ struct fanotify_event_metadata {
146146
#define FAN_EVENT_INFO_TYPE_DFID 3
147147
#define FAN_EVENT_INFO_TYPE_PIDFD 4
148148
#define FAN_EVENT_INFO_TYPE_ERROR 5
149+
#define FAN_EVENT_INFO_TYPE_RANGE 6
149150

150151
/* Special info types for FAN_RENAME */
151152
#define FAN_EVENT_INFO_TYPE_OLD_DFID_NAME 10
@@ -192,6 +193,13 @@ struct fanotify_event_info_error {
192193
__u32 error_count;
193194
};
194195

196+
struct fanotify_event_info_range {
197+
struct fanotify_event_info_header hdr;
198+
__u32 pad;
199+
__u64 offset;
200+
__u64 count;
201+
};
202+
195203
/*
196204
* User space may need to record additional information about its decision.
197205
* The extra information type records what kind of information is included.

0 commit comments

Comments
 (0)