revert-mm-fix-blkdev-size-calculation-in-generic_write_checks
[linux-2.6/linux-trees-mm.git] / fs / reiser4 / plugin / object.c
blob0de3c7e5c844dcff4f4f048298edfb3d397dd60c
1 /* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by
2 * reiser4/README */
4 /*
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
24 * from parent.
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
42 * initialized.
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.
54 #include "../inode.h"
56 static int _bugop(void)
58 BUG_ON(1);
59 return 0;
62 #define bugop ((void *)_bugop)
64 static int _dummyop(void)
66 return 0;
69 #define dummyop ((void *)_dummyop)
71 static int change_file(struct inode *inode,
72 reiser4_plugin * plugin,
73 pset_member memb)
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 = {
84 .change = change_file
88 * Definitions of object plugins.
91 file_plugin file_plugins[LAST_FILE_PLUGIN_ID] = {
92 [UNIX_FILE_PLUGIN_ID] = {
93 .h = {
94 .type_id = REISER4_FILE_PLUGIN_TYPE,
95 .id = UNIX_FILE_PLUGIN_ID,
96 .groups = (1 << REISER4_REGULAR_FILE),
97 .pops = &file_plugin_ops,
98 .label = "reg",
99 .desc = "regular file",
100 .linkage = {NULL, NULL},
102 .inode_ops = {
103 .permission = reiser4_permission_common,
104 .setattr = setattr_unix_file,
105 .getattr = reiser4_getattr_common
107 .file_ops = {
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,
118 .as_ops = {
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,
142 .detach = dummyop,
143 .bind = dummyop,
144 .safelink = safelink_common,
145 .estimate = {
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,
152 .wire = {
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] = {
161 .h = {
162 .type_id = REISER4_FILE_PLUGIN_TYPE,
163 .id = DIRECTORY_FILE_PLUGIN_ID,
164 .groups = (1 << REISER4_DIRECTORY_FILE),
165 .pops = &file_plugin_ops,
166 .label = "dir",
167 .desc = "directory",
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,
189 .estimate = {
190 .create = estimate_create_common_dir,
191 .update = estimate_update_common,
192 .unlink = estimate_unlink_common_dir
194 .wire = {
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] = {
205 .h = {
206 .type_id = REISER4_FILE_PLUGIN_TYPE,
207 .id = SYMLINK_FILE_PLUGIN_ID,
208 .groups = (1 << REISER4_SYMLINK_FILE),
209 .pops = &file_plugin_ops,
210 .label = "symlink",
211 .desc = "symbolic link",
212 .linkage = {NULL,NULL}
214 .inode_ops = {
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,
233 .detach = dummyop,
234 .bind = dummyop,
235 .safelink = safelink_common,
236 .estimate = {
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,
244 .wire = {
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] = {
253 .h = {
254 .type_id = REISER4_FILE_PLUGIN_TYPE,
255 .id = SPECIAL_FILE_PLUGIN_ID,
256 .groups = (1 << REISER4_SPECIAL_FILE),
257 .pops = &file_plugin_ops,
258 .label = "special",
259 .desc =
260 "special: fifo, device or socket",
261 .linkage = {NULL, NULL}
263 .inode_ops = {
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,
282 .detach = dummyop,
283 .bind = dummyop,
284 .safelink = safelink_common,
285 .estimate = {
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,
292 .wire = {
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] = {
301 .h = {
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}
310 .inode_ops = {
311 .permission = reiser4_permission_common,
312 .setattr = prot_setattr_cryptcompress,
313 .getattr = reiser4_getattr_common
315 .file_ops = {
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,
324 .as_ops = {
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,
347 .detach = dummyop,
348 .bind = dummyop,
349 .safelink = safelink_common,
350 .estimate = {
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,
358 .wire = {
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,
370 pset_member memb)
372 /* cannot change dir plugin of already existing object */
373 return RETERR(-EINVAL);
376 static reiser4_plugin_ops dir_plugin_ops = {
377 .change = change_dir
381 * definition of directory plugins
384 dir_plugin dir_plugins[LAST_DIR_ID] = {
385 /* standard hashed directory plugin */
386 [HASHED_DIR_PLUGIN_ID] = {
387 .h = {
388 .type_id = REISER4_DIR_PLUGIN_TYPE,
389 .id = HASHED_DIR_PLUGIN_ID,
390 .pops = &dir_plugin_ops,
391 .label = "dir",
392 .desc = "hashed directory",
393 .linkage = {NULL, NULL}
395 .inode_ops = {
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
409 .file_ops = {
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
416 .as_ops = {
417 .writepage = bugop,
418 .sync_page = bugop,
419 .writepages = dummyop,
420 .set_page_dirty = bugop,
421 .readpages = bugop,
422 .prepare_write = bugop,
423 .commit_write = bugop,
424 .bmap = bugop,
425 .invalidatepage = bugop,
426 .releasepage = 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,
438 .estimate = {
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] = {
447 .h = {
448 .type_id = REISER4_DIR_PLUGIN_TYPE,
449 .id = SEEKABLE_HASHED_DIR_PLUGIN_ID,
450 .pops = &dir_plugin_ops,
451 .label = "dir32",
452 .desc = "directory hashed with 31 bit hash",
453 .linkage = {NULL, NULL}
455 .inode_ops = {
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
469 .file_ops = {
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
476 .as_ops = {
477 .writepage = bugop,
478 .sync_page = bugop,
479 .writepages = dummyop,
480 .set_page_dirty = bugop,
481 .readpages = bugop,
482 .prepare_write = bugop,
483 .commit_write = bugop,
484 .bmap = bugop,
485 .invalidatepage = bugop,
486 .releasepage = 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,
498 .estimate = {
499 .add_entry = estimate_add_entry_common,
500 .rem_entry = estimate_rem_entry_common,
501 .unlink = dir_estimate_unlink_common
506 /* Make Linus happy.
507 Local variables:
508 c-indentation-style: "K&R"
509 mode-name: "LC"
510 c-basic-offset: 8
511 tab-width: 8
512 fill-column: 120
513 End: