1 /* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by
5 * Examples of object plugins: file, directory, symlink, special file.
7 * Plugins associated with inode:
9 * Plugin of inode is plugin referenced by plugin-id field of on-disk
10 * stat-data. How we store this plugin in in-core inode is not
11 * important. Currently pointers are used, another variant is to store offsets
12 * and do array lookup on each access.
14 * Now, each inode has one selected plugin: object plugin that
15 * determines what type of file this object is: directory, regular etc.
17 * This main plugin can use other plugins that are thus subordinated to
18 * it. Directory instance of object plugin uses hash; regular file
19 * instance uses tail policy plugin.
21 * Object plugin is either taken from id in stat-data or guessed from
22 * i_mode bits. Once it is established we ask it to install its
23 * subordinate plugins, by looking again in stat-data or inheriting them
26 * How new inode is initialized during ->read_inode():
27 * 1 read stat-data and initialize inode fields: i_size, i_mode,
28 * i_generation, capabilities etc.
29 * 2 read plugin id from stat data or try to guess plugin id
30 * from inode->i_mode bits if plugin id is missing.
31 * 3 Call ->init_inode() method of stat-data plugin to initialise inode fields.
33 * NIKITA-FIXME-HANS: can you say a little about 1 being done before 3? What
34 * if stat data does contain i_size, etc., due to it being an unusual plugin?
36 * 4 Call ->activate() method of object's plugin. Plugin is either read from
37 * from stat-data or guessed from mode bits
38 * 5 Call ->inherit() method of object plugin to inherit as yet un initialized
39 * plugins from parent.
41 * Easy induction proves that on last step all plugins of inode would be
44 * When creating new object:
45 * 1 obtain object plugin id (see next period)
46 * NIKITA-FIXME-HANS: period?
47 * 2 ->install() this plugin
48 * 3 ->inherit() the rest from the parent
50 * We need some examples of creating an object with default and non-default
51 * plugin ids. Nikita, please create them.
56 static int _bugop(void)
62 #define bugop ((void *)_bugop)
64 static int _dummyop(void)
69 #define dummyop ((void *)_dummyop)
71 static int change_file(struct inode
*inode
,
72 reiser4_plugin
* plugin
,
75 /* cannot change object plugin of already existing object */
76 if (memb
== PSET_FILE
)
77 return RETERR(-EINVAL
);
79 /* Change PSET_CREATE */
80 return aset_set_unsafe(&reiser4_inode_data(inode
)->pset
, memb
, plugin
);
83 static reiser4_plugin_ops file_plugin_ops
= {
88 * Definitions of object plugins.
91 file_plugin file_plugins
[LAST_FILE_PLUGIN_ID
] = {
92 [UNIX_FILE_PLUGIN_ID
] = {
94 .type_id
= REISER4_FILE_PLUGIN_TYPE
,
95 .id
= UNIX_FILE_PLUGIN_ID
,
96 .groups
= (1 << REISER4_REGULAR_FILE
),
97 .pops
= &file_plugin_ops
,
99 .desc
= "regular file",
100 .linkage
= {NULL
, NULL
},
103 .permission
= reiser4_permission_common
,
104 .setattr
= setattr_unix_file
,
105 .getattr
= reiser4_getattr_common
108 .llseek
= generic_file_llseek
,
109 .read
= read_unix_file
,
110 .write
= write_unix_file
,
111 .aio_read
= generic_file_aio_read
,
112 .ioctl
= ioctl_unix_file
,
113 .mmap
= mmap_unix_file
,
114 .open
= open_unix_file
,
115 .release
= release_unix_file
,
116 .fsync
= sync_unix_file
,
119 .writepage
= reiser4_writepage
,
120 .readpage
= readpage_unix_file
,
121 .sync_page
= block_sync_page
,
122 .writepages
= writepages_unix_file
,
123 .set_page_dirty
= reiser4_set_page_dirty
,
124 .readpages
= readpages_unix_file
,
125 .prepare_write
= prepare_write_unix_file
,
126 .commit_write
= commit_write_unix_file
,
127 .bmap
= bmap_unix_file
,
128 .invalidatepage
= reiser4_invalidatepage
,
129 .releasepage
= reiser4_releasepage
131 .write_sd_by_inode
= write_sd_by_inode_common
,
132 .flow_by_inode
= flow_by_inode_unix_file
,
133 .key_by_inode
= key_by_inode_and_offset_common
,
134 .set_plug_in_inode
= set_plug_in_inode_common
,
135 .adjust_to_parent
= adjust_to_parent_common
,
136 .create_object
= reiser4_create_object_common
,
137 .delete_object
= delete_object_unix_file
,
138 .add_link
= reiser4_add_link_common
,
139 .rem_link
= reiser4_rem_link_common
,
140 .owns_item
= owns_item_unix_file
,
141 .can_add_link
= can_add_link_common
,
144 .safelink
= safelink_common
,
146 .create
= estimate_create_common
,
147 .update
= estimate_update_common
,
148 .unlink
= estimate_unlink_common
150 .init_inode_data
= init_inode_data_unix_file
,
151 .cut_tree_worker
= cut_tree_worker_common
,
153 .write
= wire_write_common
,
154 .read
= wire_read_common
,
155 .get
= wire_get_common
,
156 .size
= wire_size_common
,
157 .done
= wire_done_common
160 [DIRECTORY_FILE_PLUGIN_ID
] = {
162 .type_id
= REISER4_FILE_PLUGIN_TYPE
,
163 .id
= DIRECTORY_FILE_PLUGIN_ID
,
164 .groups
= (1 << REISER4_DIRECTORY_FILE
),
165 .pops
= &file_plugin_ops
,
168 .linkage
= {NULL
, NULL
}
170 .inode_ops
= {.create
= NULL
},
171 .file_ops
= {.owner
= NULL
},
172 .as_ops
= {.writepage
= NULL
},
174 .write_sd_by_inode
= write_sd_by_inode_common
,
175 .flow_by_inode
= bugop
,
176 .key_by_inode
= bugop
,
177 .set_plug_in_inode
= set_plug_in_inode_common
,
178 .adjust_to_parent
= adjust_to_parent_common_dir
,
179 .create_object
= reiser4_create_object_common
,
180 .delete_object
= reiser4_delete_dir_common
,
181 .add_link
= reiser4_add_link_common
,
182 .rem_link
= rem_link_common_dir
,
183 .owns_item
= owns_item_common_dir
,
184 .can_add_link
= can_add_link_common
,
185 .can_rem_link
= can_rem_link_common_dir
,
186 .detach
= reiser4_detach_common_dir
,
187 .bind
= reiser4_bind_common_dir
,
188 .safelink
= safelink_common
,
190 .create
= estimate_create_common_dir
,
191 .update
= estimate_update_common
,
192 .unlink
= estimate_unlink_common_dir
195 .write
= wire_write_common
,
196 .read
= wire_read_common
,
197 .get
= wire_get_common
,
198 .size
= wire_size_common
,
199 .done
= wire_done_common
201 .init_inode_data
= init_inode_ordering
,
202 .cut_tree_worker
= cut_tree_worker_common
,
204 [SYMLINK_FILE_PLUGIN_ID
] = {
206 .type_id
= REISER4_FILE_PLUGIN_TYPE
,
207 .id
= SYMLINK_FILE_PLUGIN_ID
,
208 .groups
= (1 << REISER4_SYMLINK_FILE
),
209 .pops
= &file_plugin_ops
,
211 .desc
= "symbolic link",
212 .linkage
= {NULL
,NULL
}
215 .readlink
= generic_readlink
,
216 .follow_link
= reiser4_follow_link_common
,
217 .permission
= reiser4_permission_common
,
218 .setattr
= reiser4_setattr_common
,
219 .getattr
= reiser4_getattr_common
221 /* inode->i_fop of symlink is initialized by NULL in setup_inode_ops */
222 .file_ops
= {.owner
= NULL
},
223 .as_ops
= {.writepage
= NULL
},
225 .write_sd_by_inode
= write_sd_by_inode_common
,
226 .set_plug_in_inode
= set_plug_in_inode_common
,
227 .adjust_to_parent
= adjust_to_parent_common
,
228 .create_object
= reiser4_create_symlink
,
229 .delete_object
= reiser4_delete_object_common
,
230 .add_link
= reiser4_add_link_common
,
231 .rem_link
= reiser4_rem_link_common
,
232 .can_add_link
= can_add_link_common
,
235 .safelink
= safelink_common
,
237 .create
= estimate_create_common
,
238 .update
= estimate_update_common
,
239 .unlink
= estimate_unlink_common
241 .init_inode_data
= init_inode_ordering
,
242 .cut_tree_worker
= cut_tree_worker_common
,
243 .destroy_inode
= destroy_inode_symlink
,
245 .write
= wire_write_common
,
246 .read
= wire_read_common
,
247 .get
= wire_get_common
,
248 .size
= wire_size_common
,
249 .done
= wire_done_common
252 [SPECIAL_FILE_PLUGIN_ID
] = {
254 .type_id
= REISER4_FILE_PLUGIN_TYPE
,
255 .id
= SPECIAL_FILE_PLUGIN_ID
,
256 .groups
= (1 << REISER4_SPECIAL_FILE
),
257 .pops
= &file_plugin_ops
,
260 "special: fifo, device or socket",
261 .linkage
= {NULL
, NULL
}
264 .permission
= reiser4_permission_common
,
265 .setattr
= reiser4_setattr_common
,
266 .getattr
= reiser4_getattr_common
268 /* file_ops of special files (sockets, block, char, fifo) are
269 initialized by init_special_inode. */
270 .file_ops
= {.owner
= NULL
},
271 .as_ops
= {.writepage
= NULL
},
273 .write_sd_by_inode
= write_sd_by_inode_common
,
274 .set_plug_in_inode
= set_plug_in_inode_common
,
275 .adjust_to_parent
= adjust_to_parent_common
,
276 .create_object
= reiser4_create_object_common
,
277 .delete_object
= reiser4_delete_object_common
,
278 .add_link
= reiser4_add_link_common
,
279 .rem_link
= reiser4_rem_link_common
,
280 .owns_item
= owns_item_common
,
281 .can_add_link
= can_add_link_common
,
284 .safelink
= safelink_common
,
286 .create
= estimate_create_common
,
287 .update
= estimate_update_common
,
288 .unlink
= estimate_unlink_common
290 .init_inode_data
= init_inode_ordering
,
291 .cut_tree_worker
= cut_tree_worker_common
,
293 .write
= wire_write_common
,
294 .read
= wire_read_common
,
295 .get
= wire_get_common
,
296 .size
= wire_size_common
,
297 .done
= wire_done_common
300 [CRYPTCOMPRESS_FILE_PLUGIN_ID
] = {
302 .type_id
= REISER4_FILE_PLUGIN_TYPE
,
303 .id
= CRYPTCOMPRESS_FILE_PLUGIN_ID
,
304 .groups
= (1 << REISER4_REGULAR_FILE
),
305 .pops
= &file_plugin_ops
,
306 .label
= "cryptcompress",
307 .desc
= "cryptcompress file",
308 .linkage
= {NULL
, NULL
}
311 .permission
= reiser4_permission_common
,
312 .setattr
= prot_setattr_cryptcompress
,
313 .getattr
= reiser4_getattr_common
316 .llseek
= generic_file_llseek
,
317 .read
= prot_read_cryptcompress
,
318 .write
= prot_write_cryptcompress
,
319 .aio_read
= generic_file_aio_read
,
320 .mmap
= prot_mmap_cryptcompress
,
321 .release
= prot_release_cryptcompress
,
322 .fsync
= reiser4_sync_common
,
325 .writepage
= reiser4_writepage
,
326 .readpage
= readpage_cryptcompress
,
327 .sync_page
= block_sync_page
,
328 .writepages
= writepages_cryptcompress
,
329 .set_page_dirty
= reiser4_set_page_dirty
,
330 .readpages
= readpages_cryptcompress
,
331 .prepare_write
= prepare_write_common
,
332 .invalidatepage
= reiser4_invalidatepage
,
333 .releasepage
= reiser4_releasepage
335 .write_sd_by_inode
= write_sd_by_inode_common
,
336 .flow_by_inode
= flow_by_inode_cryptcompress
,
337 .key_by_inode
= key_by_inode_cryptcompress
,
338 .set_plug_in_inode
= set_plug_in_inode_common
,
339 .adjust_to_parent
= adjust_to_parent_cryptcompress
,
340 .create_object
= create_cryptcompress
,
341 .open_object
= open_object_cryptcompress
,
342 .delete_object
= delete_object_cryptcompress
,
343 .add_link
= reiser4_add_link_common
,
344 .rem_link
= reiser4_rem_link_common
,
345 .owns_item
= owns_item_common
,
346 .can_add_link
= can_add_link_common
,
349 .safelink
= safelink_common
,
351 .create
= estimate_create_common
,
352 .update
= estimate_update_common
,
353 .unlink
= estimate_unlink_common
355 .init_inode_data
= init_inode_data_cryptcompress
,
356 .cut_tree_worker
= cut_tree_worker_cryptcompress
,
357 .destroy_inode
= destroy_inode_cryptcompress
,
359 .write
= wire_write_common
,
360 .read
= wire_read_common
,
361 .get
= wire_get_common
,
362 .size
= wire_size_common
,
363 .done
= wire_done_common
368 static int change_dir(struct inode
*inode
,
369 reiser4_plugin
* plugin
,
372 /* cannot change dir plugin of already existing object */
373 return RETERR(-EINVAL
);
376 static reiser4_plugin_ops dir_plugin_ops
= {
381 * definition of directory plugins
384 dir_plugin dir_plugins
[LAST_DIR_ID
] = {
385 /* standard hashed directory plugin */
386 [HASHED_DIR_PLUGIN_ID
] = {
388 .type_id
= REISER4_DIR_PLUGIN_TYPE
,
389 .id
= HASHED_DIR_PLUGIN_ID
,
390 .pops
= &dir_plugin_ops
,
392 .desc
= "hashed directory",
393 .linkage
= {NULL
, NULL
}
396 .create
= reiser4_create_common
,
397 .lookup
= reiser4_lookup_common
,
398 .link
= reiser4_link_common
,
399 .unlink
= reiser4_unlink_common
,
400 .symlink
= reiser4_symlink_common
,
401 .mkdir
= reiser4_mkdir_common
,
402 .rmdir
= reiser4_unlink_common
,
403 .mknod
= reiser4_mknod_common
,
404 .rename
= reiser4_rename_common
,
405 .permission
= reiser4_permission_common
,
406 .setattr
= reiser4_setattr_common
,
407 .getattr
= reiser4_getattr_common
410 .llseek
= reiser4_llseek_dir_common
,
411 .read
= generic_read_dir
,
412 .readdir
= reiser4_readdir_common
,
413 .release
= reiser4_release_dir_common
,
414 .fsync
= reiser4_sync_common
419 .writepages
= dummyop
,
420 .set_page_dirty
= bugop
,
422 .prepare_write
= bugop
,
423 .commit_write
= bugop
,
425 .invalidatepage
= bugop
,
428 .get_parent
= get_parent_common
,
429 .is_name_acceptable
= is_name_acceptable_common
,
430 .build_entry_key
= build_entry_key_hashed
,
431 .build_readdir_key
= build_readdir_key_common
,
432 .add_entry
= reiser4_add_entry_common
,
433 .rem_entry
= reiser4_rem_entry_common
,
434 .init
= reiser4_dir_init_common
,
435 .done
= reiser4_dir_done_common
,
436 .attach
= reiser4_attach_common
,
437 .detach
= reiser4_detach_common
,
439 .add_entry
= estimate_add_entry_common
,
440 .rem_entry
= estimate_rem_entry_common
,
441 .unlink
= dir_estimate_unlink_common
444 /* hashed directory for which seekdir/telldir are guaranteed to
445 * work. Brain-damage. */
446 [SEEKABLE_HASHED_DIR_PLUGIN_ID
] = {
448 .type_id
= REISER4_DIR_PLUGIN_TYPE
,
449 .id
= SEEKABLE_HASHED_DIR_PLUGIN_ID
,
450 .pops
= &dir_plugin_ops
,
452 .desc
= "directory hashed with 31 bit hash",
453 .linkage
= {NULL
, NULL
}
456 .create
= reiser4_create_common
,
457 .lookup
= reiser4_lookup_common
,
458 .link
= reiser4_link_common
,
459 .unlink
= reiser4_unlink_common
,
460 .symlink
= reiser4_symlink_common
,
461 .mkdir
= reiser4_mkdir_common
,
462 .rmdir
= reiser4_unlink_common
,
463 .mknod
= reiser4_mknod_common
,
464 .rename
= reiser4_rename_common
,
465 .permission
= reiser4_permission_common
,
466 .setattr
= reiser4_setattr_common
,
467 .getattr
= reiser4_getattr_common
470 .llseek
= reiser4_llseek_dir_common
,
471 .read
= generic_read_dir
,
472 .readdir
= reiser4_readdir_common
,
473 .release
= reiser4_release_dir_common
,
474 .fsync
= reiser4_sync_common
479 .writepages
= dummyop
,
480 .set_page_dirty
= bugop
,
482 .prepare_write
= bugop
,
483 .commit_write
= bugop
,
485 .invalidatepage
= bugop
,
488 .get_parent
= get_parent_common
,
489 .is_name_acceptable
= is_name_acceptable_common
,
490 .build_entry_key
= build_entry_key_seekable
,
491 .build_readdir_key
= build_readdir_key_common
,
492 .add_entry
= reiser4_add_entry_common
,
493 .rem_entry
= reiser4_rem_entry_common
,
494 .init
= reiser4_dir_init_common
,
495 .done
= reiser4_dir_done_common
,
496 .attach
= reiser4_attach_common
,
497 .detach
= reiser4_detach_common
,
499 .add_entry
= estimate_add_entry_common
,
500 .rem_entry
= estimate_rem_entry_common
,
501 .unlink
= dir_estimate_unlink_common
508 c-indentation-style: "K&R"