Skip to content
This repository was archived by the owner on Jul 8, 2024. It is now read-only.

Commit f306f48

Browse files
committed
add move permission and delete notification events
Previously, deletion operations (rmdir and unlink) sent a permission request event, but no notification event after successful deletion. Rename operations did the opposite, sending only a notification event after a successful move. In order to fully support VFSForGit, and to treat these two forms of filesystem modification similarly, we issue both a permission request beforehand, and if the request is granted and the operation successful, a subsequent informational event notification. We also shift the value of PROJFS_DELETE_PERM left by one bit to leave room in case PROJFS_CREATE_PERM is ever needed in the future.
1 parent 95cb9ca commit f306f48

8 files changed

+102
-72
lines changed

include/projfs_notify.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,11 @@ extern "C" {
3939
#define PROJFS_CLOSE_WRITE 0x00000008 /* Writable file closed */
4040
#define PROJFS_MOVE 0x000000C0 /* File/dir moved (TO+FROM) */
4141
#define PROJFS_CREATE 0x00000100 /* File/dir created */
42+
#define PROJFS_DELETE 0x00000200 /* File/dir deleted */
4243
#define PROJFS_OPEN_PERM 0x00010000 /* File open perm (wr only) */
43-
#define PROJFS_DELETE_PERM himask(0x0001) /* Delete permission */
44+
/* Create perm (future) */
45+
#define PROJFS_DELETE_PERM himask(0x0002) /* Delete permission */
46+
#define PROJFS_MOVE_PERM himask(0x0004) /* Move permission */
4447

4548
/** Filesystem event flags */
4649
#define PROJFS_ONDIR 0x40000000 /* Event occurred on dir */
@@ -78,6 +81,7 @@ extern "C" {
7881
#if (PROJFS_CLOSE_WRITE != IN_CLOSE_WRITE || \
7982
PROJFS_MOVE != IN_MOVE || \
8083
PROJFS_CREATE != IN_CREATE || \
84+
PROJFS_DELETE != IN_DELETE || \
8185
PROJFS_ONDIR != IN_ISDIR)
8286
#error "Projfs notification API out of sync with sys/inotify.h API"
8387
#endif

lib/projfs.c

+19-5
Original file line numberDiff line numberDiff line change
@@ -1090,7 +1090,12 @@ static int projfs_op_unlink(char const *path)
10901090
return -res;
10911091

10921092
res = unlinkat(get_fuse_context_lowerdir_fd(), path, 0);
1093-
return res == -1 ? -errno : 0;
1093+
if (res == -1)
1094+
return -errno;
1095+
1096+
// do not report event handler errors after successful unlink op
1097+
(void)send_notify_event(PROJFS_DELETE, 0, path, NULL);
1098+
return 0;
10941099
}
10951100

10961101
static int projfs_op_mkdir(char const *path, mode_t mode)
@@ -1125,13 +1130,18 @@ static int projfs_op_rmdir(char const *path)
11251130
return -res;
11261131

11271132
res = unlinkat(get_fuse_context_lowerdir_fd(), path, AT_REMOVEDIR);
1128-
return res == -1 ? -errno : 0;
1133+
if (res == -1)
1134+
return -errno;
1135+
1136+
// do not report event handler errors after successful rmdir op
1137+
(void)send_notify_event(PROJFS_DELETE | PROJFS_ONDIR, 0, path, NULL);
1138+
return 0;
11291139
}
11301140

