Skip to content

Commit

Permalink
fanotify: report file range info with pre-content events
Browse files Browse the repository at this point in the history
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 <amir73il@gmail.com>
Signed-off-by: Jan Kara <jack@suse.cz>
Link: https://patch.msgid.link/b90a9e6c809dd3cad5684da90f23ea93ec6ce8c8.1731684329.git.josef@toxicpanda.com
  • Loading branch information
Amir Goldstein authored and Jan Kara committed Dec 10, 2024
1 parent 4f8afa3 commit 870499b
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 0 deletions.
8 changes: 8 additions & 0 deletions fs/notify/fanotify/fanotify.h
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,14 @@ static inline bool fanotify_is_perm_event(u32 mask)
mask & FANOTIFY_PERM_EVENTS;
}

static inline bool fanotify_event_has_access_range(struct fanotify_event *event)
{
if (!(event->mask & FANOTIFY_PRE_CONTENT_EVENTS))
return false;

return FANOTIFY_PERM(event)->ppos;
}

static inline struct fanotify_event *FANOTIFY_E(struct fsnotify_event *fse)
{
return container_of(fse, struct fanotify_event, fse);
Expand Down
38 changes: 38 additions & 0 deletions fs/notify/fanotify/fanotify_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ struct kmem_cache *fanotify_perm_event_cachep __ro_after_init;
sizeof(struct fanotify_event_info_pidfd)
#define FANOTIFY_ERROR_INFO_LEN \
(sizeof(struct fanotify_event_info_error))
#define FANOTIFY_RANGE_INFO_LEN \
(sizeof(struct fanotify_event_info_range))

static int fanotify_fid_info_len(int fh_len, int name_len)
{
Expand Down Expand Up @@ -180,6 +182,9 @@ static size_t fanotify_event_len(unsigned int info_mode,
if (info_mode & FAN_REPORT_PIDFD)
event_len += FANOTIFY_PIDFD_INFO_LEN;

if (fanotify_event_has_access_range(event))
event_len += FANOTIFY_RANGE_INFO_LEN;

return event_len;
}

Expand Down Expand Up @@ -516,6 +521,30 @@ static int copy_pidfd_info_to_user(int pidfd,
return info_len;
}

static size_t copy_range_info_to_user(struct fanotify_event *event,
char __user *buf, int count)
{
struct fanotify_perm_event *pevent = FANOTIFY_PERM(event);
struct fanotify_event_info_range info = { };
size_t info_len = FANOTIFY_RANGE_INFO_LEN;

if (WARN_ON_ONCE(info_len > count))
return -EFAULT;

if (WARN_ON_ONCE(!pevent->ppos))
return -EINVAL;

info.hdr.info_type = FAN_EVENT_INFO_TYPE_RANGE;
info.hdr.len = info_len;
info.offset = *(pevent->ppos);
info.count = pevent->count;

if (copy_to_user(buf, &info, info_len))
return -EFAULT;

return info_len;
}

static int copy_info_records_to_user(struct fanotify_event *event,
struct fanotify_info *info,
unsigned int info_mode, int pidfd,
Expand Down Expand Up @@ -637,6 +666,15 @@ static int copy_info_records_to_user(struct fanotify_event *event,
total_bytes += ret;
}

if (fanotify_event_has_access_range(event)) {
ret = copy_range_info_to_user(event, buf, count);
if (ret < 0)
return ret;
buf += ret;
count -= ret;
total_bytes += ret;
}

return total_bytes;
}

Expand Down
8 changes: 8 additions & 0 deletions include/uapi/linux/fanotify.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ struct fanotify_event_metadata {
#define FAN_EVENT_INFO_TYPE_DFID 3
#define FAN_EVENT_INFO_TYPE_PIDFD 4
#define FAN_EVENT_INFO_TYPE_ERROR 5
#define FAN_EVENT_INFO_TYPE_RANGE 6

/* Special info types for FAN_RENAME */
#define FAN_EVENT_INFO_TYPE_OLD_DFID_NAME 10
Expand Down Expand Up @@ -192,6 +193,13 @@ struct fanotify_event_info_error {
__u32 error_count;
};

struct fanotify_event_info_range {
struct fanotify_event_info_header hdr;
__u32 pad;
__u64 offset;
__u64 count;
};

/*
* User space may need to record additional information about its decision.
* The extra information type records what kind of information is included.
Expand Down

0 comments on commit 870499b

Please sign in to comment.