@@ -19,8 +19,8 @@ __always_inline static void path_write_char(char* p, unsigned int offset, char c
1919 * path_safe_access (p , offset ) = c ;
2020}
2121
22- __always_inline static struct bound_path_t * _path_read (struct path * path , bool use_bpf_d_path ) {
23- struct bound_path_t * bound_path = get_bound_path ();
22+ __always_inline static struct bound_path_t * _path_read (struct path * path , bound_path_buffer_t key , bool use_bpf_d_path ) {
23+ struct bound_path_t * bound_path = get_bound_path (key );
2424 if (bound_path == NULL ) {
2525 return NULL ;
2626 }
@@ -37,11 +37,19 @@ __always_inline static struct bound_path_t* _path_read(struct path* path, bool u
3737}
3838
3939__always_inline static struct bound_path_t * path_read (struct path * path ) {
40- return _path_read (path , true);
40+ return _path_read (path , BOUND_PATH_MAIN , true);
4141}
4242
4343__always_inline static struct bound_path_t * path_read_no_d_path (struct path * path ) {
44- return _path_read (path , false);
44+ return _path_read (path , BOUND_PATH_MAIN , false);
45+ }
46+
47+ __always_inline static struct bound_path_t * path_read_alt (struct path * path ) {
48+ return _path_read (path , BOUND_PATH_ALTERNATE , true);
49+ }
50+
51+ __always_inline static struct bound_path_t * path_read_alt_no_d_path (struct path * path ) {
52+ return _path_read (path , BOUND_PATH_ALTERNATE , false);
4553}
4654
4755enum path_append_status_t {
@@ -69,3 +77,47 @@ __always_inline static enum path_append_status_t path_append_dentry(struct bound
6977
7078 return 0 ;
7179}
80+
81+ __always_inline static struct bound_path_t * _path_read_append_d_entry (struct path * dir , struct dentry * dentry , bound_path_buffer_t key ) {
82+ struct bound_path_t * path = _path_read (dir , key , path_hooks_support_bpf_d_path );
83+
84+ if (path == NULL ) {
85+ bpf_printk ("Failed to read path" );
86+ return NULL ;
87+ }
88+ path_write_char (path -> path , path -> len - 1 , '/' );
89+
90+ switch (path_append_dentry (path , dentry )) {
91+ case PATH_APPEND_SUCCESS :
92+ break ;
93+ case PATH_APPEND_INVALID_LENGTH :
94+ bpf_printk ("Invalid path length: %u" , path -> len );
95+ return NULL ;
96+ case PATH_APPEND_READ_ERROR :
97+ bpf_printk ("Failed to read final path component" );
98+ return NULL ;
99+ }
100+ return path ;
101+ }
102+
103+ /**
104+ * Read the path and append the supplied dentry.
105+ *
106+ * A very common pattern in the kernel is to provide a struct path to a
107+ * directory and a dentry to an element in said directory, this helper
108+ * provides a short way of resolving the full path in one call.
109+ */
110+ __always_inline static struct bound_path_t * path_read_append_d_entry (struct path * dir , struct dentry * dentry ) {
111+ return _path_read_append_d_entry (dir , dentry , BOUND_PATH_MAIN );
112+ }
113+
114+ /**
115+ * Read the path and append the supplied dentry.
116+ *
117+ * This works essentially the same as path_read_append_d_entry, but does
118+ * so in an alternate buffer. Useful for operations that take more than
119+ * one path, like path_rename.
120+ */
121+ __always_inline static struct bound_path_t * path_read_alt_append_d_entry (struct path * dir , struct dentry * dentry ) {
122+ return _path_read_append_d_entry (dir , dentry , BOUND_PATH_ALTERNATE );
123+ }
0 commit comments