Skip to content

Commit 3cf984e

Browse files
amir73iljankara
authored andcommitted
fanotify: support secondary dir fh and name in fanotify_info
Allow storing a secondary dir fh and name tupple in fanotify_info. This will be used to store the new parent and name information in FAN_RENAME event. Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Amir Goldstein <[email protected]> Signed-off-by: Jan Kara <[email protected]>
1 parent 1a9515a commit 3cf984e

File tree

3 files changed

+88
-14
lines changed

3 files changed

+88
-14
lines changed

fs/notify/fanotify/fanotify.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,23 +76,35 @@ static bool fanotify_info_equal(struct fanotify_info *info1,
7676
struct fanotify_info *info2)
7777
{
7878
if (info1->dir_fh_totlen != info2->dir_fh_totlen ||
79+
info1->dir2_fh_totlen != info2->dir2_fh_totlen ||
7980
info1->file_fh_totlen != info2->file_fh_totlen ||
80-
info1->name_len != info2->name_len)
81+
info1->name_len != info2->name_len ||
82+
info1->name2_len != info2->name2_len)
8183
return false;
8284

8385
if (info1->dir_fh_totlen &&
8486
!fanotify_fh_equal(fanotify_info_dir_fh(info1),
8587
fanotify_info_dir_fh(info2)))
8688
return false;
8789

90+
if (info1->dir2_fh_totlen &&
91+
!fanotify_fh_equal(fanotify_info_dir2_fh(info1),
92+
fanotify_info_dir2_fh(info2)))
93+
return false;
94+
8895
if (info1->file_fh_totlen &&
8996
!fanotify_fh_equal(fanotify_info_file_fh(info1),
9097
fanotify_info_file_fh(info2)))
9198
return false;
9299

93-
return !info1->name_len ||
94-
!memcmp(fanotify_info_name(info1), fanotify_info_name(info2),
95-
info1->name_len);
100+
if (info1->name_len &&
101+
memcmp(fanotify_info_name(info1), fanotify_info_name(info2),
102+
info1->name_len))
103+
return false;
104+
105+
return !info1->name2_len ||
106+
!memcmp(fanotify_info_name2(info1), fanotify_info_name2(info2),
107+
info1->name2_len);
96108
}
97109

98110
static bool fanotify_name_event_equal(struct fanotify_name_event *fne1,

fs/notify/fanotify/fanotify.h

Lines changed: 71 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,31 +40,45 @@ struct fanotify_fh {
4040
struct fanotify_info {
4141
/* size of dir_fh/file_fh including fanotify_fh hdr size */
4242
u8 dir_fh_totlen;
43+
u8 dir2_fh_totlen;
4344
u8 file_fh_totlen;
4445
u8 name_len;
45-
u8 pad;
46+
u8 name2_len;
47+
u8 pad[3];
4648
unsigned char buf[];
4749
/*
4850
* (struct fanotify_fh) dir_fh starts at buf[0]
49-
* (optional) file_fh starts at buf[dir_fh_totlen]
50-
* name starts at buf[dir_fh_totlen + file_fh_totlen]
51+
* (optional) dir2_fh starts at buf[dir_fh_totlen]
52+
* (optional) file_fh starts at buf[dir_fh_totlen + dir2_fh_totlen]
53+
* name starts at buf[dir_fh_totlen + dir2_fh_totlen + file_fh_totlen]
54+
* ...
5155
*/
5256
#define FANOTIFY_DIR_FH_SIZE(info) ((info)->dir_fh_totlen)
57+
#define FANOTIFY_DIR2_FH_SIZE(info) ((info)->dir2_fh_totlen)
5358
#define FANOTIFY_FILE_FH_SIZE(info) ((info)->file_fh_totlen)
5459
#define FANOTIFY_NAME_SIZE(info) ((info)->name_len + 1)
60+
#define FANOTIFY_NAME2_SIZE(info) ((info)->name2_len + 1)
5561

5662
#define FANOTIFY_DIR_FH_OFFSET(info) 0
57-
#define FANOTIFY_FILE_FH_OFFSET(info) \
63+
#define FANOTIFY_DIR2_FH_OFFSET(info) \
5864
(FANOTIFY_DIR_FH_OFFSET(info) + FANOTIFY_DIR_FH_SIZE(info))
65+
#define FANOTIFY_FILE_FH_OFFSET(info) \
66+
(FANOTIFY_DIR2_FH_OFFSET(info) + FANOTIFY_DIR2_FH_SIZE(info))
5967
#define FANOTIFY_NAME_OFFSET(info) \
6068
(FANOTIFY_FILE_FH_OFFSET(info) + FANOTIFY_FILE_FH_SIZE(info))
69+
#define FANOTIFY_NAME2_OFFSET(info) \
70+
(FANOTIFY_NAME_OFFSET(info) + FANOTIFY_NAME_SIZE(info))
6171

6272
#define FANOTIFY_DIR_FH_BUF(info) \
6373
((info)->buf + FANOTIFY_DIR_FH_OFFSET(info))
74+
#define FANOTIFY_DIR2_FH_BUF(info) \
75+
((info)->buf + FANOTIFY_DIR2_FH_OFFSET(info))
6476
#define FANOTIFY_FILE_FH_BUF(info) \
6577
((info)->buf + FANOTIFY_FILE_FH_OFFSET(info))
6678
#define FANOTIFY_NAME_BUF(info) \
6779
((info)->buf + FANOTIFY_NAME_OFFSET(info))
80+
#define FANOTIFY_NAME2_BUF(info) \
81+
((info)->buf + FANOTIFY_NAME2_OFFSET(info))
6882
} __aligned(4);
6983

7084
static inline bool fanotify_fh_has_ext_buf(struct fanotify_fh *fh)
@@ -106,6 +120,20 @@ static inline struct fanotify_fh *fanotify_info_dir_fh(struct fanotify_info *inf
106120
return (struct fanotify_fh *)FANOTIFY_DIR_FH_BUF(info);
107121
}
108122

123+
static inline int fanotify_info_dir2_fh_len(struct fanotify_info *info)
124+
{
125+
if (!info->dir2_fh_totlen ||
126+
WARN_ON_ONCE(info->dir2_fh_totlen < FANOTIFY_FH_HDR_LEN))
127+
return 0;
128+
129+
return info->dir2_fh_totlen - FANOTIFY_FH_HDR_LEN;
130+
}
131+
132+
static inline struct fanotify_fh *fanotify_info_dir2_fh(struct fanotify_info *info)
133+
{
134+
return (struct fanotify_fh *)FANOTIFY_DIR2_FH_BUF(info);
135+
}
136+
109137
static inline int fanotify_info_file_fh_len(struct fanotify_info *info)
110138
{
111139
if (!info->file_fh_totlen ||
@@ -128,31 +156,55 @@ static inline char *fanotify_info_name(struct fanotify_info *info)
128156
return FANOTIFY_NAME_BUF(info);
129157
}
130158

159+
static inline char *fanotify_info_name2(struct fanotify_info *info)
160+
{
161+
if (!info->name2_len)
162+
return NULL;
163+
164+
return FANOTIFY_NAME2_BUF(info);
165+
}
166+
131167
static inline void fanotify_info_init(struct fanotify_info *info)
132168
{
133169
BUILD_BUG_ON(FANOTIFY_FH_HDR_LEN + MAX_HANDLE_SZ > U8_MAX);
134170
BUILD_BUG_ON(NAME_MAX > U8_MAX);
135171

136172
info->dir_fh_totlen = 0;
173+
info->dir2_fh_totlen = 0;
137174
info->file_fh_totlen = 0;
138175
info->name_len = 0;
176+
info->name2_len = 0;
139177
}
140178

141179
/* These set/copy helpers MUST be called by order */
142180
static inline void fanotify_info_set_dir_fh(struct fanotify_info *info,
143181
unsigned int totlen)
144182
{
145-
if (WARN_ON_ONCE(info->file_fh_totlen > 0) ||
146-
WARN_ON_ONCE(info->name_len > 0))
183+
if (WARN_ON_ONCE(info->dir2_fh_totlen > 0) ||
184+
WARN_ON_ONCE(info->file_fh_totlen > 0) ||
185+
WARN_ON_ONCE(info->name_len > 0) ||
186+
WARN_ON_ONCE(info->name2_len > 0))
147187
return;
148188

149189
info->dir_fh_totlen = totlen;
150190
}
151191

192+
static inline void fanotify_info_set_dir2_fh(struct fanotify_info *info,
193+
unsigned int totlen)
194+
{
195+
if (WARN_ON_ONCE(info->file_fh_totlen > 0) ||
196+
WARN_ON_ONCE(info->name_len > 0) ||
197+
WARN_ON_ONCE(info->name2_len > 0))
198+
return;
199+
200+
info->dir2_fh_totlen = totlen;
201+
}
202+
152203
static inline void fanotify_info_set_file_fh(struct fanotify_info *info,
153204
unsigned int totlen)
154205
{
155-
if (WARN_ON_ONCE(info->name_len > 0))
206+
if (WARN_ON_ONCE(info->name_len > 0) ||
207+
WARN_ON_ONCE(info->name2_len > 0))
156208
return;
157209

158210
info->file_fh_totlen = totlen;
@@ -161,13 +213,24 @@ static inline void fanotify_info_set_file_fh(struct fanotify_info *info,
161213
static inline void fanotify_info_copy_name(struct fanotify_info *info,
162214
const struct qstr *name)
163215
{
164-
if (WARN_ON_ONCE(name->len > NAME_MAX))
216+
if (WARN_ON_ONCE(name->len > NAME_MAX) ||
217+
WARN_ON_ONCE(info->name2_len > 0))
165218
return;
166219

167220
info->name_len = name->len;
168221
strcpy(fanotify_info_name(info), name->name);
169222
}
170223

224+
static inline void fanotify_info_copy_name2(struct fanotify_info *info,
225+
const struct qstr *name)
226+
{
227+
if (WARN_ON_ONCE(name->len > NAME_MAX))
228+
return;
229+
230+
info->name2_len = name->len;
231+
strcpy(fanotify_info_name2(info), name->name);
232+
}
233+
171234
/*
172235
* Common structure for fanotify events. Concrete structs are allocated in
173236
* fanotify_handle_event() and freed when the information is retrieved by

fs/notify/fanotify/fanotify_user.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -332,11 +332,10 @@ static int process_access_response(struct fsnotify_group *group,
332332
static size_t copy_error_info_to_user(struct fanotify_event *event,
333333
char __user *buf, int count)
334334
{
335-
struct fanotify_event_info_error info;
335+
struct fanotify_event_info_error info = { };
336336
struct fanotify_error_event *fee = FANOTIFY_EE(event);
337337

338338
info.hdr.info_type = FAN_EVENT_INFO_TYPE_ERROR;
339-
info.hdr.pad = 0;
340339
info.hdr.len = FANOTIFY_ERROR_INFO_LEN;
341340

342341
if (WARN_ON(count < info.hdr.len))

0 commit comments

Comments
 (0)