VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git] / fs / xfs / linux-2.6 / xfs_aops.c
index 200159f..7122efd 100644 (file)
@@ -172,28 +172,15 @@ xfs_map_blocks(
        struct inode            *inode,
        loff_t                  offset,
        ssize_t                 count,
-       xfs_iomap_t             *iomapp,
+       xfs_iomap_t             *mapp,
        int                     flags)
 {
        vnode_t                 *vp = LINVFS_GET_VP(inode);
-       int                     error, niomaps = 1;
-
-       if (((flags & (BMAPI_DIRECT|BMAPI_SYNC)) == BMAPI_DIRECT) &&
-           (offset >= i_size_read(inode)))
-               count = max_t(ssize_t, count, XFS_WRITE_IO_LOG);
-retry:
-       VOP_BMAP(vp, offset, count, flags, iomapp, &niomaps, error);
-       if ((error == EAGAIN) || (error == EIO))
-               return -error;
-       if (unlikely((flags & (BMAPI_WRITE|BMAPI_DIRECT)) ==
-                                       (BMAPI_WRITE|BMAPI_DIRECT) && niomaps &&
-                                       (iomapp->iomap_flags & IOMAP_DELAY))) {
-               flags = BMAPI_ALLOCATE;
-               goto retry;
-       }
-       if (flags & (BMAPI_WRITE|BMAPI_ALLOCATE)) {
+       int                     error, nmaps = 1;
+
+       VOP_BMAP(vp, offset, count, flags, mapp, &nmaps, error);
+       if (!error && (flags & (BMAPI_WRITE|BMAPI_ALLOCATE)))
                VMODIFY(vp);
-       }
        return -error;
 }
 
@@ -288,7 +275,7 @@ xfs_probe_unwritten_page(
                *fsbs = 0;
                bh = head = page_buffers(page);
                do {
-                       if (!buffer_unwritten(bh))
+                       if (!buffer_unwritten(bh) || !buffer_uptodate(bh))
                                break;
                        if (!xfs_offset_to_map(page, iomapp, p_offset))
                                break;
@@ -681,13 +668,12 @@ xfs_cluster_write(
        xfs_iomap_t             *iomapp,
        struct writeback_control *wbc,
        int                     startio,
-       int                     all_bh)
+       int                     all_bh,
+       pgoff_t                 tlast)
 {
-       pgoff_t                 tlast;
        struct page             *page;
 
-       tlast = (iomapp->iomap_offset + iomapp->iomap_bsize) >> PAGE_CACHE_SHIFT;
-       for (; tindex < tlast; tindex++) {
+       for (; tindex <= tlast; tindex++) {
                page = xfs_probe_delalloc_page(inode, tindex);
                if (!page)
                        break;
@@ -725,17 +711,20 @@ xfs_page_state_convert(
 {
        struct buffer_head      *bh_arr[MAX_BUF_PER_PAGE], *bh, *head;
        xfs_iomap_t             *iomp, iomap;
-       unsigned long           p_offset = 0;
-       pgoff_t                 end_index;
        loff_t                  offset;
-       unsigned long long      end_offset;
+       unsigned long           p_offset = 0;
+       __uint64_t              end_offset;
+       pgoff_t                 end_index, last_index, tlast;
        int                     len, err, i, cnt = 0, uptodate = 1;
        int                     flags = startio ? 0 : BMAPI_TRYLOCK;
        int                     page_dirty = 1;
+       int                     delalloc = 0;
 
 
        /* Are we off the end of the file ? */
-       end_index = i_size_read(inode) >> PAGE_CACHE_SHIFT;
+       offset = i_size_read(inode);
+       end_index = offset >> PAGE_CACHE_SHIFT;
+       last_index = (offset - 1) >> PAGE_CACHE_SHIFT;
        if (page->index >= end_index) {
                if ((page->index >= end_index + 1) ||
                    !(i_size_read(inode) & (PAGE_CACHE_SIZE - 1))) {
@@ -769,6 +758,8 @@ xfs_page_state_convert(
                 * extent state conversion transaction on completion.
                 */
                if (buffer_unwritten(bh)) {
+                       if (!startio)
+                               continue;
                        if (!iomp) {
                                err = xfs_map_blocks(inode, offset, len, &iomap,
                                                BMAPI_READ|BMAPI_IGNSTATE);
@@ -778,7 +769,7 @@ xfs_page_state_convert(
                                iomp = xfs_offset_to_map(page, &iomap,
                                                                p_offset);
                        }
-                       if (iomp && startio) {
+                       if (iomp) {
                                if (!bh->b_end_io) {
                                        err = xfs_map_unwritten(inode, page,
                                                        head, bh, p_offset,
@@ -787,7 +778,10 @@ xfs_page_state_convert(
                                        if (err) {
                                                goto error;
                                        }
+                               } else {
+                                       set_bit(BH_Lock, &bh->b_state);
                                }
+                               BUG_ON(!buffer_locked(bh));
                                bh_arr[cnt++] = bh;
                                page_dirty = 0;
                        }
@@ -797,6 +791,7 @@ xfs_page_state_convert(
                 */
                } else if (buffer_delay(bh)) {
                        if (!iomp) {
+                               delalloc = 1;
                                err = xfs_map_blocks(inode, offset, len, &iomap,
                                                BMAPI_ALLOCATE | flags);
                                if (err) {
@@ -871,8 +866,12 @@ xfs_page_state_convert(
                xfs_submit_page(page, bh_arr, cnt);
 
        if (iomp) {
+               tlast = (iomp->iomap_offset + iomp->iomap_bsize - 1) >>
+                                       PAGE_CACHE_SHIFT;
+               if (delalloc && (tlast > last_index))
+                       tlast = last_index;
                xfs_cluster_write(inode, page->index + 1, iomp, wbc,
-                               startio, unmapped);
+                                       startio, unmapped, tlast);
        }
 
        return page_dirty;