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"
17 #include <linux/types.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
);
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. */
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 */ )
77 reiser4_stat_data_base
*sd_base
;
80 assert("nikita-625", inode
!= NULL
);
81 assert("nikita-626", sd
!= NULL
);
84 sd_base
= (reiser4_stat_data_base
*) sd
;
85 state
= reiser4_inode_data(inode
);
86 mask
= le16_to_cpu(get_unaligned(&sd_base
->extmask
));
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
;
94 if (((bit
+ 1) % 16) != 0) {
95 /* handle extension */
96 sd_ext_plugin
*sdplug
;
98 if (bit
>= LAST_SD_EXTENSION
) {
100 "No such extension %i in inode %llu",
103 get_inode_oid(inode
));
105 result
= RETERR(-EINVAL
);
109 sdplug
= sd_ext_plugin_by_id(bit
);
110 if (sdplug
== NULL
) {
111 warning("nikita-627",
112 "No such extension %i in inode %llu",
115 get_inode_oid(inode
));
117 result
= RETERR(-EINVAL
);
121 assert("nikita-628", sdplug
->present
);
122 /* alignment is not supported in node layout
124 result = align( inode, &len, &sd,
125 sdplug -> alignment );
128 result
= sdplug
->present(inode
, &sd
, &len
);
129 } else if (sdplug
->absent
!= NULL
)
130 result
= sdplug
->absent(inode
);
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",
141 get_inode_oid(inode
));
143 result
= RETERR(-EINVAL
);
146 mask
= le16_to_cpu(get_unaligned((d16
*)sd
));
149 move_on(&len
, &sd
, sizeof(d16
));
152 if (!(mask
& 0x8000)) {
158 warning("nikita-630",
159 "Too many extensions in %llu",
161 get_inode_oid(inode
));
163 result
= RETERR(-EINVAL
);
167 /* bitmask exhausted */
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
175 warning("nikita-631", "unused space in inode %llu",
176 (unsigned long long)get_inode_oid(inode
));
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). */
186 int save_len_static_sd(struct inode
*inode
/* object being processed */ )
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) {
198 sd_ext_plugin
*sdplug
;
200 sdplug
= sd_ext_plugin_by_id(bit
);
201 assert("nikita-633", sdplug
!= NULL
);
202 /* no aligment support
204 round_up( result, sdplug -> alignment ) - result; */
205 result
+= sdplug
->save_len(inode
);
208 result
+= bit
/ 16 * sizeof(d16
);
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). */
216 int save_static_sd(struct inode
*inode
/* object being processed */ ,
217 char **area
/* where to save stat-data */ )
223 reiser4_stat_data_base
*sd_base
;
225 assert("nikita-634", inode
!= NULL
);
226 assert("nikita-635", area
!= NULL
);
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
;
236 for (bit
= 0; emask
!= 0; ++bit
, 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
);
249 put_unaligned(cpu_to_le16((__u16
)(emask
& 0xffff)),
251 /*cputod16((unsigned)(emask & 0xffff),
253 *area
+= sizeof(d16
);
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
);
282 return not_enough_space(inode
, "lw sd");
285 static int save_len_lw_sd(struct inode
*inode UNUSED_ARG
/* object being
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
;
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
);
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
));
335 inode_set_bytes(inode
, (loff_t
) le64_to_cpu(get_unaligned(&sd
->u
.bytes
)));
336 move_on(len
, area
, sizeof *sd
);
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
);
354 /* Audited by: green(2002.06.14) */
355 static int save_len_unix_sd(struct inode
*inode UNUSED_ARG
/* object being
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
);
379 put_unaligned(cpu_to_le64((__u64
) inode_get_bytes(inode
)), &sd
->u
.bytes
);
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
);
401 return not_enough_space(inode
, "large times sd");
405 save_len_large_times_sd(struct inode
*inode UNUSED_ARG
406 /* object being processed */ )
408 return sizeof(reiser4_large_times_stat
);
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
);
431 /* symlink stat data extension */
433 /* allocate memory for symlink target and attach it to inode->i_private */
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
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
);
453 /* this is called on read_inode. There is nothing to do actually, but some
455 static int present_symlink_sd(struct inode
*inode
, char **area
, int *len
)
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
467 return not_enough_space(inode
, "symlink");
469 if (*(*area
+ length
) != 0) {
470 warning("vs-840", "Symlink is not zero terminated");
474 sd
= (reiser4_symlink_stat
*) * area
;
475 result
= symlink_target_to_inode(inode
, sd
->body
, length
);
477 move_on(len
, area
, length
+ 1);
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
488 static int save_symlink_sd(struct inode
*inode
, char **area
)
492 reiser4_symlink_stat
*sd
;
494 length
= (int)inode
->i_size
;
495 /* inode->i_size must be set already */
496 assert("vs-841", length
);
499 sd
= (reiser4_symlink_stat
*) * area
;
500 if (!reiser4_inode_get_flag(inode
, REISER4_GENERIC_PTR_USED
)) {
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
);
512 /* there is nothing to do in update but move area */
514 !memcmp(inode
->i_private
, sd
->body
,
515 (size_t) length
+ 1));
518 *area
+= (length
+ 1);
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
);
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
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
);
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
;
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
);
592 num_of_plugins
= le16_to_cpu(get_unaligned(&sd
->plugins_no
));
593 move_on(len
, area
, sizeof *sd
);
595 for (i
= 0; i
< num_of_plugins
; ++i
) {
596 reiser4_plugin_slot
*slot
;
597 reiser4_plugin_type type
;
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
),
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
))) {
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
);
633 result
= aset_set_unsafe(is_pset
? &info
->pset
:
634 &info
->hset
, memb
, plugin
);
639 /* if object plugin wasn't loaded from stat-data, guess it by
641 plugin
= file_plugin_to_plugin(inode_file_plugin(inode
));
643 result
= absent_plugin_sd(inode
);
644 info
->plugin_mask
= mask
;
646 info
->heir_mask
= mask
;
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)).
665 guess_plugin_by_mode(struct inode
*inode
/* object to guess plugins for */ )
671 assert("nikita-736", inode
!= NULL
);
673 dplug_id
= fplug_id
= -1;
675 switch (inode
->i_mode
& S_IFMT
) {
680 fplug_id
= SPECIAL_FILE_PLUGIN_ID
;
683 fplug_id
= SYMLINK_FILE_PLUGIN_ID
;
686 fplug_id
= DIRECTORY_FILE_PLUGIN_ID
;
687 dplug_id
= HASHED_DIR_PLUGIN_ID
;
690 warning("nikita-737", "wrong file mode: %o", inode
->i_mode
);
693 fplug_id
= UNIX_FILE_PLUGIN_ID
;
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
);
704 /* Audited by: green(2002.06.14) */
705 static int absent_plugin_sd(struct inode
*inode
/* object being processed */ )
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 */
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 */ ,
726 int len
, int is_pset
)
729 assert("nikita-661", inode
!= NULL
);
734 info
= reiser4_inode_data(inode
);
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
);
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 */,
757 reiser4_inode
*state
;
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)
767 len
= sizeof(reiser4_plugin_stat
);
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
));
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
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
;
795 assert("nikita-665", inode
!= NULL
);
796 assert("nikita-666", area
!= NULL
);
797 assert("nikita-667", *area
!= NULL
);
803 !(reiser4_inode_data(inode
)->plugin_mask
& (1 << memb
)) :
804 !(reiser4_inode_data(inode
)->heir_mask
& (1 << memb
)))
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
);
813 if (plugin
->h
.pops
!= NULL
) {
814 if (plugin
->h
.pops
->save
!= NULL
)
815 result
= plugin
->h
.pops
->save(inode
, plugin
, area
);
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 */)
828 reiser4_plugin_stat
*sd
;
829 reiser4_inode
*state
;
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)
839 sd
= (reiser4_plugin_stat
*) * area
;
840 fake_len
= (int)0xffff;
841 move_on(&fake_len
, area
, sizeof *sd
);
844 for (memb
= 0; memb
< PSET_LAST
; ++memb
) {
845 result
= save_plug(aset_get(is_pset
? state
->pset
: state
->hset
,
847 inode
, memb
, area
, &num_of_plugins
, is_pset
);
852 put_unaligned(cpu_to_le16((__u16
)num_of_plugins
), &sd
->plugins_no
);
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
);
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
);
892 /* crypto stat-data extension */
894 static int present_crypto_sd(struct inode
*inode
, char **area
, int *len
)
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
);
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
)
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
);
954 static int eio(struct inode
*inode
, char **area
, int *len
)
959 sd_ext_plugin sd_ext_plugins
[LAST_SD_EXTENSION
] = {
960 [LIGHT_WEIGHT_STAT
] = {
962 .type_id
= REISER4_SD_EXT_PLUGIN_TYPE
,
963 .id
= LIGHT_WEIGHT_STAT
,
965 .label
= "light-weight sd",
966 .desc
= "sd for light-weight files",
967 .linkage
= {NULL
,NULL
}
969 .present
= present_lw_sd
,
971 .save_len
= save_len_lw_sd
,
977 .type_id
= REISER4_SD_EXT_PLUGIN_TYPE
,
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
,
990 [LARGE_TIMES_STAT
] = {
992 .type_id
= REISER4_SD_EXT_PLUGIN_TYPE
,
993 .id
= LARGE_TIMES_STAT
,
995 .label
= "64time-sd",
996 .desc
= "nanosecond resolution for times",
997 .linkage
= {NULL
,NULL
}
999 .present
= present_large_times_sd
,
1001 .save_len
= save_len_large_times_sd
,
1002 .save
= save_large_times_sd
,
1006 /* stat data of symlink has this extension */
1008 .type_id
= REISER4_SD_EXT_PLUGIN_TYPE
,
1011 .label
= "symlink-sd",
1013 "stat data is appended with symlink name",
1014 .linkage
= {NULL
,NULL
}
1016 .present
= present_symlink_sd
,
1018 .save_len
= save_len_symlink_sd
,
1019 .save
= save_symlink_sd
,
1024 .type_id
= REISER4_SD_EXT_PLUGIN_TYPE
,
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
,
1039 .type_id
= REISER4_SD_EXT_PLUGIN_TYPE
,
1042 .label
= "heir-plugin-sd",
1043 .desc
= "heir plugin stat-data fields",
1044 .linkage
= {NULL
,NULL
}
1046 .present
= present_hset_sd
,
1048 .save_len
= save_len_hset_sd
,
1049 .save
= save_hset_sd
,
1054 .type_id
= REISER4_SD_EXT_PLUGIN_TYPE
,
1057 .label
= "flags-sd",
1058 .desc
= "inode bit flags",
1059 .linkage
= {NULL
, NULL
}
1061 .present
= present_flags_sd
,
1063 .save_len
= save_len_flags_sd
,
1064 .save
= save_flags_sd
,
1067 [CAPABILITIES_STAT
] = {
1069 .type_id
= REISER4_SD_EXT_PLUGIN_TYPE
,
1070 .id
= CAPABILITIES_STAT
,
1072 .label
= "capabilities-sd",
1073 .desc
= "capabilities",
1074 .linkage
= {NULL
, NULL
}
1078 .save_len
= save_len_flags_sd
,
1079 .save
= save_flags_sd
,
1084 .type_id
= REISER4_SD_EXT_PLUGIN_TYPE
,
1087 .label
= "crypto-sd",
1088 .desc
= "secret key size and id",
1089 .linkage
= {NULL
, NULL
}
1091 .present
= present_crypto_sd
,
1093 .save_len
= save_len_crypto_sd
,
1094 .save
= save_crypto_sd
,
1099 /* Make Linus happy.
1101 c-indentation-style: "K&R"