]> err.no Git - linux-2.6/blobdiff - fs/ocfs2/aops.c
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
[linux-2.6] / fs / ocfs2 / aops.c
index 014f4f52809cddf6fe6b1119ccb72e1a7d20345a..8e7cafb5fc6c638cded86d0a04c369f62daa5b25 100644 (file)
@@ -78,7 +78,8 @@ static int ocfs2_symlink_get_block(struct inode *inode, sector_t iblock,
 
        if (!OCFS2_IS_VALID_DINODE(fe)) {
                mlog(ML_ERROR, "Invalid dinode #%llu: signature = %.*s\n",
-                    (unsigned long long)fe->i_blkno, 7, fe->i_signature);
+                    (unsigned long long)le64_to_cpu(fe->i_blkno), 7,
+                    fe->i_signature);
                goto bail;
        }
 
@@ -137,6 +138,7 @@ static int ocfs2_get_block(struct inode *inode, sector_t iblock,
                           struct buffer_head *bh_result, int create)
 {
        int err = 0;
+       unsigned int ext_flags;
        u64 p_blkno, past_eof;
        struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
 
@@ -153,7 +155,8 @@ static int ocfs2_get_block(struct inode *inode, sector_t iblock,
                goto bail;
        }
 
-       err = ocfs2_extent_map_get_blocks(inode, iblock, &p_blkno, NULL);
+       err = ocfs2_extent_map_get_blocks(inode, iblock, &p_blkno, NULL,
+                                         &ext_flags);
        if (err) {
                mlog(ML_ERROR, "Error %d from get_blocks(0x%p, %llu, 1, "
                     "%llu, NULL)\n", err, inode, (unsigned long long)iblock,
@@ -171,7 +174,8 @@ static int ocfs2_get_block(struct inode *inode, sector_t iblock,
                        "ino %lu, iblock %llu\n", inode->i_ino,
                        (unsigned long long)iblock);
 
-       if (p_blkno)
+       /* Treat the unwritten extent as a hole for zeroing purposes. */
+       if (p_blkno && !(ext_flags & OCFS2_EXT_UNWRITTEN))
                map_bh(bh_result, inode->i_sb, p_blkno);
 
        if (!ocfs2_sparse_alloc(osb)) {
@@ -396,7 +400,7 @@ static sector_t ocfs2_bmap(struct address_space *mapping, sector_t block)
                down_read(&OCFS2_I(inode)->ip_alloc_sem);
        }
 
-       err = ocfs2_extent_map_get_blocks(inode, block, &p_blkno, NULL);
+       err = ocfs2_extent_map_get_blocks(inode, block, &p_blkno, NULL, NULL);
 
        if (!INODE_JOURNAL(inode)) {
                up_read(&OCFS2_I(inode)->ip_alloc_sem);
@@ -436,8 +440,8 @@ static int ocfs2_direct_IO_get_blocks(struct inode *inode, sector_t iblock,
                                     struct buffer_head *bh_result, int create)
 {
        int ret;
-       u64 p_blkno, inode_blocks;
-       int contig_blocks;
+       u64 p_blkno, inode_blocks, contig_blocks;
+       unsigned int ext_flags;
        unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits;
        unsigned long max_blocks = bh_result->b_size >> inode->i_blkbits;
 
@@ -458,7 +462,7 @@ static int ocfs2_direct_IO_get_blocks(struct inode *inode, sector_t iblock,
        /* This figures out the size of the next contiguous block, and
         * our logical offset */
        ret = ocfs2_extent_map_get_blocks(inode, iblock, &p_blkno,
-                                         &contig_blocks);
+                                         &contig_blocks, &ext_flags);
        if (ret) {
                mlog(ML_ERROR, "get_blocks() failed iblock=%llu\n",
                     (unsigned long long)iblock);
@@ -478,8 +482,10 @@ static int ocfs2_direct_IO_get_blocks(struct inode *inode, sector_t iblock,
        /*
         * get_more_blocks() expects us to describe a hole by clearing
         * the mapped bit on bh_result().
+        *
+        * Consider an unwritten extent as a hole.
         */
-       if (p_blkno)
+       if (p_blkno && !(ext_flags & OCFS2_EXT_UNWRITTEN))
                map_bh(bh_result, inode->i_sb, p_blkno);
        else {
                /*
@@ -517,12 +523,17 @@ static void ocfs2_dio_end_io(struct kiocb *iocb,
                             void *private)
 {
        struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode;
+       int level;
 
        /* this io's submitter should not have unlocked this before we could */
        BUG_ON(!ocfs2_iocb_is_rw_locked(iocb));
+
        ocfs2_iocb_clear_rw_locked(iocb);
-       up_read(&inode->i_alloc_sem);
-       ocfs2_rw_unlock(inode, 0);
+
+       level = ocfs2_iocb_rw_locked_level(iocb);
+       if (!level)
+               up_read(&inode->i_alloc_sem);
+       ocfs2_rw_unlock(inode, level);
 }
 
 /*
@@ -929,9 +940,9 @@ out:
  * Returns a negative error code or the number of bytes copied into
  * the page.
  */
-int ocfs2_write_data_page(struct inode *inode, handle_t *handle,
-                         u64 *p_blkno, struct page *page,
-                         struct ocfs2_write_ctxt *wc, int new)
+static int ocfs2_write_data_page(struct inode *inode, handle_t *handle,
+                                u64 *p_blkno, struct page *page,
+                                struct ocfs2_write_ctxt *wc, int new)
 {
        int ret, copied = 0;
        unsigned int from = 0, to = 0;
@@ -1076,7 +1087,7 @@ static ssize_t ocfs2_write(struct file *file, u32 phys, handle_t *handle,
        for(i = 0; i < numpages; i++) {
                index = start + i;
 
-               cpages[i] = grab_cache_page(mapping, index);
+               cpages[i] = find_or_create_page(mapping, index, GFP_NOFS);
                if (!cpages[i]) {
                        ret = -ENOMEM;
                        mlog_errno(ret);
@@ -1111,7 +1122,8 @@ static ssize_t ocfs2_write(struct file *file, u32 phys, handle_t *handle,
                }
        }
 
-       ret = ocfs2_extent_map_get_blocks(inode, v_blkno, &p_blkno, NULL);
+       ret = ocfs2_extent_map_get_blocks(inode, v_blkno, &p_blkno, NULL,
+                                         NULL);
        if (ret < 0) {
 
                /*
@@ -1215,7 +1227,7 @@ ssize_t ocfs2_buffered_write_cluster(struct file *file, loff_t pos,
         */
        down_write(&OCFS2_I(inode)->ip_alloc_sem);
 
-       ret = ocfs2_get_clusters(inode, wc.w_cpos, &phys, NULL);
+       ret = ocfs2_get_clusters(inode, wc.w_cpos, &phys, NULL, NULL);
        if (ret) {
                mlog_errno(ret);
                goto out_meta;
@@ -1265,7 +1277,7 @@ ssize_t ocfs2_buffered_write_cluster(struct file *file, loff_t pos,
                i_size_write(inode, pos);
                mark_inode_dirty(inode);
        }
-       inode->i_blocks = ocfs2_align_bytes_to_sectors((u64)(i_size_read(inode)));
+       inode->i_blocks = ocfs2_inode_sector_count(inode);
        di->i_size = cpu_to_le64((u64)i_size_read(inode));
        inode->i_mtime = inode->i_ctime = CURRENT_TIME;
        di->i_mtime = di->i_ctime = cpu_to_le64(inode->i_mtime.tv_sec);