if (dio->end_io && dio->result) {
                dio->end_io(dio->iocb, offset, transferred,
                            dio->map_bh.b_private, ret, is_async);
-       } else if (is_async) {
-               aio_complete(dio->iocb, ret, 0);
+       } else {
+               if (is_async)
+                       aio_complete(dio->iocb, ret, 0);
+               inode_dio_done(dio->inode);
        }
 
-       inode_dio_done(dio->inode);
        return ret;
 }
 
 
                            ssize_t size, void *private, int ret,
                            bool is_async)
 {
+       struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode;
         ext4_io_end_t *io_end = iocb->private;
        struct workqueue_struct *wq;
        unsigned long flags;
 out:
                if (is_async)
                        aio_complete(iocb, ret, 0);
+               inode_dio_done(inode);
                return;
        }
 
        /* queue the work to convert unwritten extents to written */
        queue_work(wq, &io_end->work);
        iocb->private = NULL;
+
+       /* XXX: probably should move into the real I/O completion handler */
+       inode_dio_done(inode);
 }
 
 static void ext4_end_io_buffer_write(struct buffer_head *bh, int uptodate)
 
 
        if (is_async)
                aio_complete(iocb, ret, 0);
+       inode_dio_done(inode);
 }
 
 /*
 
        } else {
                xfs_finish_ioend_sync(ioend);
        }
+
+       /* XXX: probably should move into the real I/O completion handler */
+       inode_dio_done(ioend->io_inode);
 }
 
 STATIC ssize_t