11311141
static int projfs_op_rename(char const *src, char const *dst,
11321142
unsigned int flags)
11331143
{
1134-
uint64_t mask = PROJFS_MOVE;
1144+
uint64_t dir_mask = 0;
11351145
int lowerdir_fd;
11361146
int res;
11371147

@@ -1142,7 +1152,7 @@ static int projfs_op_rename(char const *src, char const *dst,
11421152
// always convert to fully local file before renaming
11431153
res = project_file("rename", src, PROJ_STATE_MODIFIED);
11441154
if (res == EISDIR)
1145-
mask |= PROJFS_ONDIR;
1155+
dir_mask = PROJFS_ONDIR;
11461156
else if (res)
11471157
return -res;
11481158

@@ -1151,6 +1161,10 @@ static int projfs_op_rename(char const *src, char const *dst,
11511161
if (res)
11521162
return -res;
11531163

1164+
res = send_perm_event(PROJFS_MOVE_PERM | dir_mask, src, dst);
1165+
if (res < 0)
1166+
return res;
1167+
11541168
// TODO: for non Linux, use renameat(); fail if flags != 0
11551169
lowerdir_fd = get_fuse_context_lowerdir_fd();
11561170
res = syscall(SYS_renameat2, lowerdir_fd, src, lowerdir_fd, dst,
@@ -1159,7 +1173,7 @@ static int projfs_op_rename(char const *src, char const *dst,
11591173
return -errno;
11601174

11611175
// do not report event handler errors after successful rename op
1162-
(void)send_notify_event(mask, 0, src, dst);
1176+
(void)send_notify_event(PROJFS_MOVE | dir_mask, 0, src, dst);
11631177
return 0;
11641178
}
11651179

t/t200-event-ok.t

+6
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,13 @@ test_expect_success 'test event handler on nested file creation' '
5656
'
5757

5858
projfs_event_printf perm delete_file d1/d2/f2.txt
59+
projfs_event_printf notify delete_file d1/d2/f2.txt
5960
test_expect_success 'test permission granted on nested file deletion' '
6061
projfs_event_exec rm target/d1/d2/f2.txt &&
6162
test_path_is_missing target/d1/d2/f2.txt
6263
'
6364

65+
projfs_event_printf perm rename_file f1.txt f1a.txt
6466
projfs_event_printf notify rename_file f1.txt f1a.txt
6567
test_expect_success 'test event handler on file rename' '
6668
projfs_event_exec mv target/f1.txt target/f1a.txt &&
@@ -75,11 +77,13 @@ test_expect_success 'test event handler on file hard link' '
7577
'
7678

7779
projfs_event_printf perm delete_file f1a.txt
80+
projfs_event_printf notify delete_file f1a.txt
7881
test_expect_success 'test permission granted on top-level file deletion' '
7982
projfs_event_exec rm target/f1a.txt &&
8083
test_path_is_missing target/f1a.txt
8184
'
8285

86+
projfs_event_printf perm rename_dir d1/d2 d1/d2a
8387
projfs_event_printf notify rename_dir d1/d2 d1/d2a
8488
test_expect_success 'test event handler on directory rename' '
8589
projfs_event_exec mv target/d1/d2 target/d1/d2a &&
@@ -88,12 +92,14 @@ test_expect_success 'test event handler on directory rename' '
8892
'
8993

9094
projfs_event_printf perm delete_dir d1/d2a
95+
projfs_event_printf notify delete_dir d1/d2a
9196
test_expect_success 'test permission granted on nested directory deletion' '
9297
projfs_event_exec rmdir target/d1/d2a &&
9398
test_path_is_missing target/d1/d2a
9499
'
95100

96101
projfs_event_printf perm delete_dir d1
102+
projfs_event_printf notify delete_dir d1
97103
test_expect_success 'test permission granted on parent directory deletion' '
98104
projfs_event_exec rmdir target/d1 &&
99105
test_path_is_missing target/d1

t/t201-event-err.t

+15-19
Original file line numberDiff line numberDiff line change
@@ -45,40 +45,36 @@ test_expect_success 'test event handler error on file creation' '
4545
test_path_is_file target/f1.txt
4646
'
4747

48-
# TODO: we expect mv to rename a dir despite the handler error and
49-
# to not report a failure exit code
50-
projfs_event_printf error ENOMEM notify rename_dir d1 d1a
48+
projfs_event_printf error ENOMEM perm rename_dir d1 d1a
5149
test_expect_success 'test event handler error on directory rename' '
52-
test_might_fail projfs_event_exec mv target/d1 target/d1a &&
53-
test_path_is_dir target/d1a
50+
test_must_fail projfs_event_exec mv target/d1 target/d1a &&
51+
test_path_is_dir target/d1
5452
'
5553

56-
# TODO: we expect mv to rename a file despite the handler error and
57-
# to not report a failure exit code
58-
projfs_event_printf error ENOMEM notify rename_file f1.txt f1a.txt
54+
projfs_event_printf error ENOMEM perm rename_file f1.txt f1a.txt
5955
test_expect_success 'test event handler error on file rename' '
60-
test_might_fail projfs_event_exec mv target/f1.txt target/f1a.txt &&
61-
test_path_is_file target/f1a.txt
56+
test_must_fail projfs_event_exec mv target/f1.txt target/f1a.txt &&
57+
test_path_is_file target/f1.txt
6258
'
6359

6460
# TODO: we expect ln to link a file despite the handler error and
6561
# to not report a failure exit code
66-
projfs_event_printf error ENOMEM notify link_file f1a.txt l1a.txt
62+
projfs_event_printf error ENOMEM notify link_file f1.txt l1.txt
6763
test_expect_success 'test event handler error on file hard link' '
68-
test_might_fail projfs_event_exec ln target/f1a.txt target/l1a.txt &&
69-
test_path_is_file target/l1a.txt
64+
test_might_fail projfs_event_exec ln target/f1.txt target/l1.txt &&
65+
test_path_is_file target/l1.txt
7066
'
7167

72-
projfs_event_printf error ENOMEM perm delete_file f1a.txt
68+
projfs_event_printf error ENOMEM perm delete_file f1.txt
7369
test_expect_success 'test event handler error on file deletion' '
74-
test_must_fail projfs_event_exec rm target/f1a.txt &&
75-
test_path_is_file target/f1a.txt
70+
test_must_fail projfs_event_exec rm target/f1.txt &&
71+
test_path_is_file target/f1.txt
7672
'
7773

78-
projfs_event_printf error ENOMEM perm delete_dir d1a
74+
projfs_event_printf error ENOMEM perm delete_dir d1
7975
test_expect_success 'test event handler error on directory deletion' '
80-
test_must_fail projfs_event_exec rmdir target/d1a &&
81-
test_path_is_dir target/d1a
76+
test_must_fail projfs_event_exec rmdir target/d1 &&
77+
test_path_is_dir target/d1
8278
'
8379

8480
rm retval

t/t202-event-deny.t

+19-19
Original file line numberDiff line numberDiff line change
@@ -40,36 +40,36 @@ test_expect_success 'test event handler on file creation' '
4040
test_path_is_file target/f1.txt
4141
'
4242

43-
projfs_event_printf notify rename_dir d1 d1a
44-
test_expect_success 'test event handler on directory rename' '
45-
projfs_event_exec mv target/d1 target/d1a &&
46-
test_path_is_missing target/d1 &&
47-
test_path_is_dir target/d1a
43+
projfs_event_printf perm rename_dir d1 d1a
44+
test_expect_success 'test permission request denied on directory rename' '
45+
test_must_fail projfs_event_exec mv target/d1 target/d1a &&
46+
test_path_is_missing target/d1a &&
47+
test_path_is_dir target/d1
4848
'
4949

50-
projfs_event_printf notify rename_file f1.txt f1a.txt
51-
test_expect_success 'test event handler on file rename' '
52-
projfs_event_exec mv target/f1.txt target/f1a.txt &&
53-
test_path_is_missing target/f1.txt &&
54-
test_path_is_file target/f1a.txt
50+
projfs_event_printf perm rename_file f1.txt f1a.txt
51+
test_expect_success 'test permission request denied on file rename' '
52+
test_must_fail projfs_event_exec mv target/f1.txt target/f1a.txt &&
53+
test_path_is_missing target/f1a.txt &&
54+
test_path_is_file target/f1.txt
5555
'
5656

57-
projfs_event_printf notify link_file f1a.txt l1a.txt
57+
projfs_event_printf notify link_file f1.txt l1.txt
5858
test_expect_success 'test event handler on file hard link' '
59-
projfs_event_exec ln target/f1a.txt target/l1a.txt &&
60-
test_path_is_file target/l1a.txt
59+
projfs_event_exec ln target/f1.txt target/l1.txt &&
60+
test_path_is_file target/l1.txt
6161
'
6262

63-
projfs_event_printf perm delete_file f1a.txt
63+
projfs_event_printf perm delete_file f1.txt
6464
test_expect_success 'test permission request denied on file deletion' '
65-
test_must_fail projfs_event_exec rm target/f1a.txt &&
66-
test_path_is_file target/f1a.txt
65+
test_must_fail projfs_event_exec rm target/f1.txt &&
66+
test_path_is_file target/f1.txt
6767
'
6868

69-
projfs_event_printf perm delete_dir d1a
69+
projfs_event_printf perm delete_dir d1
7070
test_expect_success 'test permission request denied on directory deletion' '
71-
test_must_fail projfs_event_exec rmdir target/d1a &&
72-
test_path_is_dir target/d1a
71+
test_must_fail projfs_event_exec rmdir target/d1 &&
72+
test_path_is_dir target/d1
7373
'
7474

7575
rm retval

t/t203-event-null.t

+19-19
Original file line numberDiff line numberDiff line change
@@ -40,36 +40,36 @@ test_expect_success 'test event handler on file creation' '
4040
test_path_is_file target/f1.txt
4141
'
4242

43-
projfs_event_printf notify rename_dir d1 d1a
44-
test_expect_success 'test event handler on directory rename' '
45-
projfs_event_exec mv target/d1 target/d1a &&
46-
test_path_is_missing target/d1 &&
47-
test_path_is_dir target/d1a
43+
projfs_event_printf perm rename_dir d1 d1a
44+
test_expect_success 'test permission request denied on directory rename' '
45+
test_must_fail projfs_event_exec mv target/d1 target/d1a &&
46+
test_path_is_missing target/d1a &&
47+
test_path_is_dir target/d1
4848
'
4949

50-
projfs_event_printf notify rename_file f1.txt f1a.txt
51-
test_expect_success 'test event handler on file rename' '
52-
projfs_event_exec mv target/f1.txt target/f1a.txt &&
53-
test_path_is_missing target/f1.txt &&
54-
test_path_is_file target/f1a.txt
50+
projfs_event_printf perm rename_file f1.txt f1a.txt
51+
test_expect_success 'test permission request denied on file rename' '
52+
test_must_fail projfs_event_exec mv target/f1.txt target/f1a.txt &&
53+
test_path_is_missing target/f1a.txt &&
54+
test_path_is_file target/f1.txt
5555
'
5656

57-
projfs_event_printf notify link_file f1a.txt l1a.txt
57+
projfs_event_printf notify link_file f1.txt l1.txt
5858
test_expect_success 'test event handler on file hard link' '
59-
projfs_event_exec ln target/f1a.txt target/l1a.txt &&
60-
test_path_is_file target/l1a.txt
59+
projfs_event_exec ln target/f1.txt target/l1.txt &&
60+
test_path_is_file target/l1.txt
6161
'
6262

63-
projfs_event_printf perm delete_file f1a.txt
63+
projfs_event_printf perm delete_file f1.txt
6464
test_expect_success 'test permission request denied on file deletion' '
65-
test_must_fail projfs_event_exec rm target/f1a.txt &&
66-
test_path_is_file target/f1a.txt
65+
test_must_fail projfs_event_exec rm target/f1.txt &&
66+
test_path_is_file target/f1.txt
6767
'
6868

69-
projfs_event_printf perm delete_dir d1a
69+
projfs_event_printf perm delete_dir d1
7070
test_expect_success 'test permission request denied on directory deletion' '
71-
test_must_fail projfs_event_exec rmdir target/d1a &&
72-
test_path_is_dir target/d1a
71+
test_must_fail projfs_event_exec rmdir target/d1 &&
72+
test_path_is_dir target/d1
7373
'
7474

7575
rm retval

t/t204-event-allow.t

+4
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,15 @@ test_expect_success 'test event handler on file creation' '
4040
test_path_is_file target/f1.txt
4141
'
4242

43+
projfs_event_printf perm rename_dir d1 d1a
4344
projfs_event_printf notify rename_dir d1 d1a
4445
test_expect_success 'test event handler on directory rename' '
4546
projfs_event_exec mv target/d1 target/d1a &&
4647
test_path_is_missing target/d1 &&
4748
test_path_is_dir target/d1a
4849
'
4950

51+
projfs_event_printf perm rename_file f1.txt f1a.txt
5052
projfs_event_printf notify rename_file f1.txt f1a.txt
5153
test_expect_success 'test event handler on file rename' '
5254
projfs_event_exec mv target/f1.txt target/f1a.txt &&
@@ -61,12 +63,14 @@ test_expect_success 'test event handler on file hard link' '
6163
'
6264

6365
projfs_event_printf perm delete_file f1a.txt
66+
projfs_event_printf notify delete_file f1a.txt
6467
test_expect_success 'test permission request allowed on file deletion' '
6568
projfs_event_exec rm target/f1a.txt &&
6669
test_path_is_missing target/f1a.txt
6770
'
6871

6972
projfs_event_printf perm delete_dir d1a
73+
projfs_event_printf notify delete_dir d1a
7074
test_expect_success 'test permission request allowed on directory deletion' '
7175
projfs_event_exec rmdir target/d1a &&
7276
test_path_is_missing target/d1a

t/test-lib-event.sh

+15-9
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,21 @@ event_msg_perm="test permission request for"
2323

2424
event_msg_err="event handler failed"
2525

26-
event_rename_dir="0x0000-400000c0"
27-
event_create_dir="0x0000-40000100"
28-
event_delete_dir="0x0001-40000000"
26+
event_notify_close_file="0x0000-00000008"
27+
event_notify_rename_file="0x0000-000000c0"
28+
event_notify_create_file="0x0000-00000100"
29+
event_notify_delete_file="0x0000-00000200"
30+
event_notify_link_file="0x1000-00000100"
2931

30-
event_close_file="0x0000-00000008"
31-
event_rename_file="0x0000-000000c0"
32-
event_create_file="0x0000-00000100"
33-
event_delete_file="0x0001-00000000"
34-
event_link_file="0x1000-00000100"
32+
event_notify_rename_dir="0x0000-400000c0"
33+
event_notify_create_dir="0x0000-40000100"
34+
event_notify_delete_dir="0x0000-40000200"
35+
36+
event_perm_delete_file="0x0002-00000000"
37+
event_perm_rename_file="0x0004-00000000"
38+
39+
event_perm_delete_dir="0x0002-40000000"
40+
event_perm_rename_dir="0x0004-40000000"
3541

3642
NL=$(printf "\nx")
3743
NL="${NL%%x}"
@@ -59,7 +65,7 @@ projfs_event_printf () {
5965
fi
6066

6167
eval msg=\$event_msg_"$1"
62-
eval code=\$event_"$2"
68+
eval code=\$event_"$1"_"$2"
6369

6470
if test -z "$4"
6571
then

0 commit comments

Comments
 (0)