revert-mm-fix-blkdev-size-calculation-in-generic_write_checks
[linux-2.6/linux-trees-mm.git] / fs / reiser4 / plugin / item / static_stat.c
blobeb3a3df4bd42e5e82e2af96fbd0f8406900bce6a
1 /* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */
3 /* stat data manipulation. */
5 #include "../../forward.h"
6 #include "../../super.h"
7 #include "../../vfs_ops.h"
8 #include "../../inode.h"
9 #include "../../debug.h"
10 #include "../../dformat.h"
11 #include "../object.h"
12 #include "../plugin.h"
13 #include "../plugin_header.h"
14 #include "static_stat.h"
15 #include "item.h"
17 #include <linux/types.h>
18 #include <linux/fs.h>
20 /* see static_stat.h for explanation */
22 /* helper function used while we are dumping/loading inode/plugin state
23 to/from the stat-data. */
25 static void move_on(int *length /* space remaining in stat-data */ ,
26 char **area /* current coord in stat data */ ,
27 int size_of /* how many bytes to move forward */ )
29 assert("nikita-615", length != NULL);
30 assert("nikita-616", area != NULL);
32 *length -= size_of;
33 *area += size_of;
35 assert("nikita-617", *length >= 0);
38 /* helper function used while loading inode/plugin state from stat-data.
39 Complain if there is less space in stat-data than was expected.
40 Can only happen on disk corruption. */
41 static int not_enough_space(struct inode *inode /* object being processed */ ,
42 const char *where /* error message */ )
44 assert("nikita-618", inode != NULL);
46 warning("nikita-619", "Not enough space in %llu while loading %s",
47 (unsigned long long)get_inode_oid(inode), where);
49 return RETERR(-EINVAL);
52 /* helper function used while loading inode/plugin state from
53 stat-data. Call it if invalid plugin id was found. */
54 static int unknown_plugin(reiser4_plugin_id id /* invalid id */ ,
55 struct inode *inode /* object being processed */ )
57 warning("nikita-620", "Unknown plugin %i in %llu",
58 id, (unsigned long long)get_inode_oid(inode));
60 return RETERR(-EINVAL);
63 /* this is installed as ->init_inode() method of
64 item_plugins[ STATIC_STAT_DATA_IT ] (fs/reiser4/plugin/item/item.c).
65 Copies data from on-disk stat-data format into inode.
66 Handles stat-data extensions. */
67 /* was sd_load */
68 int init_inode_static_sd(struct inode *inode /* object being processed */ ,
69 char *sd /* stat-data body */ ,
70 int len /* length of stat-data */ )
72 int result;
73 int bit;
74 int chunk;
75 __u16 mask;
76 __u64 bigmask;
77 reiser4_stat_data_base *sd_base;
78 reiser4_inode *state;
80 assert("nikita-625", inode != NULL);
81 assert("nikita-626", sd != NULL);
83 result = 0;
84 sd_base = (reiser4_stat_data_base *) sd;
85 state = reiser4_inode_data(inode);
86 mask = le16_to_cpu(get_unaligned(&sd_base->extmask));
87 bigmask = mask;
88 reiser4_inode_set_flag(inode, REISER4_SDLEN_KNOWN);
90 move_on(&len, &sd, sizeof *sd_base);
91 for (bit = 0, chunk = 0;
92 mask != 0 || bit <= LAST_IMPORTANT_SD_EXTENSION;
93 ++bit, mask >>= 1) {
94 if (((bit + 1) % 16) != 0) {
95 /* handle extension */
96 sd_ext_plugin *sdplug;
98 if (bit >= LAST_SD_EXTENSION) {
99 warning("vpf-1904",
100 "No such extension %i in inode %llu",
101 bit,
102 (unsigned long long)
103 get_inode_oid(inode));
105 result = RETERR(-EINVAL);
106 break;
109 sdplug = sd_ext_plugin_by_id(bit);
110 if (sdplug == NULL) {
111 warning("nikita-627",
112 "No such extension %i in inode %llu",
113 bit,
114 (unsigned long long)
115 get_inode_oid(inode));
117 result = RETERR(-EINVAL);
118 break;
120 if (mask & 1) {
121 assert("nikita-628", sdplug->present);
122 /* alignment is not supported in node layout
123 plugin yet.
124 result = align( inode, &len, &sd,
125 sdplug -> alignment );
126 if( result != 0 )
127 return result; */
128 result = sdplug->present(inode, &sd, &len);
129 } else if (sdplug->absent != NULL)
130 result = sdplug->absent(inode);
131 if (result)
132 break;
133 /* else, we are looking at the last bit in 16-bit
134 portion of bitmask */
135 } else if (mask & 1) {
136 /* next portion of bitmask */
137 if (len < (int)sizeof(d16)) {
138 warning("nikita-629",
139 "No space for bitmap in inode %llu",
140 (unsigned long long)
141 get_inode_oid(inode));
143 result = RETERR(-EINVAL);
144 break;
146 mask = le16_to_cpu(get_unaligned((d16 *)sd));
147 bigmask <<= 16;
148 bigmask |= mask;
149 move_on(&len, &sd, sizeof(d16));
150 ++chunk;
151 if (chunk == 3) {
152 if (!(mask & 0x8000)) {
153 /* clear last bit */
154 mask &= ~0x8000;
155 continue;
157 /* too much */
158 warning("nikita-630",
159 "Too many extensions in %llu",
160 (unsigned long long)
161 get_inode_oid(inode));
163 result = RETERR(-EINVAL);
164 break;
166 } else
167 /* bitmask exhausted */
168 break;
170 state->extmask = bigmask;
171 /* common initialisations */
172 if (len - (bit / 16 * sizeof(d16)) > 0) {
173 /* alignment in save_len_static_sd() is taken into account
174 -edward */
175 warning("nikita-631", "unused space in inode %llu",
176 (unsigned long long)get_inode_oid(inode));
179 return result;
182 /* estimates size of stat-data required to store inode.
183 Installed as ->save_len() method of
184 item_plugins[ STATIC_STAT_DATA_IT ] (fs/reiser4/plugin/item/item.c). */
185 /* was sd_len */
186 int save_len_static_sd(struct inode *inode /* object being processed */ )
188 unsigned int result;
189 __u64 mask;
190 int bit;
192 assert("nikita-632", inode != NULL);
194 result = sizeof(reiser4_stat_data_base);
195 mask = reiser4_inode_data(inode)->extmask;
196 for (bit = 0; mask != 0; ++bit, mask >>= 1) {
197 if (mask & 1) {
198 sd_ext_plugin *sdplug;
200 sdplug = sd_ext_plugin_by_id(bit);
201 assert("nikita-633", sdplug != NULL);
202 /* no aligment support
203 result +=
204 round_up( result, sdplug -> alignment ) - result; */
205 result += sdplug->save_len(inode);
208 result += bit / 16 * sizeof(d16);
209 return result;
212 /* saves inode into stat-data.
213 Installed as ->save() method of
214 item_plugins[ STATIC_STAT_DATA_IT ] (fs/reiser4/plugin/item/item.c). */
215 /* was sd_save */
216 int save_static_sd(struct inode *inode /* object being processed */ ,
217 char **area /* where to save stat-data */ )
219 int result;
220 __u64 emask;
221 int bit;
222 unsigned int len;
223 reiser4_stat_data_base *sd_base;
225 assert("nikita-634", inode != NULL);
226 assert("nikita-635", area != NULL);
228 result = 0;
229 emask = reiser4_inode_data(inode)->extmask;
230 sd_base = (reiser4_stat_data_base *) * area;
231 put_unaligned(cpu_to_le16((__u16)(emask & 0xffff)), &sd_base->extmask);
232 /*cputod16((unsigned)(emask & 0xffff), &sd_base->extmask);*/
234 *area += sizeof *sd_base;
235 len = 0xffffffffu;
236 for (bit = 0; emask != 0; ++bit, emask >>= 1) {
237 if (emask & 1) {
238 if ((bit + 1) % 16 != 0) {
239 sd_ext_plugin *sdplug;
240 sdplug = sd_ext_plugin_by_id(bit);
241 assert("nikita-636", sdplug != NULL);
242 /* no alignment support yet
243 align( inode, &len, area,
244 sdplug -> alignment ); */
245 result = sdplug->save(inode, area);
246 if (result)
247 break;
248 } else {
249 put_unaligned(cpu_to_le16((__u16)(emask & 0xffff)),
250 (d16 *)(*area));
251 /*cputod16((unsigned)(emask & 0xffff),
252 (d16 *) * area);*/
253 *area += sizeof(d16);
257 return result;
260 /* stat-data extension handling functions. */
262 static int present_lw_sd(struct inode *inode /* object being processed */ ,
263 char **area /* position in stat-data */ ,
264 int *len /* remaining length */ )
266 if (*len >= (int)sizeof(reiser4_light_weight_stat)) {
267 reiser4_light_weight_stat *sd_lw;
269 sd_lw = (reiser4_light_weight_stat *) * area;
271 inode->i_mode = le16_to_cpu(get_unaligned(&sd_lw->mode));
272 inode->i_nlink = le32_to_cpu(get_unaligned(&sd_lw->nlink));
273 inode->i_size = le64_to_cpu(get_unaligned(&sd_lw->size));
274 if ((inode->i_mode & S_IFMT) == (S_IFREG | S_IFIFO)) {
275 inode->i_mode &= ~S_IFIFO;
276 warning("", "partially converted file is encountered");
277 reiser4_inode_set_flag(inode, REISER4_PART_MIXED);
279 move_on(len, area, sizeof *sd_lw);
280 return 0;
281 } else
282 return not_enough_space(inode, "lw sd");
285 static int save_len_lw_sd(struct inode *inode UNUSED_ARG /* object being
286 * processed */ )
288 return sizeof(reiser4_light_weight_stat);
291 static int save_lw_sd(struct inode *inode /* object being processed */ ,
292 char **area /* position in stat-data */ )
294 reiser4_light_weight_stat *sd;
295 mode_t delta;
297 assert("nikita-2705", inode != NULL);
298 assert("nikita-2706", area != NULL);
299 assert("nikita-2707", *area != NULL);
301 sd = (reiser4_light_weight_stat *) * area;
303 delta = (reiser4_inode_get_flag(inode,
304 REISER4_PART_MIXED) ? S_IFIFO : 0);
305 put_unaligned(cpu_to_le16(inode->i_mode | delta), &sd->mode);
306 put_unaligned(cpu_to_le32(inode->i_nlink), &sd->nlink);
307 put_unaligned(cpu_to_le64((__u64) inode->i_size), &sd->size);
308 *area += sizeof *sd;
309 return 0;
312 static int present_unix_sd(struct inode *inode /* object being processed */ ,
313 char **area /* position in stat-data */ ,
314 int *len /* remaining length */ )
316 assert("nikita-637", inode != NULL);
317 assert("nikita-638", area != NULL);
318 assert("nikita-639", *area != NULL);
319 assert("nikita-640", len != NULL);
320 assert("nikita-641", *len > 0);
322 if (*len >= (int)sizeof(reiser4_unix_stat)) {
323 reiser4_unix_stat *sd;
325 sd = (reiser4_unix_stat *) * area;
327 inode->i_uid = le32_to_cpu(get_unaligned(&sd->uid));
328 inode->i_gid = le32_to_cpu(get_unaligned(&sd->gid));
329 inode->i_atime.tv_sec = le32_to_cpu(get_unaligned(&sd->atime));
330 inode->i_mtime.tv_sec = le32_to_cpu(get_unaligned(&sd->mtime));
331 inode->i_ctime.tv_sec = le32_to_cpu(get_unaligned(&sd->ctime));
332 if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode))
333 inode->i_rdev = le64_to_cpu(get_unaligned(&sd->u.rdev));
334 else
335 inode_set_bytes(inode, (loff_t) le64_to_cpu(get_unaligned(&sd->u.bytes)));
336 move_on(len, area, sizeof *sd);
337 return 0;
338 } else
339 return not_enough_space(inode, "unix sd");
342 static int absent_unix_sd(struct inode *inode /* object being processed */ )
344 inode->i_uid = get_super_private(inode->i_sb)->default_uid;
345 inode->i_gid = get_super_private(inode->i_sb)->default_gid;
346 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
347 inode_set_bytes(inode, inode->i_size);
348 /* mark inode as lightweight, so that caller (lookup_common) will
349 complete initialisation by copying [ug]id from a parent. */
350 reiser4_inode_set_flag(inode, REISER4_LIGHT_WEIGHT);
351 return 0;
354 /* Audited by: green(2002.06.14) */
355 static int save_len_unix_sd(struct inode *inode UNUSED_ARG /* object being
356 * processed */ )
358 return sizeof(reiser4_unix_stat);
361 static int save_unix_sd(struct inode *inode /* object being processed */ ,
362 char **area /* position in stat-data */ )
364 reiser4_unix_stat *sd;
366 assert("nikita-642", inode != NULL);
367 assert("nikita-643", area != NULL);
368 assert("nikita-644", *area != NULL);
370 sd = (reiser4_unix_stat *) * area;
371 put_unaligned(cpu_to_le32(inode->i_uid), &sd->uid);
372 put_unaligned(cpu_to_le32(inode->i_gid), &sd->gid);
373 put_unaligned(cpu_to_le32((__u32) inode->i_atime.tv_sec), &sd->atime);
374 put_unaligned(cpu_to_le32((__u32) inode->i_ctime.tv_sec), &sd->ctime);
375 put_unaligned(cpu_to_le32((__u32) inode->i_mtime.tv_sec), &sd->mtime);
376 if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode))
377 put_unaligned(cpu_to_le64(inode->i_rdev), &sd->u.rdev);
378 else
379 put_unaligned(cpu_to_le64((__u64) inode_get_bytes(inode)), &sd->u.bytes);
380 *area += sizeof *sd;
381 return 0;
384 static int
385 present_large_times_sd(struct inode *inode /* object being processed */ ,
386 char **area /* position in stat-data */ ,
387 int *len /* remaining length */ )
389 if (*len >= (int)sizeof(reiser4_large_times_stat)) {
390 reiser4_large_times_stat *sd_lt;
392 sd_lt = (reiser4_large_times_stat *) * area;
394 inode->i_atime.tv_nsec = le32_to_cpu(get_unaligned(&sd_lt->atime));
395 inode->i_mtime.tv_nsec = le32_to_cpu(get_unaligned(&sd_lt->mtime));
396 inode->i_ctime.tv_nsec = le32_to_cpu(get_unaligned(&sd_lt->ctime));
398 move_on(len, area, sizeof *sd_lt);
399 return 0;
400 } else
401 return not_enough_space(inode, "large times sd");
404 static int
405 save_len_large_times_sd(struct inode *inode UNUSED_ARG
406 /* object being processed */ )
408 return sizeof(reiser4_large_times_stat);
411 static int
412 save_large_times_sd(struct inode *inode /* object being processed */ ,
413 char **area /* position in stat-data */ )
415 reiser4_large_times_stat *sd;
417 assert("nikita-2817", inode != NULL);
418 assert("nikita-2818", area != NULL);
419 assert("nikita-2819", *area != NULL);
421 sd = (reiser4_large_times_stat *) * area;
423 put_unaligned(cpu_to_le32((__u32) inode->i_atime.tv_nsec), &sd->atime);
424 put_unaligned(cpu_to_le32((__u32) inode->i_ctime.tv_nsec), &sd->ctime);
425 put_unaligned(cpu_to_le32((__u32) inode->i_mtime.tv_nsec), &sd->mtime);
427 *area += sizeof *sd;
428 return 0;
431 /* symlink stat data extension */
433 /* allocate memory for symlink target and attach it to inode->i_private */
434 static int
435 symlink_target_to_inode(struct inode *inode, const char *target, int len)
437 assert("vs-845", inode->i_private == NULL);
438 assert("vs-846", !reiser4_inode_get_flag(inode,
439 REISER4_GENERIC_PTR_USED));
440 /* FIXME-VS: this is prone to deadlock. Not more than other similar
441 places, though */
442 inode->i_private = kmalloc((size_t) len + 1,
443 reiser4_ctx_gfp_mask_get());
444 if (!inode->i_private)
445 return RETERR(-ENOMEM);
447 memcpy((char *)(inode->i_private), target, (size_t) len);
448 ((char *)(inode->i_private))[len] = 0;
449 reiser4_inode_set_flag(inode, REISER4_GENERIC_PTR_USED);
450 return 0;
453 /* this is called on read_inode. There is nothing to do actually, but some
454 sanity checks */
455 static int present_symlink_sd(struct inode *inode, char **area, int *len)
457 int result;
458 int length;
459 reiser4_symlink_stat *sd;
461 length = (int)inode->i_size;
463 * *len is number of bytes in stat data item from *area to the end of
464 * item. It must be not less than size of symlink + 1 for ending 0
466 if (length > *len)
467 return not_enough_space(inode, "symlink");
469 if (*(*area + length) != 0) {
470 warning("vs-840", "Symlink is not zero terminated");
471 return RETERR(-EIO);
474 sd = (reiser4_symlink_stat *) * area;
475 result = symlink_target_to_inode(inode, sd->body, length);
477 move_on(len, area, length + 1);
478 return result;
481 static int save_len_symlink_sd(struct inode *inode)
483 return inode->i_size + 1;
486 /* this is called on create and update stat data. Do nothing on update but
487 update @area */
488 static int save_symlink_sd(struct inode *inode, char **area)
490 int result;
491 int length;
492 reiser4_symlink_stat *sd;
494 length = (int)inode->i_size;
495 /* inode->i_size must be set already */
496 assert("vs-841", length);
498 result = 0;
499 sd = (reiser4_symlink_stat *) * area;
500 if (!reiser4_inode_get_flag(inode, REISER4_GENERIC_PTR_USED)) {
501 const char *target;
503 target = (const char *)(inode->i_private);
504 inode->i_private = NULL;
506 result = symlink_target_to_inode(inode, target, length);
508 /* copy symlink to stat data */
509 memcpy(sd->body, target, (size_t) length);
510 (*area)[length] = 0;
511 } else {
512 /* there is nothing to do in update but move area */
513 assert("vs-844",
514 !memcmp(inode->i_private, sd->body,
515 (size_t) length + 1));
518 *area += (length + 1);
519 return result;
522 static int present_flags_sd(struct inode *inode /* object being processed */ ,
523 char **area /* position in stat-data */ ,
524 int *len /* remaining length */ )
526 assert("nikita-645", inode != NULL);
527 assert("nikita-646", area != NULL);
528 assert("nikita-647", *area != NULL);
529 assert("nikita-648", len != NULL);
530 assert("nikita-649", *len > 0);
532 if (*len >= (int)sizeof(reiser4_flags_stat)) {
533 reiser4_flags_stat *sd;
535 sd = (reiser4_flags_stat *) * area;
536 inode->i_flags = le32_to_cpu(get_unaligned(&sd->flags));
537 move_on(len, area, sizeof *sd);
538 return 0;
539 } else
540 return not_enough_space(inode, "generation and attrs");
543 /* Audited by: green(2002.06.14) */
544 static int save_len_flags_sd(struct inode *inode UNUSED_ARG /* object being
545 * processed */ )
547 return sizeof(reiser4_flags_stat);
550 static int save_flags_sd(struct inode *inode /* object being processed */ ,
551 char **area /* position in stat-data */ )
553 reiser4_flags_stat *sd;
555 assert("nikita-650", inode != NULL);
556 assert("nikita-651", area != NULL);
557 assert("nikita-652", *area != NULL);
559 sd = (reiser4_flags_stat *) * area;
560 put_unaligned(cpu_to_le32(inode->i_flags), &sd->flags);
561 *area += sizeof *sd;
562 return 0;
565 static int absent_plugin_sd(struct inode *inode);
566 static int present_plugin_sd(struct inode *inode /* object being processed */ ,
567 char **area /* position in stat-data */ ,
568 int *len /* remaining length */,
569 int is_pset /* 1 if plugin set, 0 if heir set. */)
571 reiser4_plugin_stat *sd;
572 reiser4_plugin *plugin;
573 reiser4_inode *info;
574 int i;
575 __u16 mask;
576 int result;
577 int num_of_plugins;
579 assert("nikita-653", inode != NULL);
580 assert("nikita-654", area != NULL);
581 assert("nikita-655", *area != NULL);
582 assert("nikita-656", len != NULL);
583 assert("nikita-657", *len > 0);
585 if (*len < (int)sizeof(reiser4_plugin_stat))
586 return not_enough_space(inode, "plugin");
588 sd = (reiser4_plugin_stat *) * area;
589 info = reiser4_inode_data(inode);
591 mask = 0;
592 num_of_plugins = le16_to_cpu(get_unaligned(&sd->plugins_no));
593 move_on(len, area, sizeof *sd);
594 result = 0;
595 for (i = 0; i < num_of_plugins; ++i) {
596 reiser4_plugin_slot *slot;
597 reiser4_plugin_type type;
598 pset_member memb;
600 slot = (reiser4_plugin_slot *) * area;
601 if (*len < (int)sizeof *slot)
602 return not_enough_space(inode, "additional plugin");
604 memb = le16_to_cpu(get_unaligned(&slot->pset_memb));
605 type = aset_member_to_type_unsafe(memb);
607 if (type == REISER4_PLUGIN_TYPES) {
608 warning("nikita-3502",
609 "wrong %s member (%i) for %llu", is_pset ?
610 "pset" : "hset", memb,
611 (unsigned long long)get_inode_oid(inode));
612 return RETERR(-EINVAL);
614 plugin = plugin_by_disk_id(reiser4_tree_by_inode(inode),
615 type, &slot->id);
616 if (plugin == NULL)
617 return unknown_plugin(le16_to_cpu(get_unaligned(&slot->id)), inode);
619 /* plugin is loaded into inode, mark this into inode's
620 bitmask of loaded non-standard plugins */
621 if (!(mask & (1 << memb))) {
622 mask |= (1 << memb);
623 } else {
624 warning("nikita-658", "duplicate plugin for %llu",
625 (unsigned long long)get_inode_oid(inode));
626 return RETERR(-EINVAL);
628 move_on(len, area, sizeof *slot);
629 /* load plugin data, if any */
630 if (plugin->h.pops != NULL && plugin->h.pops->load)
631 result = plugin->h.pops->load(inode, plugin, area, len);
632 else
633 result = aset_set_unsafe(is_pset ? &info->pset :
634 &info->hset, memb, plugin);
635 if (result)
636 return result;
638 if (is_pset) {
639 /* if object plugin wasn't loaded from stat-data, guess it by
640 mode bits */
641 plugin = file_plugin_to_plugin(inode_file_plugin(inode));
642 if (plugin == NULL)
643 result = absent_plugin_sd(inode);
644 info->plugin_mask = mask;
645 } else
646 info->heir_mask = mask;
648 return result;
651 static int present_pset_sd(struct inode *inode, char **area, int *len) {
652 return present_plugin_sd(inode, area, len, 1 /* pset */);
655 /* Determine object plugin for @inode based on i_mode.
657 Many objects in reiser4 file system are controlled by standard object
658 plugins that emulate traditional unix objects: unix file, directory, symlink, fifo, and so on.
660 For such files we don't explicitly store plugin id in object stat
661 data. Rather required plugin is guessed from mode bits, where file "type"
662 is encoded (see stat(2)).
664 static int
665 guess_plugin_by_mode(struct inode *inode /* object to guess plugins for */ )
667 int fplug_id;
668 int dplug_id;
669 reiser4_inode *info;
671 assert("nikita-736", inode != NULL);
673 dplug_id = fplug_id = -1;
675 switch (inode->i_mode & S_IFMT) {
676 case S_IFSOCK:
677 case S_IFBLK:
678 case S_IFCHR:
679 case S_IFIFO:
680 fplug_id = SPECIAL_FILE_PLUGIN_ID;
681 break;
682 case S_IFLNK:
683 fplug_id = SYMLINK_FILE_PLUGIN_ID;
684 break;
685 case S_IFDIR:
686 fplug_id = DIRECTORY_FILE_PLUGIN_ID;
687 dplug_id = HASHED_DIR_PLUGIN_ID;
688 break;
689 default:
690 warning("nikita-737", "wrong file mode: %o", inode->i_mode);
691 return RETERR(-EIO);
692 case S_IFREG:
693 fplug_id = UNIX_FILE_PLUGIN_ID;
694 break;
696 info = reiser4_inode_data(inode);
697 set_plugin(&info->pset, PSET_FILE, (fplug_id >= 0) ?
698 plugin_by_id(REISER4_FILE_PLUGIN_TYPE, fplug_id) : NULL);
699 set_plugin(&info->pset, PSET_DIR, (dplug_id >= 0) ?
700 plugin_by_id(REISER4_DIR_PLUGIN_TYPE, dplug_id) : NULL);
701 return 0;
704 /* Audited by: green(2002.06.14) */
705 static int absent_plugin_sd(struct inode *inode /* object being processed */ )
707 int result;
709 assert("nikita-659", inode != NULL);
711 result = guess_plugin_by_mode(inode);
712 /* if mode was wrong, guess_plugin_by_mode() returns "regular file",
713 but setup_inode_ops() will call make_bad_inode().
714 Another, more logical but bit more complex solution is to add
715 "bad-file plugin". */
716 /* FIXME-VS: activate was called here */
717 return result;
720 /* helper function for plugin_sd_save_len(): calculate how much space
721 required to save state of given plugin */
722 /* Audited by: green(2002.06.14) */
723 static int len_for(reiser4_plugin * plugin /* plugin to save */ ,
724 struct inode *inode /* object being processed */ ,
725 pset_member memb,
726 int len, int is_pset)
728 reiser4_inode *info;
729 assert("nikita-661", inode != NULL);
731 if (plugin == NULL)
732 return len;
734 info = reiser4_inode_data(inode);
735 if (is_pset ?
736 info->plugin_mask & (1 << memb) :
737 info->heir_mask & (1 << memb)) {
738 len += sizeof(reiser4_plugin_slot);
739 if (plugin->h.pops && plugin->h.pops->save_len != NULL) {
740 /* non-standard plugin, call method */
741 /* commented as it is incompatible with alignment
742 * policy in save_plug() -edward */
743 /* len = round_up(len, plugin->h.pops->alignment); */
744 len += plugin->h.pops->save_len(inode, plugin);
747 return len;
750 /* calculate how much space is required to save state of all plugins,
751 associated with inode */
752 static int save_len_plugin_sd(struct inode *inode /* object being processed */,
753 int is_pset)
755 int len;
756 int last;
757 reiser4_inode *state;
758 pset_member memb;
760 assert("nikita-663", inode != NULL);
762 state = reiser4_inode_data(inode);
764 /* common case: no non-standard plugins */
765 if (is_pset ? state->plugin_mask == 0 : state->heir_mask == 0)
766 return 0;
767 len = sizeof(reiser4_plugin_stat);
768 last = PSET_LAST;
770 for (memb = 0; memb < last; ++memb) {
771 len = len_for(aset_get(is_pset ? state->pset : state->hset, memb),
772 inode, memb, len, is_pset);
774 assert("nikita-664", len > (int)sizeof(reiser4_plugin_stat));
775 return len;
778 static int save_len_pset_sd(struct inode *inode) {
779 return save_len_plugin_sd(inode, 1 /* pset */);
782 /* helper function for plugin_sd_save(): save plugin, associated with
783 inode. */
784 static int save_plug(reiser4_plugin * plugin /* plugin to save */ ,
785 struct inode *inode /* object being processed */ ,
786 int memb /* what element of pset is saved */ ,
787 char **area /* position in stat-data */ ,
788 int *count /* incremented if plugin were actually saved. */,
789 int is_pset /* 1 for plugin set, 0 for heir set */)
791 reiser4_plugin_slot *slot;
792 int fake_len;
793 int result;
795 assert("nikita-665", inode != NULL);
796 assert("nikita-666", area != NULL);
797 assert("nikita-667", *area != NULL);
799 if (plugin == NULL)
800 return 0;
802 if (is_pset ?
803 !(reiser4_inode_data(inode)->plugin_mask & (1 << memb)) :
804 !(reiser4_inode_data(inode)->heir_mask & (1 << memb)))
805 return 0;
806 slot = (reiser4_plugin_slot *) * area;
807 put_unaligned(cpu_to_le16(memb), &slot->pset_memb);
808 put_unaligned(cpu_to_le16(plugin->h.id), &slot->id);
809 fake_len = (int)0xffff;
810 move_on(&fake_len, area, sizeof *slot);
811 ++*count;
812 result = 0;
813 if (plugin->h.pops != NULL) {
814 if (plugin->h.pops->save != NULL)
815 result = plugin->h.pops->save(inode, plugin, area);
817 return result;
820 /* save state of all non-standard plugins associated with inode */
821 static int save_plugin_sd(struct inode *inode /* object being processed */ ,
822 char **area /* position in stat-data */,
823 int is_pset /* 1 for pset, 0 for hset */)
825 int fake_len;
826 int result = 0;
827 int num_of_plugins;
828 reiser4_plugin_stat *sd;
829 reiser4_inode *state;
830 pset_member memb;
832 assert("nikita-669", inode != NULL);
833 assert("nikita-670", area != NULL);
834 assert("nikita-671", *area != NULL);
836 state = reiser4_inode_data(inode);
837 if (is_pset ? state->plugin_mask == 0 : state->heir_mask == 0)
838 return 0;
839 sd = (reiser4_plugin_stat *) * area;
840 fake_len = (int)0xffff;
841 move_on(&fake_len, area, sizeof *sd);
843 num_of_plugins = 0;
844 for (memb = 0; memb < PSET_LAST; ++memb) {
845 result = save_plug(aset_get(is_pset ? state->pset : state->hset,
846 memb),
847 inode, memb, area, &num_of_plugins, is_pset);
848 if (result != 0)
849 break;
852 put_unaligned(cpu_to_le16((__u16)num_of_plugins), &sd->plugins_no);
853 return result;
856 static int save_pset_sd(struct inode *inode, char **area) {
857 return save_plugin_sd(inode, area, 1 /* pset */);
860 static int present_hset_sd(struct inode *inode, char **area, int *len) {
861 return present_plugin_sd(inode, area, len, 0 /* hset */);
864 static int save_len_hset_sd(struct inode *inode) {
865 return save_len_plugin_sd(inode, 0 /* pset */);
868 static int save_hset_sd(struct inode *inode, char **area) {
869 return save_plugin_sd(inode, area, 0 /* hset */);
872 /* helper function for crypto_sd_present(), crypto_sd_save.
873 Extract crypto info from stat-data and attach it to inode */
874 static int extract_crypto_info (struct inode * inode,
875 reiser4_crypto_stat * sd)
877 struct reiser4_crypto_info * info;
878 assert("edward-11", !inode_crypto_info(inode));
879 assert("edward-1413",
880 !reiser4_inode_get_flag(inode, REISER4_CRYPTO_STAT_LOADED));
881 /* create and attach a crypto-stat without secret key loaded */
882 info = reiser4_alloc_crypto_info(inode);
883 if (IS_ERR(info))
884 return PTR_ERR(info);
885 info->keysize = le16_to_cpu(get_unaligned(&sd->keysize));
886 memcpy(info->keyid, sd->keyid, inode_digest_plugin(inode)->fipsize);
887 reiser4_attach_crypto_info(inode, info);
888 reiser4_inode_set_flag(inode, REISER4_CRYPTO_STAT_LOADED);
889 return 0;
892 /* crypto stat-data extension */
894 static int present_crypto_sd(struct inode *inode, char **area, int *len)
896 int result;
897 reiser4_crypto_stat *sd;
898 digest_plugin *dplug = inode_digest_plugin(inode);
900 assert("edward-06", dplug != NULL);
901 assert("edward-684", dplug->fipsize);
902 assert("edward-07", area != NULL);
903 assert("edward-08", *area != NULL);
904 assert("edward-09", len != NULL);
905 assert("edward-10", *len > 0);
907 if (*len < (int)sizeof(reiser4_crypto_stat)) {
908 return not_enough_space(inode, "crypto-sd");
910 /* *len is number of bytes in stat data item from *area to the end of
911 item. It must be not less than size of this extension */
912 assert("edward-75", sizeof(*sd) + dplug->fipsize <= *len);
914 sd = (reiser4_crypto_stat *) * area;
915 result = extract_crypto_info(inode, sd);
916 move_on(len, area, sizeof(*sd) + dplug->fipsize);
918 return result;
921 static int save_len_crypto_sd(struct inode *inode)
923 return sizeof(reiser4_crypto_stat) +
924 inode_digest_plugin(inode)->fipsize;
927 static int save_crypto_sd(struct inode *inode, char **area)
929 int result = 0;
930 reiser4_crypto_stat *sd;
931 struct reiser4_crypto_info * info = inode_crypto_info(inode);
932 digest_plugin *dplug = inode_digest_plugin(inode);
934 assert("edward-12", dplug != NULL);
935 assert("edward-13", area != NULL);
936 assert("edward-14", *area != NULL);
937 assert("edward-15", info != NULL);
938 assert("edward-1414", info->keyid != NULL);
939 assert("edward-1415", info->keysize != 0);
940 assert("edward-76", reiser4_inode_data(inode) != NULL);
942 if (!reiser4_inode_get_flag(inode, REISER4_CRYPTO_STAT_LOADED)) {
943 /* file is just created */
944 sd = (reiser4_crypto_stat *) *area;
945 /* copy everything but private key to the disk stat-data */
946 put_unaligned(cpu_to_le16(info->keysize), &sd->keysize);
947 memcpy(sd->keyid, info->keyid, (size_t) dplug->fipsize);
948 reiser4_inode_set_flag(inode, REISER4_CRYPTO_STAT_LOADED);
950 *area += (sizeof(*sd) + dplug->fipsize);
951 return result;
954 static int eio(struct inode *inode, char **area, int *len)
956 return RETERR(-EIO);
959 sd_ext_plugin sd_ext_plugins[LAST_SD_EXTENSION] = {
960 [LIGHT_WEIGHT_STAT] = {
961 .h = {
962 .type_id = REISER4_SD_EXT_PLUGIN_TYPE,
963 .id = LIGHT_WEIGHT_STAT,
964 .pops = NULL,
965 .label = "light-weight sd",
966 .desc = "sd for light-weight files",
967 .linkage = {NULL,NULL}
969 .present = present_lw_sd,
970 .absent = NULL,
971 .save_len = save_len_lw_sd,
972 .save = save_lw_sd,
973 .alignment = 8
975 [UNIX_STAT] = {
976 .h = {
977 .type_id = REISER4_SD_EXT_PLUGIN_TYPE,
978 .id = UNIX_STAT,
979 .pops = NULL,
980 .label = "unix-sd",
981 .desc = "unix stat-data fields",
982 .linkage = {NULL,NULL}
984 .present = present_unix_sd,
985 .absent = absent_unix_sd,
986 .save_len = save_len_unix_sd,
987 .save = save_unix_sd,
988 .alignment = 8
990 [LARGE_TIMES_STAT] = {
991 .h = {
992 .type_id = REISER4_SD_EXT_PLUGIN_TYPE,
993 .id = LARGE_TIMES_STAT,
994 .pops = NULL,
995 .label = "64time-sd",
996 .desc = "nanosecond resolution for times",
997 .linkage = {NULL,NULL}
999 .present = present_large_times_sd,
1000 .absent = NULL,
1001 .save_len = save_len_large_times_sd,
1002 .save = save_large_times_sd,
1003 .alignment = 8
1005 [SYMLINK_STAT] = {
1006 /* stat data of symlink has this extension */
1007 .h = {
1008 .type_id = REISER4_SD_EXT_PLUGIN_TYPE,
1009 .id = SYMLINK_STAT,
1010 .pops = NULL,
1011 .label = "symlink-sd",
1012 .desc =
1013 "stat data is appended with symlink name",
1014 .linkage = {NULL,NULL}
1016 .present = present_symlink_sd,
1017 .absent = NULL,
1018 .save_len = save_len_symlink_sd,
1019 .save = save_symlink_sd,
1020 .alignment = 8
1022 [PLUGIN_STAT] = {
1023 .h = {
1024 .type_id = REISER4_SD_EXT_PLUGIN_TYPE,
1025 .id = PLUGIN_STAT,
1026 .pops = NULL,
1027 .label = "plugin-sd",
1028 .desc = "plugin stat-data fields",
1029 .linkage = {NULL,NULL}
1031 .present = present_pset_sd,
1032 .absent = absent_plugin_sd,
1033 .save_len = save_len_pset_sd,
1034 .save = save_pset_sd,
1035 .alignment = 8
1037 [HEIR_STAT] = {
1038 .h = {
1039 .type_id = REISER4_SD_EXT_PLUGIN_TYPE,
1040 .id = HEIR_STAT,
1041 .pops = NULL,
1042 .label = "heir-plugin-sd",
1043 .desc = "heir plugin stat-data fields",
1044 .linkage = {NULL,NULL}
1046 .present = present_hset_sd,
1047 .absent = NULL,
1048 .save_len = save_len_hset_sd,
1049 .save = save_hset_sd,
1050 .alignment = 8
1052 [FLAGS_STAT] = {
1053 .h = {
1054 .type_id = REISER4_SD_EXT_PLUGIN_TYPE,
1055 .id = FLAGS_STAT,
1056 .pops = NULL,
1057 .label = "flags-sd",
1058 .desc = "inode bit flags",
1059 .linkage = {NULL, NULL}
1061 .present = present_flags_sd,
1062 .absent = NULL,
1063 .save_len = save_len_flags_sd,
1064 .save = save_flags_sd,
1065 .alignment = 8
1067 [CAPABILITIES_STAT] = {
1068 .h = {
1069 .type_id = REISER4_SD_EXT_PLUGIN_TYPE,
1070 .id = CAPABILITIES_STAT,
1071 .pops = NULL,
1072 .label = "capabilities-sd",
1073 .desc = "capabilities",
1074 .linkage = {NULL, NULL}
1076 .present = eio,
1077 .absent = NULL,
1078 .save_len = save_len_flags_sd,
1079 .save = save_flags_sd,
1080 .alignment = 8
1082 [CRYPTO_STAT] = {
1083 .h = {
1084 .type_id = REISER4_SD_EXT_PLUGIN_TYPE,
1085 .id = CRYPTO_STAT,
1086 .pops = NULL,
1087 .label = "crypto-sd",
1088 .desc = "secret key size and id",
1089 .linkage = {NULL, NULL}
1091 .present = present_crypto_sd,
1092 .absent = NULL,
1093 .save_len = save_len_crypto_sd,
1094 .save = save_crypto_sd,
1095 .alignment = 8
1099 /* Make Linus happy.
1100 Local variables:
1101 c-indentation-style: "K&R"
1102 mode-name: "LC"
1103 c-basic-offset: 8
1104 tab-width: 8
1105 fill-column: 120
1106 End: