aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jffs2/nodemgmt.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/jffs2/nodemgmt.c')
-rw-r--r--fs/jffs2/nodemgmt.c196
1 files changed, 84 insertions, 112 deletions
diff --git a/fs/jffs2/nodemgmt.c b/fs/jffs2/nodemgmt.c
index 49127a1f0458..8bedfd2ff689 100644
--- a/fs/jffs2/nodemgmt.c
+++ b/fs/jffs2/nodemgmt.c
@@ -23,13 +23,12 @@
23 * jffs2_reserve_space - request physical space to write nodes to flash 23 * jffs2_reserve_space - request physical space to write nodes to flash
24 * @c: superblock info 24 * @c: superblock info
25 * @minsize: Minimum acceptable size of allocation 25 * @minsize: Minimum acceptable size of allocation
26 * @ofs: Returned value of node offset
27 * @len: Returned value of allocation length 26 * @len: Returned value of allocation length
28 * @prio: Allocation type - ALLOC_{NORMAL,DELETION} 27 * @prio: Allocation type - ALLOC_{NORMAL,DELETION}
29 * 28 *
30 * Requests a block of physical space on the flash. Returns zero for success 29 * Requests a block of physical space on the flash. Returns zero for success
31 * and puts 'ofs' and 'len' into the appriopriate place, or returns -ENOSPC 30 * and puts 'len' into the appropriate place, or returns -ENOSPC or other
32 * or other error if appropriate. 31 * error if appropriate. Doesn't return len since that's
33 * 32 *
34 * If it returns zero, jffs2_reserve_space() also downs the per-filesystem 33 * If it returns zero, jffs2_reserve_space() also downs the per-filesystem
35 * allocation semaphore, to prevent more than one allocation from being 34 * allocation semaphore, to prevent more than one allocation from being
@@ -40,9 +39,9 @@
40 */ 39 */
41 40
42static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, 41static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize,
43 uint32_t *ofs, uint32_t *len, uint32_t sumsize); 42 uint32_t *len, uint32_t sumsize);
44 43
45int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, 44int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize,
46 uint32_t *len, int prio, uint32_t sumsize) 45 uint32_t *len, int prio, uint32_t sumsize)
47{ 46{
48 int ret = -EAGAIN; 47 int ret = -EAGAIN;
@@ -132,19 +131,21 @@ int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs
132 spin_lock(&c->erase_completion_lock); 131 spin_lock(&c->erase_completion_lock);
133 } 132 }
134 133
135 ret = jffs2_do_reserve_space(c, minsize, ofs, len, sumsize); 134 ret = jffs2_do_reserve_space(c, minsize, len, sumsize);
136 if (ret) { 135 if (ret) {
137 D1(printk(KERN_DEBUG "jffs2_reserve_space: ret is %d\n", ret)); 136 D1(printk(KERN_DEBUG "jffs2_reserve_space: ret is %d\n", ret));
138 } 137 }
139 } 138 }
140 spin_unlock(&c->erase_completion_lock); 139 spin_unlock(&c->erase_completion_lock);
140 if (!ret)
141 ret = jffs2_prealloc_raw_node_refs(c, c->nextblock, 1);
141 if (ret) 142 if (ret)
142 up(&c->alloc_sem); 143 up(&c->alloc_sem);
143 return ret; 144 return ret;
144} 145}
145 146
146int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, 147int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize,
147 uint32_t *len, uint32_t sumsize) 148 uint32_t *len, uint32_t sumsize)
148{ 149{
149 int ret = -EAGAIN; 150 int ret = -EAGAIN;
150 minsize = PAD(minsize); 151 minsize = PAD(minsize);
@@ -153,12 +154,15 @@ int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *
153 154
154 spin_lock(&c->erase_completion_lock); 155 spin_lock(&c->erase_completion_lock);
155 while(ret == -EAGAIN) { 156 while(ret == -EAGAIN) {
156 ret = jffs2_do_reserve_space(c, minsize, ofs, len, sumsize); 157 ret = jffs2_do_reserve_space(c, minsize, len, sumsize);
157 if (ret) { 158 if (ret) {
158 D1(printk(KERN_DEBUG "jffs2_reserve_space_gc: looping, ret is %d\n", ret)); 159 D1(printk(KERN_DEBUG "jffs2_reserve_space_gc: looping, ret is %d\n", ret));
159 } 160 }
160 } 161 }
161 spin_unlock(&c->erase_completion_lock); 162 spin_unlock(&c->erase_completion_lock);
163 if (!ret)
164 ret = jffs2_prealloc_raw_node_refs(c, c->nextblock, 1);
165
162 return ret; 166 return ret;
163} 167}
164 168
@@ -259,10 +263,11 @@ static int jffs2_find_nextblock(struct jffs2_sb_info *c)
259} 263}
260 264
261/* Called with alloc sem _and_ erase_completion_lock */ 265/* Called with alloc sem _and_ erase_completion_lock */
262static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len, uint32_t sumsize) 266static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize,
267 uint32_t *len, uint32_t sumsize)
263{ 268{
264 struct jffs2_eraseblock *jeb = c->nextblock; 269 struct jffs2_eraseblock *jeb = c->nextblock;
265 uint32_t reserved_size; /* for summary information at the end of the jeb */ 270 uint32_t reserved_size; /* for summary information at the end of the jeb */
266 int ret; 271 int ret;
267 272
268 restart: 273 restart:
@@ -312,6 +317,8 @@ static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uin
312 } 317 }
313 } else { 318 } else {
314 if (jeb && minsize > jeb->free_size) { 319 if (jeb && minsize > jeb->free_size) {
320 uint32_t waste;
321
315 /* Skip the end of this block and file it as having some dirty space */ 322 /* Skip the end of this block and file it as having some dirty space */
316 /* If there's a pending write to it, flush now */ 323 /* If there's a pending write to it, flush now */
317 324
@@ -324,10 +331,26 @@ static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uin
324 goto restart; 331 goto restart;
325 } 332 }
326 333
327 c->wasted_size += jeb->free_size; 334 spin_unlock(&c->erase_completion_lock);
328 c->free_size -= jeb->free_size; 335
329 jeb->wasted_size += jeb->free_size; 336 ret = jffs2_prealloc_raw_node_refs(c, jeb, 1);
330 jeb->free_size = 0; 337 if (ret)
338 return ret;
339 /* Just lock it again and continue. Nothing much can change because
340 we hold c->alloc_sem anyway. In fact, it's not entirely clear why
341 we hold c->erase_completion_lock in the majority of this function...
342 but that's a question for another (more caffeine-rich) day. */
343 spin_lock(&c->erase_completion_lock);
344
345 waste = jeb->free_size;
346 jffs2_link_node_ref(c, jeb,
347 (jeb->offset + c->sector_size - waste) | REF_OBSOLETE,
348 waste, NULL);
349 /* FIXME: that made it count as dirty. Convert to wasted */
350 jeb->dirty_size -= waste;
351 c->dirty_size -= waste;
352 jeb->wasted_size += waste;
353 c->wasted_size += waste;
331 354
332 jffs2_close_nextblock(c, jeb); 355 jffs2_close_nextblock(c, jeb);
333 jeb = NULL; 356 jeb = NULL;
@@ -349,7 +372,6 @@ static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uin
349 } 372 }
350 /* OK, jeb (==c->nextblock) is now pointing at a block which definitely has 373 /* OK, jeb (==c->nextblock) is now pointing at a block which definitely has
351 enough space */ 374 enough space */
352 *ofs = jeb->offset + (c->sector_size - jeb->free_size);
353 *len = jeb->free_size - reserved_size; 375 *len = jeb->free_size - reserved_size;
354 376
355 if (c->cleanmarker_size && jeb->used_size == c->cleanmarker_size && 377 if (c->cleanmarker_size && jeb->used_size == c->cleanmarker_size &&
@@ -365,7 +387,8 @@ static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uin
365 spin_lock(&c->erase_completion_lock); 387 spin_lock(&c->erase_completion_lock);
366 } 388 }
367 389
368 D1(printk(KERN_DEBUG "jffs2_do_reserve_space(): Giving 0x%x bytes at 0x%x\n", *len, *ofs)); 390 D1(printk(KERN_DEBUG "jffs2_do_reserve_space(): Giving 0x%x bytes at 0x%x\n",
391 *len, jeb->offset + (c->sector_size - jeb->free_size)));
369 return 0; 392 return 0;
370} 393}
371 394
@@ -374,7 +397,6 @@ static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uin
374 * @c: superblock info 397 * @c: superblock info
375 * @new: new node reference to add 398 * @new: new node reference to add
376 * @len: length of this physical node 399 * @len: length of this physical node
377 * @dirty: dirty flag for new node
378 * 400 *
379 * Should only be used to report nodes for which space has been allocated 401 * Should only be used to report nodes for which space has been allocated
380 * by jffs2_reserve_space. 402 * by jffs2_reserve_space.
@@ -382,42 +404,30 @@ static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uin
382 * Must be called with the alloc_sem held. 404 * Must be called with the alloc_sem held.
383 */ 405 */
384 406
385int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *new) 407struct jffs2_raw_node_ref *jffs2_add_physical_node_ref(struct jffs2_sb_info *c,
408 uint32_t ofs, uint32_t len,
409 struct jffs2_inode_cache *ic)
386{ 410{
387 struct jffs2_eraseblock *jeb; 411 struct jffs2_eraseblock *jeb;
388 uint32_t len; 412 struct jffs2_raw_node_ref *new;
389 413
390 jeb = &c->blocks[new->flash_offset / c->sector_size]; 414 jeb = &c->blocks[ofs / c->sector_size];
391 len = ref_totlen(c, jeb, new);
392 415
393 D1(printk(KERN_DEBUG "jffs2_add_physical_node_ref(): Node at 0x%x(%d), size 0x%x\n", ref_offset(new), ref_flags(new), len)); 416 D1(printk(KERN_DEBUG "jffs2_add_physical_node_ref(): Node at 0x%x(%d), size 0x%x\n",
417 ofs & ~3, ofs & 3, len));
394#if 1 418#if 1
395 /* we could get some obsolete nodes after nextblock was refiled 419 /* Allow non-obsolete nodes only to be added at the end of c->nextblock,
396 in wbuf.c */ 420 if c->nextblock is set. Note that wbuf.c will file obsolete nodes
397 if ((c->nextblock || !ref_obsolete(new)) 421 even after refiling c->nextblock */
398 &&(jeb != c->nextblock || ref_offset(new) != jeb->offset + (c->sector_size - jeb->free_size))) { 422 if ((c->nextblock || ((ofs & 3) != REF_OBSOLETE))
423 && (jeb != c->nextblock || (ofs & ~3) != jeb->offset + (c->sector_size - jeb->free_size))) {
399 printk(KERN_WARNING "argh. node added in wrong place\n"); 424 printk(KERN_WARNING "argh. node added in wrong place\n");
400 jffs2_free_raw_node_ref(new); 425 return ERR_PTR(-EINVAL);
401 return -EINVAL;
402 } 426 }
403#endif 427#endif
404 spin_lock(&c->erase_completion_lock); 428 spin_lock(&c->erase_completion_lock);
405 429
406 if (!jeb->first_node) 430 new = jffs2_link_node_ref(c, jeb, ofs, len, ic);
407 jeb->first_node = new;
408 if (jeb->last_node)
409 jeb->last_node->next_phys = new;
410 jeb->last_node = new;
411
412 jeb->free_size -= len;
413 c->free_size -= len;
414 if (ref_obsolete(new)) {
415 jeb->dirty_size += len;
416 c->dirty_size += len;
417 } else {
418 jeb->used_size += len;
419 c->used_size += len;
420 }
421 431
422 if (!jeb->free_size && !jeb->dirty_size && !ISDIRTY(jeb->wasted_size)) { 432 if (!jeb->free_size && !jeb->dirty_size && !ISDIRTY(jeb->wasted_size)) {
423 /* If it lives on the dirty_list, jffs2_reserve_space will put it there */ 433 /* If it lives on the dirty_list, jffs2_reserve_space will put it there */
@@ -438,7 +448,7 @@ int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_r
438 448
439 spin_unlock(&c->erase_completion_lock); 449 spin_unlock(&c->erase_completion_lock);
440 450
441 return 0; 451 return new;
442} 452}
443 453
444 454
@@ -470,8 +480,9 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
470 struct jffs2_unknown_node n; 480 struct jffs2_unknown_node n;
471 int ret, addedsize; 481 int ret, addedsize;
472 size_t retlen; 482 size_t retlen;
483 uint32_t freed_len;
473 484
474 if(!ref) { 485 if(unlikely(!ref)) {
475 printk(KERN_NOTICE "EEEEEK. jffs2_mark_node_obsolete called with NULL node\n"); 486 printk(KERN_NOTICE "EEEEEK. jffs2_mark_node_obsolete called with NULL node\n");
476 return; 487 return;
477 } 488 }
@@ -499,32 +510,34 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
499 510
500 spin_lock(&c->erase_completion_lock); 511 spin_lock(&c->erase_completion_lock);
501 512
513 freed_len = ref_totlen(c, jeb, ref);
514
502 if (ref_flags(ref) == REF_UNCHECKED) { 515 if (ref_flags(ref) == REF_UNCHECKED) {
503 D1(if (unlikely(jeb->unchecked_size < ref_totlen(c, jeb, ref))) { 516 D1(if (unlikely(jeb->unchecked_size < freed_len)) {
504 printk(KERN_NOTICE "raw unchecked node of size 0x%08x freed from erase block %d at 0x%08x, but unchecked_size was already 0x%08x\n", 517 printk(KERN_NOTICE "raw unchecked node of size 0x%08x freed from erase block %d at 0x%08x, but unchecked_size was already 0x%08x\n",
505 ref_totlen(c, jeb, ref), blocknr, ref->flash_offset, jeb->used_size); 518 freed_len, blocknr, ref->flash_offset, jeb->used_size);
506 BUG(); 519 BUG();
507 }) 520 })
508 D1(printk(KERN_DEBUG "Obsoleting previously unchecked node at 0x%08x of len %x: ", ref_offset(ref), ref_totlen(c, jeb, ref))); 521 D1(printk(KERN_DEBUG "Obsoleting previously unchecked node at 0x%08x of len %x: ", ref_offset(ref), freed_len));
509 jeb->unchecked_size -= ref_totlen(c, jeb, ref); 522 jeb->unchecked_size -= freed_len;
510 c->unchecked_size -= ref_totlen(c, jeb, ref); 523 c->unchecked_size -= freed_len;
511 } else { 524 } else {
512 D1(if (unlikely(jeb->used_size < ref_totlen(c, jeb, ref))) { 525 D1(if (unlikely(jeb->used_size < freed_len)) {
513 printk(KERN_NOTICE "raw node of size 0x%08x freed from erase block %d at 0x%08x, but used_size was already 0x%08x\n", 526 printk(KERN_NOTICE "raw node of size 0x%08x freed from erase block %d at 0x%08x, but used_size was already 0x%08x\n",
514 ref_totlen(c, jeb, ref), blocknr, ref->flash_offset, jeb->used_size); 527 freed_len, blocknr, ref->flash_offset, jeb->used_size);
515 BUG(); 528 BUG();
516 }) 529 })
517 D1(printk(KERN_DEBUG "Obsoleting node at 0x%08x of len %#x: ", ref_offset(ref), ref_totlen(c, jeb, ref))); 530 D1(printk(KERN_DEBUG "Obsoleting node at 0x%08x of len %#x: ", ref_offset(ref), freed_len));
518 jeb->used_size -= ref_totlen(c, jeb, ref); 531 jeb->used_size -= freed_len;
519 c->used_size -= ref_totlen(c, jeb, ref); 532 c->used_size -= freed_len;
520 } 533 }
521 534
522 // Take care, that wasted size is taken into concern 535 // Take care, that wasted size is taken into concern
523 if ((jeb->dirty_size || ISDIRTY(jeb->wasted_size + ref_totlen(c, jeb, ref))) && jeb != c->nextblock) { 536 if ((jeb->dirty_size || ISDIRTY(jeb->wasted_size + freed_len)) && jeb != c->nextblock) {
524 D1(printk(KERN_DEBUG "Dirtying\n")); 537 D1(printk("Dirtying\n"));
525 addedsize = ref_totlen(c, jeb, ref); 538 addedsize = freed_len;
526 jeb->dirty_size += ref_totlen(c, jeb, ref); 539 jeb->dirty_size += freed_len;
527 c->dirty_size += ref_totlen(c, jeb, ref); 540 c->dirty_size += freed_len;
528 541
529 /* Convert wasted space to dirty, if not a bad block */ 542 /* Convert wasted space to dirty, if not a bad block */
530 if (jeb->wasted_size) { 543 if (jeb->wasted_size) {
@@ -543,10 +556,10 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
543 } 556 }
544 } 557 }
545 } else { 558 } else {
546 D1(printk(KERN_DEBUG "Wasting\n")); 559 D1(printk("Wasting\n"));
547 addedsize = 0; 560 addedsize = 0;
548 jeb->wasted_size += ref_totlen(c, jeb, ref); 561 jeb->wasted_size += freed_len;
549 c->wasted_size += ref_totlen(c, jeb, ref); 562 c->wasted_size += freed_len;
550 } 563 }
551 ref->flash_offset = ref_offset(ref) | REF_OBSOLETE; 564 ref->flash_offset = ref_offset(ref) | REF_OBSOLETE;
552 565
@@ -622,7 +635,7 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
622 /* The erase_free_sem is locked, and has been since before we marked the node obsolete 635 /* The erase_free_sem is locked, and has been since before we marked the node obsolete
623 and potentially put its eraseblock onto the erase_pending_list. Thus, we know that 636 and potentially put its eraseblock onto the erase_pending_list. Thus, we know that
624 the block hasn't _already_ been erased, and that 'ref' itself hasn't been freed yet 637 the block hasn't _already_ been erased, and that 'ref' itself hasn't been freed yet
625 by jffs2_free_all_node_refs() in erase.c. Which is nice. */ 638 by jffs2_free_jeb_node_refs() in erase.c. Which is nice. */
626 639
627 D1(printk(KERN_DEBUG "obliterating obsoleted node at 0x%08x\n", ref_offset(ref))); 640 D1(printk(KERN_DEBUG "obliterating obsoleted node at 0x%08x\n", ref_offset(ref)));
628 ret = jffs2_flash_read(c, ref_offset(ref), sizeof(n), &retlen, (char *)&n); 641 ret = jffs2_flash_read(c, ref_offset(ref), sizeof(n), &retlen, (char *)&n);
@@ -634,8 +647,8 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
634 printk(KERN_WARNING "Short read from obsoleted node at 0x%08x: %zd\n", ref_offset(ref), retlen); 647 printk(KERN_WARNING "Short read from obsoleted node at 0x%08x: %zd\n", ref_offset(ref), retlen);
635 goto out_erase_sem; 648 goto out_erase_sem;
636 } 649 }
637 if (PAD(je32_to_cpu(n.totlen)) != PAD(ref_totlen(c, jeb, ref))) { 650 if (PAD(je32_to_cpu(n.totlen)) != PAD(freed_len)) {
638 printk(KERN_WARNING "Node totlen on flash (0x%08x) != totlen from node ref (0x%08x)\n", je32_to_cpu(n.totlen), ref_totlen(c, jeb, ref)); 651 printk(KERN_WARNING "Node totlen on flash (0x%08x) != totlen from node ref (0x%08x)\n", je32_to_cpu(n.totlen), freed_len);
639 goto out_erase_sem; 652 goto out_erase_sem;
640 } 653 }
641 if (!(je16_to_cpu(n.nodetype) & JFFS2_NODE_ACCURATE)) { 654 if (!(je16_to_cpu(n.nodetype) & JFFS2_NODE_ACCURATE)) {
@@ -671,6 +684,10 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
671 spin_lock(&c->erase_completion_lock); 684 spin_lock(&c->erase_completion_lock);
672 685
673 ic = jffs2_raw_ref_to_ic(ref); 686 ic = jffs2_raw_ref_to_ic(ref);
687 /* It seems we should never call jffs2_mark_node_obsolete() for
688 XATTR nodes.... yet. Make sure we notice if/when we change
689 that :) */
690 BUG_ON(ic->class != RAWNODE_CLASS_INODE_CACHE);
674 for (p = &ic->nodes; (*p) != ref; p = &((*p)->next_in_ino)) 691 for (p = &ic->nodes; (*p) != ref; p = &((*p)->next_in_ino))
675 ; 692 ;
676 693
@@ -683,51 +700,6 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
683 spin_unlock(&c->erase_completion_lock); 700 spin_unlock(&c->erase_completion_lock);
684 } 701 }
685 702
686
687 /* Merge with the next node in the physical list, if there is one
688 and if it's also obsolete and if it doesn't belong to any inode */
689 if (ref->next_phys && ref_obsolete(ref->next_phys) &&
690 !ref->next_phys->next_in_ino) {
691 struct jffs2_raw_node_ref *n = ref->next_phys;
692
693 spin_lock(&c->erase_completion_lock);
694
695 ref->__totlen += n->__totlen;
696 ref->next_phys = n->next_phys;
697 if (jeb->last_node == n) jeb->last_node = ref;
698 if (jeb->gc_node == n) {
699 /* gc will be happy continuing gc on this node */
700 jeb->gc_node=ref;
701 }
702 spin_unlock(&c->erase_completion_lock);
703
704 jffs2_free_raw_node_ref(n);
705 }
706
707 /* Also merge with the previous node in the list, if there is one
708 and that one is obsolete */
709 if (ref != jeb->first_node ) {
710 struct jffs2_raw_node_ref *p = jeb->first_node;
711
712 spin_lock(&c->erase_completion_lock);
713
714 while (p->next_phys != ref)
715 p = p->next_phys;
716
717 if (ref_obsolete(p) && !ref->next_in_ino) {
718 p->__totlen += ref->__totlen;
719 if (jeb->last_node == ref) {
720 jeb->last_node = p;
721 }
722 if (jeb->gc_node == ref) {
723 /* gc will be happy continuing gc on this node */
724 jeb->gc_node=p;
725 }
726 p->next_phys = ref->next_phys;
727 jffs2_free_raw_node_ref(ref);
728 }
729 spin_unlock(&c->erase_completion_lock);
730 }
731 out_erase_sem: 703 out_erase_sem:
732 up(&c->erase_free_sem); 704 up(&c->erase_free_sem);
733} 705}