X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fufs%2Futil.c;fp=fs%2Fufs%2Futil.c;h=22f820a9b15c782dace5e86fc2a6bf9d9ad74ab0;hb=16c70f8c1b54b61c3b951b6fb220df250fe09b32;hp=59acc8f073acf5c8c8a384e44960557e788ad2e5;hpb=4e76c8a9fa413ccc09d3f7f664183dcce3555d57;p=linux-2.6.git diff --git a/fs/ufs/util.c b/fs/ufs/util.c index 59acc8f07..22f820a9b 100644 --- a/fs/ufs/util.c +++ b/fs/ufs/util.c @@ -14,15 +14,6 @@ #include "swab.h" #include "util.h" -#undef UFS_UTILS_DEBUG - -#ifdef UFS_UTILS_DEBUG -#define UFSD(x) printk("(%s, %d), %s: ", __FILE__, __LINE__, __FUNCTION__); printk x; -#else -#define UFSD(x) -#endif - - struct ufs_buffer_head * _ubh_bread_ (struct ufs_sb_private_info * uspi, struct super_block *sb, u64 fragment, u64 size) { @@ -63,17 +54,17 @@ struct ufs_buffer_head * ubh_bread_uspi (struct ufs_sb_private_info * uspi, count = size >> uspi->s_fshift; if (count <= 0 || count > UFS_MAXFRAG) return NULL; - USPI_UBH->fragment = fragment; - USPI_UBH->count = count; + USPI_UBH(uspi)->fragment = fragment; + USPI_UBH(uspi)->count = count; for (i = 0; i < count; i++) - if (!(USPI_UBH->bh[i] = sb_bread(sb, fragment + i))) + if (!(USPI_UBH(uspi)->bh[i] = sb_bread(sb, fragment + i))) goto failed; for (; i < UFS_MAXFRAG; i++) - USPI_UBH->bh[i] = NULL; - return USPI_UBH; + USPI_UBH(uspi)->bh[i] = NULL; + return USPI_UBH(uspi); failed: for (j = 0; j < i; j++) - brelse (USPI_UBH->bh[j]); + brelse (USPI_UBH(uspi)->bh[j]); return NULL; } @@ -90,11 +81,11 @@ void ubh_brelse (struct ufs_buffer_head * ubh) void ubh_brelse_uspi (struct ufs_sb_private_info * uspi) { unsigned i; - if (!USPI_UBH) + if (!USPI_UBH(uspi)) return; - for ( i = 0; i < USPI_UBH->count; i++ ) { - brelse (USPI_UBH->bh[i]); - USPI_UBH->bh[i] = NULL; + for ( i = 0; i < USPI_UBH(uspi)->count; i++ ) { + brelse (USPI_UBH(uspi)->bh[i]); + USPI_UBH(uspi)->bh[i] = NULL; } } @@ -121,13 +112,12 @@ void ubh_mark_buffer_uptodate (struct ufs_buffer_head * ubh, int flag) } } -void ubh_ll_rw_block (int rw, unsigned nr, struct ufs_buffer_head * ubh[]) +void ubh_ll_rw_block(int rw, struct ufs_buffer_head *ubh) { - unsigned i; if (!ubh) return; - for ( i = 0; i < nr; i++ ) - ll_rw_block (rw, ubh[i]->count, ubh[i]->bh); + + ll_rw_block(rw, ubh->count, ubh->bh); } void ubh_wait_on_buffer (struct ufs_buffer_head * ubh) @@ -139,18 +129,6 @@ void ubh_wait_on_buffer (struct ufs_buffer_head * ubh) wait_on_buffer (ubh->bh[i]); } -unsigned ubh_max_bcount (struct ufs_buffer_head * ubh) -{ - unsigned i; - unsigned max = 0; - if (!ubh) - return 0; - for ( i = 0; i < ubh->count; i++ ) - if ( atomic_read(&ubh->bh[i]->b_count) > max ) - max = atomic_read(&ubh->bh[i]->b_count); - return max; -} - void ubh_bforget (struct ufs_buffer_head * ubh) { unsigned i; @@ -255,3 +233,58 @@ ufs_set_inode_dev(struct super_block *sb, struct ufs_inode_info *ufsi, dev_t dev else ufsi->i_u1.i_data[0] = fs32; } + +/** + * ufs_get_locked_page() - locate, pin and lock a pagecache page, if not exist + * read it from disk. + * @mapping: the address_space to search + * @index: the page index + * + * Locates the desired pagecache page, if not exist we'll read it, + * locks it, increments its reference + * count and returns its address. + * + */ + +struct page *ufs_get_locked_page(struct address_space *mapping, + pgoff_t index) +{ + struct page *page; + + page = find_lock_page(mapping, index); + if (!page) { + page = read_cache_page(mapping, index, + (filler_t*)mapping->a_ops->readpage, + NULL); + + if (IS_ERR(page)) { + printk(KERN_ERR "ufs_change_blocknr: " + "read_cache_page error: ino %lu, index: %lu\n", + mapping->host->i_ino, index); + goto out; + } + + lock_page(page); + + if (unlikely(page->mapping == NULL)) { + /* Truncate got there first */ + unlock_page(page); + page_cache_release(page); + page = NULL; + goto out; + } + + if (!PageUptodate(page) || PageError(page)) { + unlock_page(page); + page_cache_release(page); + + printk(KERN_ERR "ufs_change_blocknr: " + "can not read page: ino %lu, index: %lu\n", + mapping->host->i_ino, index); + + page = ERR_PTR(-EIO); + } + } +out: + return page; +}