item_ops.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788
  1. /*
  2. * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
  3. */
  4. #include <linux/time.h>
  5. #include <linux/reiserfs_fs.h>
  6. // this contains item handlers for old item types: sd, direct,
  7. // indirect, directory
  8. /* and where are the comments? how about saying where we can find an
  9. explanation of each item handler method? -Hans */
  10. //////////////////////////////////////////////////////////////////////////////
  11. // stat data functions
  12. //
  13. static int sd_bytes_number (struct item_head * ih, int block_size)
  14. {
  15. return 0;
  16. }
  17. static void sd_decrement_key (struct cpu_key * key)
  18. {
  19. key->on_disk_key.k_objectid --;
  20. set_cpu_key_k_type (key, TYPE_ANY);
  21. set_cpu_key_k_offset(key, (loff_t)(-1));
  22. }
  23. static int sd_is_left_mergeable (struct reiserfs_key * key, unsigned long bsize)
  24. {
  25. return 0;
  26. }
  27. static char * print_time (time_t t)
  28. {
  29. static char timebuf[256];
  30. sprintf (timebuf, "%ld", t);
  31. return timebuf;
  32. }
  33. static void sd_print_item (struct item_head * ih, char * item)
  34. {
  35. printk ("\tmode | size | nlinks | first direct | mtime\n");
  36. if (stat_data_v1 (ih)) {
  37. struct stat_data_v1 * sd = (struct stat_data_v1 *)item;
  38. printk ("\t0%-6o | %6u | %2u | %d | %s\n", sd_v1_mode(sd),
  39. sd_v1_size(sd), sd_v1_nlink(sd), sd_v1_first_direct_byte(sd),
  40. print_time( sd_v1_mtime(sd) ) );
  41. } else {
  42. struct stat_data * sd = (struct stat_data *)item;
  43. printk ("\t0%-6o | %6Lu | %2u | %d | %s\n", sd_v2_mode(sd),
  44. (unsigned long long)sd_v2_size(sd), sd_v2_nlink(sd),
  45. sd_v2_rdev(sd), print_time(sd_v2_mtime(sd)));
  46. }
  47. }
  48. static void sd_check_item (struct item_head * ih, char * item)
  49. {
  50. // FIXME: type something here!
  51. }
  52. static int sd_create_vi (struct virtual_node * vn,
  53. struct virtual_item * vi,
  54. int is_affected,
  55. int insert_size)
  56. {
  57. vi->vi_index = TYPE_STAT_DATA;
  58. //vi->vi_type |= VI_TYPE_STAT_DATA;// not needed?
  59. return 0;
  60. }
  61. static int sd_check_left (struct virtual_item * vi, int free,
  62. int start_skip, int end_skip)
  63. {
  64. if (start_skip || end_skip)
  65. BUG ();
  66. return -1;
  67. }
  68. static int sd_check_right (struct virtual_item * vi, int free)
  69. {
  70. return -1;
  71. }
  72. static int sd_part_size (struct virtual_item * vi, int first, int count)
  73. {
  74. if (count)
  75. BUG ();
  76. return 0;
  77. }
  78. static int sd_unit_num (struct virtual_item * vi)
  79. {
  80. return vi->vi_item_len - IH_SIZE;
  81. }
  82. static void sd_print_vi (struct virtual_item * vi)
  83. {
  84. reiserfs_warning (NULL, "STATDATA, index %d, type 0x%x, %h",
  85. vi->vi_index, vi->vi_type, vi->vi_ih);
  86. }
  87. static struct item_operations stat_data_ops = {
  88. .bytes_number = sd_bytes_number,
  89. .decrement_key = sd_decrement_key,
  90. .is_left_mergeable = sd_is_left_mergeable,
  91. .print_item = sd_print_item,
  92. .check_item = sd_check_item,
  93. .create_vi = sd_create_vi,
  94. .check_left = sd_check_left,
  95. .check_right = sd_check_right,
  96. .part_size = sd_part_size,
  97. .unit_num = sd_unit_num,
  98. .print_vi = sd_print_vi
  99. };
  100. //////////////////////////////////////////////////////////////////////////////
  101. // direct item functions
  102. //
  103. static int direct_bytes_number (struct item_head * ih, int block_size)
  104. {
  105. return ih_item_len(ih);
  106. }
  107. // FIXME: this should probably switch to indirect as well
  108. static void direct_decrement_key (struct cpu_key * key)
  109. {
  110. cpu_key_k_offset_dec (key);
  111. if (cpu_key_k_offset (key) == 0)
  112. set_cpu_key_k_type (key, TYPE_STAT_DATA);
  113. }
  114. static int direct_is_left_mergeable (struct reiserfs_key * key, unsigned long bsize)
  115. {
  116. int version = le_key_version (key);
  117. return ((le_key_k_offset (version, key) & (bsize - 1)) != 1);
  118. }
  119. static void direct_print_item (struct item_head * ih, char * item)
  120. {
  121. int j = 0;
  122. // return;
  123. printk ("\"");
  124. while (j < ih_item_len(ih))
  125. printk ("%c", item[j++]);
  126. printk ("\"\n");
  127. }
  128. static void direct_check_item (struct item_head * ih, char * item)
  129. {
  130. // FIXME: type something here!
  131. }
  132. static int direct_create_vi (struct virtual_node * vn,
  133. struct virtual_item * vi,
  134. int is_affected,
  135. int insert_size)
  136. {
  137. vi->vi_index = TYPE_DIRECT;
  138. //vi->vi_type |= VI_TYPE_DIRECT;
  139. return 0;
  140. }
  141. static int direct_check_left (struct virtual_item * vi, int free,
  142. int start_skip, int end_skip)
  143. {
  144. int bytes;
  145. bytes = free - free % 8;
  146. return bytes ?: -1;
  147. }
  148. static int direct_check_right (struct virtual_item * vi, int free)
  149. {
  150. return direct_check_left (vi, free, 0, 0);
  151. }
  152. static int direct_part_size (struct virtual_item * vi, int first, int count)
  153. {
  154. return count;
  155. }
  156. static int direct_unit_num (struct virtual_item * vi)
  157. {
  158. return vi->vi_item_len - IH_SIZE;
  159. }
  160. static void direct_print_vi (struct virtual_item * vi)
  161. {
  162. reiserfs_warning (NULL, "DIRECT, index %d, type 0x%x, %h",
  163. vi->vi_index, vi->vi_type, vi->vi_ih);
  164. }
  165. static struct item_operations direct_ops = {
  166. .bytes_number = direct_bytes_number,
  167. .decrement_key = direct_decrement_key,
  168. .is_left_mergeable = direct_is_left_mergeable,
  169. .print_item = direct_print_item,
  170. .check_item = direct_check_item,
  171. .create_vi = direct_create_vi,
  172. .check_left = direct_check_left,
  173. .check_right = direct_check_right,
  174. .part_size = direct_part_size,
  175. .unit_num = direct_unit_num,
  176. .print_vi = direct_print_vi
  177. };
  178. //////////////////////////////////////////////////////////////////////////////
  179. // indirect item functions
  180. //
  181. static int indirect_bytes_number (struct item_head * ih, int block_size)
  182. {
  183. return ih_item_len(ih) / UNFM_P_SIZE * block_size; //- get_ih_free_space (ih);
  184. }
  185. // decrease offset, if it becomes 0, change type to stat data
  186. static void indirect_decrement_key (struct cpu_key * key)
  187. {
  188. cpu_key_k_offset_dec (key);
  189. if (cpu_key_k_offset (key) == 0)
  190. set_cpu_key_k_type (key, TYPE_STAT_DATA);
  191. }
  192. // if it is not first item of the body, then it is mergeable
  193. static int indirect_is_left_mergeable (struct reiserfs_key * key, unsigned long bsize)
  194. {
  195. int version = le_key_version (key);
  196. return (le_key_k_offset (version, key) != 1);
  197. }
  198. // printing of indirect item
  199. static void start_new_sequence (__u32 * start, int * len, __u32 new)
  200. {
  201. *start = new;
  202. *len = 1;
  203. }
  204. static int sequence_finished (__u32 start, int * len, __u32 new)
  205. {
  206. if (start == INT_MAX)
  207. return 1;
  208. if (start == 0 && new == 0) {
  209. (*len) ++;
  210. return 0;
  211. }
  212. if (start != 0 && (start + *len) == new) {
  213. (*len) ++;
  214. return 0;
  215. }
  216. return 1;
  217. }
  218. static void print_sequence (__u32 start, int len)
  219. {
  220. if (start == INT_MAX)
  221. return;
  222. if (len == 1)
  223. printk (" %d", start);
  224. else
  225. printk (" %d(%d)", start, len);
  226. }
  227. static void indirect_print_item (struct item_head * ih, char * item)
  228. {
  229. int j;
  230. __u32 * unp, prev = INT_MAX;
  231. int num;
  232. unp = (__u32 *)item;
  233. if (ih_item_len(ih) % UNFM_P_SIZE)
  234. reiserfs_warning (NULL, "indirect_print_item: invalid item len");
  235. printk ("%d pointers\n[ ", (int)I_UNFM_NUM (ih));
  236. for (j = 0; j < I_UNFM_NUM (ih); j ++) {
  237. if (sequence_finished (prev, &num, get_block_num(unp, j))) {
  238. print_sequence (prev, num);
  239. start_new_sequence (&prev, &num, get_block_num(unp, j));
  240. }
  241. }
  242. print_sequence (prev, num);
  243. printk ("]\n");
  244. }
  245. static void indirect_check_item (struct item_head * ih, char * item)
  246. {
  247. // FIXME: type something here!
  248. }
  249. static int indirect_create_vi (struct virtual_node * vn,
  250. struct virtual_item * vi,
  251. int is_affected,
  252. int insert_size)
  253. {
  254. vi->vi_index = TYPE_INDIRECT;
  255. //vi->vi_type |= VI_TYPE_INDIRECT;
  256. return 0;
  257. }
  258. static int indirect_check_left (struct virtual_item * vi, int free,
  259. int start_skip, int end_skip)
  260. {
  261. int bytes;
  262. bytes = free - free % UNFM_P_SIZE;
  263. return bytes ?: -1;
  264. }
  265. static int indirect_check_right (struct virtual_item * vi, int free)
  266. {
  267. return indirect_check_left (vi, free, 0, 0);
  268. }
  269. // return size in bytes of 'units' units. If first == 0 - calculate from the head (left), otherwise - from tail (right)
  270. static int indirect_part_size (struct virtual_item * vi, int first, int units)
  271. {
  272. // unit of indirect item is byte (yet)
  273. return units;
  274. }
  275. static int indirect_unit_num (struct virtual_item * vi)
  276. {
  277. // unit of indirect item is byte (yet)
  278. return vi->vi_item_len - IH_SIZE;
  279. }
  280. static void indirect_print_vi (struct virtual_item * vi)
  281. {
  282. reiserfs_warning (NULL, "INDIRECT, index %d, type 0x%x, %h",
  283. vi->vi_index, vi->vi_type, vi->vi_ih);
  284. }
  285. static struct item_operations indirect_ops = {
  286. .bytes_number = indirect_bytes_number,
  287. .decrement_key = indirect_decrement_key,
  288. .is_left_mergeable = indirect_is_left_mergeable,
  289. .print_item = indirect_print_item,
  290. .check_item = indirect_check_item,
  291. .create_vi = indirect_create_vi,
  292. .check_left = indirect_check_left,
  293. .check_right = indirect_check_right,
  294. .part_size = indirect_part_size,
  295. .unit_num = indirect_unit_num,
  296. .print_vi = indirect_print_vi
  297. };
  298. //////////////////////////////////////////////////////////////////////////////
  299. // direntry functions
  300. //
  301. static int direntry_bytes_number (struct item_head * ih, int block_size)
  302. {
  303. reiserfs_warning (NULL, "vs-16090: direntry_bytes_number: "
  304. "bytes number is asked for direntry");
  305. return 0;
  306. }
  307. static void direntry_decrement_key (struct cpu_key * key)
  308. {
  309. cpu_key_k_offset_dec (key);
  310. if (cpu_key_k_offset (key) == 0)
  311. set_cpu_key_k_type (key, TYPE_STAT_DATA);
  312. }
  313. static int direntry_is_left_mergeable (struct reiserfs_key * key, unsigned long bsize)
  314. {
  315. if (le32_to_cpu (key->u.k_offset_v1.k_offset) == DOT_OFFSET)
  316. return 0;
  317. return 1;
  318. }
  319. static void direntry_print_item (struct item_head * ih, char * item)
  320. {
  321. int i;
  322. int namelen;
  323. struct reiserfs_de_head * deh;
  324. char * name;
  325. static char namebuf [80];
  326. printk ("\n # %-15s%-30s%-15s%-15s%-15s\n", "Name", "Key of pointed object", "Hash", "Gen number", "Status");
  327. deh = (struct reiserfs_de_head *)item;
  328. for (i = 0; i < I_ENTRY_COUNT (ih); i ++, deh ++) {
  329. namelen = (i ? (deh_location(deh - 1)) : ih_item_len(ih)) - deh_location(deh);
  330. name = item + deh_location(deh);
  331. if (name[namelen-1] == 0)
  332. namelen = strlen (name);
  333. namebuf[0] = '"';
  334. if (namelen > sizeof (namebuf) - 3) {
  335. strncpy (namebuf + 1, name, sizeof (namebuf) - 3);
  336. namebuf[sizeof (namebuf) - 2] = '"';
  337. namebuf[sizeof (namebuf) - 1] = 0;
  338. } else {
  339. memcpy (namebuf + 1, name, namelen);
  340. namebuf[namelen + 1] = '"';
  341. namebuf[namelen + 2] = 0;
  342. }
  343. printk ("%d: %-15s%-15d%-15d%-15Ld%-15Ld(%s)\n",
  344. i, namebuf,
  345. deh_dir_id(deh), deh_objectid(deh),
  346. GET_HASH_VALUE (deh_offset (deh)), GET_GENERATION_NUMBER ((deh_offset (deh))),
  347. (de_hidden (deh)) ? "HIDDEN" : "VISIBLE");
  348. }
  349. }
  350. static void direntry_check_item (struct item_head * ih, char * item)
  351. {
  352. int i;
  353. struct reiserfs_de_head * deh;
  354. // FIXME: type something here!
  355. deh = (struct reiserfs_de_head *)item;
  356. for (i = 0; i < I_ENTRY_COUNT (ih); i ++, deh ++) {
  357. ;
  358. }
  359. }
  360. #define DIRENTRY_VI_FIRST_DIRENTRY_ITEM 1
  361. /*
  362. * function returns old entry number in directory item in real node
  363. * using new entry number in virtual item in virtual node */
  364. static inline int old_entry_num (int is_affected, int virtual_entry_num, int pos_in_item, int mode)
  365. {
  366. if ( mode == M_INSERT || mode == M_DELETE)
  367. return virtual_entry_num;
  368. if (!is_affected)
  369. /* cut or paste is applied to another item */
  370. return virtual_entry_num;
  371. if (virtual_entry_num < pos_in_item)
  372. return virtual_entry_num;
  373. if (mode == M_CUT)
  374. return virtual_entry_num + 1;
  375. RFALSE( mode != M_PASTE || virtual_entry_num == 0,
  376. "vs-8015: old_entry_num: mode must be M_PASTE (mode = \'%c\'", mode);
  377. return virtual_entry_num - 1;
  378. }
  379. /* Create an array of sizes of directory entries for virtual
  380. item. Return space used by an item. FIXME: no control over
  381. consuming of space used by this item handler */
  382. static int direntry_create_vi (struct virtual_node * vn,
  383. struct virtual_item * vi,
  384. int is_affected,
  385. int insert_size)
  386. {
  387. struct direntry_uarea * dir_u = vi->vi_uarea;
  388. int i, j;
  389. int size = sizeof (struct direntry_uarea);
  390. struct reiserfs_de_head * deh;
  391. vi->vi_index = TYPE_DIRENTRY;
  392. if (!(vi->vi_ih) || !vi->vi_item)
  393. BUG ();
  394. dir_u->flags = 0;
  395. if (le_ih_k_offset (vi->vi_ih) == DOT_OFFSET)
  396. dir_u->flags |= DIRENTRY_VI_FIRST_DIRENTRY_ITEM;
  397. deh = (struct reiserfs_de_head *)(vi->vi_item);
  398. /* virtual directory item have this amount of entry after */
  399. dir_u->entry_count = ih_entry_count (vi->vi_ih) +
  400. ((is_affected) ? ((vn->vn_mode == M_CUT) ? -1 :
  401. (vn->vn_mode == M_PASTE ? 1 : 0)) : 0);
  402. for (i = 0; i < dir_u->entry_count; i ++) {
  403. j = old_entry_num (is_affected, i, vn->vn_pos_in_item, vn->vn_mode);
  404. dir_u->entry_sizes[i] = (j ? deh_location( &(deh[j - 1]) ) :
  405. ih_item_len (vi->vi_ih)) -
  406. deh_location( &(deh[j])) + DEH_SIZE;
  407. }
  408. size += (dir_u->entry_count * sizeof (short));
  409. /* set size of pasted entry */
  410. if (is_affected && vn->vn_mode == M_PASTE)
  411. dir_u->entry_sizes[vn->vn_pos_in_item] = insert_size;
  412. #ifdef CONFIG_REISERFS_CHECK
  413. /* compare total size of entries with item length */
  414. {
  415. int k, l;
  416. l = 0;
  417. for (k = 0; k < dir_u->entry_count; k ++)
  418. l += dir_u->entry_sizes[k];
  419. if (l + IH_SIZE != vi->vi_item_len +
  420. ((is_affected && (vn->vn_mode == M_PASTE || vn->vn_mode == M_CUT)) ? insert_size : 0) ) {
  421. reiserfs_panic (NULL, "vs-8025: set_entry_sizes: (mode==%c, insert_size==%d), invalid length of directory item",
  422. vn->vn_mode, insert_size);
  423. }
  424. }
  425. #endif
  426. return size;
  427. }
  428. //
  429. // return number of entries which may fit into specified amount of
  430. // free space, or -1 if free space is not enough even for 1 entry
  431. //
  432. static int direntry_check_left (struct virtual_item * vi, int free,
  433. int start_skip, int end_skip)
  434. {
  435. int i;
  436. int entries = 0;
  437. struct direntry_uarea * dir_u = vi->vi_uarea;
  438. for (i = start_skip; i < dir_u->entry_count - end_skip; i ++) {
  439. if (dir_u->entry_sizes[i] > free)
  440. /* i-th entry doesn't fit into the remaining free space */
  441. break;
  442. free -= dir_u->entry_sizes[i];
  443. entries ++;
  444. }
  445. if (entries == dir_u->entry_count) {
  446. reiserfs_panic (NULL, "free space %d, entry_count %d\n", free, dir_u->entry_count);
  447. }
  448. /* "." and ".." can not be separated from each other */
  449. if (start_skip == 0 && (dir_u->flags & DIRENTRY_VI_FIRST_DIRENTRY_ITEM) && entries < 2)
  450. entries = 0;
  451. return entries ?: -1;
  452. }
  453. static int direntry_check_right (struct virtual_item * vi, int free)
  454. {
  455. int i;
  456. int entries = 0;
  457. struct direntry_uarea * dir_u = vi->vi_uarea;
  458. for (i = dir_u->entry_count - 1; i >= 0; i --) {
  459. if (dir_u->entry_sizes[i] > free)
  460. /* i-th entry doesn't fit into the remaining free space */
  461. break;
  462. free -= dir_u->entry_sizes[i];
  463. entries ++;
  464. }
  465. if (entries == dir_u->entry_count)
  466. BUG ();
  467. /* "." and ".." can not be separated from each other */
  468. if ((dir_u->flags & DIRENTRY_VI_FIRST_DIRENTRY_ITEM) && entries > dir_u->entry_count - 2)
  469. entries = dir_u->entry_count - 2;
  470. return entries ?: -1;
  471. }
  472. /* sum of entry sizes between from-th and to-th entries including both edges */
  473. static int direntry_part_size (struct virtual_item * vi, int first, int count)
  474. {
  475. int i, retval;
  476. int from, to;
  477. struct direntry_uarea * dir_u = vi->vi_uarea;
  478. retval = 0;
  479. if (first == 0)
  480. from = 0;
  481. else
  482. from = dir_u->entry_count - count;
  483. to = from + count - 1;
  484. for (i = from; i <= to; i ++)
  485. retval += dir_u->entry_sizes[i];
  486. return retval;
  487. }
  488. static int direntry_unit_num (struct virtual_item * vi)
  489. {
  490. struct direntry_uarea * dir_u = vi->vi_uarea;
  491. return dir_u->entry_count;
  492. }
  493. static void direntry_print_vi (struct virtual_item * vi)
  494. {
  495. int i;
  496. struct direntry_uarea * dir_u = vi->vi_uarea;
  497. reiserfs_warning (NULL, "DIRENTRY, index %d, type 0x%x, %h, flags 0x%x",
  498. vi->vi_index, vi->vi_type, vi->vi_ih, dir_u->flags);
  499. printk ("%d entries: ", dir_u->entry_count);
  500. for (i = 0; i < dir_u->entry_count; i ++)
  501. printk ("%d ", dir_u->entry_sizes[i]);
  502. printk ("\n");
  503. }
  504. static struct item_operations direntry_ops = {
  505. .bytes_number = direntry_bytes_number,
  506. .decrement_key = direntry_decrement_key,
  507. .is_left_mergeable = direntry_is_left_mergeable,
  508. .print_item = direntry_print_item,
  509. .check_item = direntry_check_item,
  510. .create_vi = direntry_create_vi,
  511. .check_left = direntry_check_left,
  512. .check_right = direntry_check_right,
  513. .part_size = direntry_part_size,
  514. .unit_num = direntry_unit_num,
  515. .print_vi = direntry_print_vi
  516. };
  517. //////////////////////////////////////////////////////////////////////////////
  518. // Error catching functions to catch errors caused by incorrect item types.
  519. //
  520. static int errcatch_bytes_number (struct item_head * ih, int block_size)
  521. {
  522. reiserfs_warning (NULL, "green-16001: Invalid item type observed, run fsck ASAP");
  523. return 0;
  524. }
  525. static void errcatch_decrement_key (struct cpu_key * key)
  526. {
  527. reiserfs_warning (NULL, "green-16002: Invalid item type observed, run fsck ASAP");
  528. }
  529. static int errcatch_is_left_mergeable (struct reiserfs_key * key, unsigned long bsize)
  530. {
  531. reiserfs_warning (NULL, "green-16003: Invalid item type observed, run fsck ASAP");
  532. return 0;
  533. }
  534. static void errcatch_print_item (struct item_head * ih, char * item)
  535. {
  536. reiserfs_warning (NULL, "green-16004: Invalid item type observed, run fsck ASAP");
  537. }
  538. static void errcatch_check_item (struct item_head * ih, char * item)
  539. {
  540. reiserfs_warning (NULL, "green-16005: Invalid item type observed, run fsck ASAP");
  541. }
  542. static int errcatch_create_vi (struct virtual_node * vn,
  543. struct virtual_item * vi,
  544. int is_affected,
  545. int insert_size)
  546. {
  547. reiserfs_warning (NULL, "green-16006: Invalid item type observed, run fsck ASAP");
  548. return 0; // We might return -1 here as well, but it won't help as create_virtual_node() from where
  549. // this operation is called from is of return type void.
  550. }
  551. static int errcatch_check_left (struct virtual_item * vi, int free,
  552. int start_skip, int end_skip)
  553. {
  554. reiserfs_warning (NULL, "green-16007: Invalid item type observed, run fsck ASAP");
  555. return -1;
  556. }
  557. static int errcatch_check_right (struct virtual_item * vi, int free)
  558. {
  559. reiserfs_warning (NULL, "green-16008: Invalid item type observed, run fsck ASAP");
  560. return -1;
  561. }
  562. static int errcatch_part_size (struct virtual_item * vi, int first, int count)
  563. {
  564. reiserfs_warning (NULL, "green-16009: Invalid item type observed, run fsck ASAP");
  565. return 0;
  566. }
  567. static int errcatch_unit_num (struct virtual_item * vi)
  568. {
  569. reiserfs_warning (NULL, "green-16010: Invalid item type observed, run fsck ASAP");
  570. return 0;
  571. }
  572. static void errcatch_print_vi (struct virtual_item * vi)
  573. {
  574. reiserfs_warning (NULL, "green-16011: Invalid item type observed, run fsck ASAP");
  575. }
  576. static struct item_operations errcatch_ops = {
  577. errcatch_bytes_number,
  578. errcatch_decrement_key,
  579. errcatch_is_left_mergeable,
  580. errcatch_print_item,
  581. errcatch_check_item,
  582. errcatch_create_vi,
  583. errcatch_check_left,
  584. errcatch_check_right,
  585. errcatch_part_size,
  586. errcatch_unit_num,
  587. errcatch_print_vi
  588. };
  589. //////////////////////////////////////////////////////////////////////////////
  590. //
  591. //
  592. #if ! (TYPE_STAT_DATA == 0 && TYPE_INDIRECT == 1 && TYPE_DIRECT == 2 && TYPE_DIRENTRY == 3)
  593. do not compile
  594. #endif
  595. struct item_operations * item_ops [TYPE_ANY + 1] = {
  596. &stat_data_ops,
  597. &indirect_ops,
  598. &direct_ops,
  599. &direntry_ops,
  600. NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  601. &errcatch_ops /* This is to catch errors with invalid type (15th entry for TYPE_ANY) */
  602. };