page.c (bc030d6cb9532877c1c5a3f5e7123344fa24a285) | page.c (622daaff0a8975fb5c5b95f24f3234550ba32e92) |
---|---|
1/* 2 * page.c - buffer/page management specific to NILFS 3 * 4 * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or --- 532 unchanged lines hidden (view full) --- 541 spin_unlock_irq(&mapping->tree_lock); 542 return clear_page_dirty_for_io(page); 543 } 544 spin_unlock_irq(&mapping->tree_lock); 545 return 0; 546 } 547 return TestClearPageDirty(page); 548} | 1/* 2 * page.c - buffer/page management specific to NILFS 3 * 4 * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or --- 532 unchanged lines hidden (view full) --- 541 spin_unlock_irq(&mapping->tree_lock); 542 return clear_page_dirty_for_io(page); 543 } 544 spin_unlock_irq(&mapping->tree_lock); 545 return 0; 546 } 547 return TestClearPageDirty(page); 548} |
549 550/** 551 * nilfs_find_uncommitted_extent - find extent of uncommitted data 552 * @inode: inode 553 * @start_blk: start block offset (in) 554 * @blkoff: start offset of the found extent (out) 555 * 556 * This function searches an extent of buffers marked "delayed" which 557 * starts from a block offset equal to or larger than @start_blk. If 558 * such an extent was found, this will store the start offset in 559 * @blkoff and return its length in blocks. Otherwise, zero is 560 * returned. 561 */ 562unsigned long nilfs_find_uncommitted_extent(struct inode *inode, 563 sector_t start_blk, 564 sector_t *blkoff) 565{ 566 unsigned int i; 567 pgoff_t index; 568 unsigned int nblocks_in_page; 569 unsigned long length = 0; 570 sector_t b; 571 struct pagevec pvec; 572 struct page *page; 573 574 if (inode->i_mapping->nrpages == 0) 575 return 0; 576 577 index = start_blk >> (PAGE_CACHE_SHIFT - inode->i_blkbits); 578 nblocks_in_page = 1U << (PAGE_CACHE_SHIFT - inode->i_blkbits); 579 580 pagevec_init(&pvec, 0); 581 582repeat: 583 pvec.nr = find_get_pages_contig(inode->i_mapping, index, PAGEVEC_SIZE, 584 pvec.pages); 585 if (pvec.nr == 0) 586 return length; 587 588 if (length > 0 && pvec.pages[0]->index > index) 589 goto out; 590 591 b = pvec.pages[0]->index << (PAGE_CACHE_SHIFT - inode->i_blkbits); 592 i = 0; 593 do { 594 page = pvec.pages[i]; 595 596 lock_page(page); 597 if (page_has_buffers(page)) { 598 struct buffer_head *bh, *head; 599 600 bh = head = page_buffers(page); 601 do { 602 if (b < start_blk) 603 continue; 604 if (buffer_delay(bh)) { 605 if (length == 0) 606 *blkoff = b; 607 length++; 608 } else if (length > 0) { 609 goto out_locked; 610 } 611 } while (++b, bh = bh->b_this_page, bh != head); 612 } else { 613 if (length > 0) 614 goto out_locked; 615 616 b += nblocks_in_page; 617 } 618 unlock_page(page); 619 620 } while (++i < pagevec_count(&pvec)); 621 622 index = page->index + 1; 623 pagevec_release(&pvec); 624 cond_resched(); 625 goto repeat; 626 627out_locked: 628 unlock_page(page); 629out: 630 pagevec_release(&pvec); 631 return length; 632} |
|