Whamcloud - gitweb
LU-10810 clio: SEEK_HOLE/SEEK_DATA on client side
[fs/lustre-release.git] / lustre / obdclass / cl_io.c
index fdc80ae..21fa939 100644 (file)
@@ -45,6 +45,7 @@
 #include <lustre_fid.h>
 #include <cl_object.h>
 #include "cl_internal.h"
+#include <libcfs/crypto/llcrypt.h>
 
 /*****************************************************************************
  *
@@ -125,6 +126,7 @@ void cl_io_fini(const struct lu_env *env, struct cl_io *io)
        case CIT_GLIMPSE:
                break;
        case CIT_LADVISE:
+       case CIT_LSEEK:
                break;
        default:
                LBUG();
@@ -704,7 +706,8 @@ EXPORT_SYMBOL(cl_io_submit_sync);
  */
 int cl_io_loop(const struct lu_env *env, struct cl_io *io)
 {
-       int result   = 0;
+       int result = 0;
+       int rc = 0;
 
        LINVRNT(cl_io_is_loopable(io));
        ENTRY;
@@ -738,7 +741,13 @@ int cl_io_loop(const struct lu_env *env, struct cl_io *io)
                        }
                }
                cl_io_iter_fini(env, io);
-       } while (result == 0 && io->ci_continue);
+               if (result)
+                       rc = result;
+       } while ((result == 0 || result == -EIOCBQUEUED) &&
+                io->ci_continue);
+
+       if (rc && !result)
+               result = rc;
 
        if (result == -EWOULDBLOCK && io->ci_ndelay) {
                io->ci_need_restart = 1;
@@ -787,7 +796,6 @@ void cl_page_list_init(struct cl_page_list *plist)
        ENTRY;
        plist->pl_nr = 0;
        INIT_LIST_HEAD(&plist->pl_pages);
-       plist->pl_owner = current;
        EXIT;
 }
 EXPORT_SYMBOL(cl_page_list_init);
@@ -801,7 +809,6 @@ void cl_page_list_add(struct cl_page_list *plist, struct cl_page *page)
        /* it would be better to check that page is owned by "current" io, but
         * it is not passed here. */
        LASSERT(page->cp_owner != NULL);
-       LINVRNT(plist->pl_owner == current);
 
        LASSERT(list_empty(&page->cp_batch));
        list_add_tail(&page->cp_batch, &plist->pl_pages);
@@ -820,7 +827,6 @@ void cl_page_list_del(const struct lu_env *env,
 {
        LASSERT(plist->pl_nr > 0);
        LASSERT(cl_page_is_vmlocked(env, page));
-       LINVRNT(plist->pl_owner == current);
 
        ENTRY;
        list_del_init(&page->cp_batch);
@@ -838,8 +844,6 @@ void cl_page_list_move(struct cl_page_list *dst, struct cl_page_list *src,
                       struct cl_page *page)
 {
        LASSERT(src->pl_nr > 0);
-       LINVRNT(dst->pl_owner == current);
-       LINVRNT(src->pl_owner == current);
 
        ENTRY;
        list_move_tail(&page->cp_batch, &dst->pl_pages);
@@ -858,8 +862,6 @@ void cl_page_list_move_head(struct cl_page_list *dst, struct cl_page_list *src,
                            struct cl_page *page)
 {
        LASSERT(src->pl_nr > 0);
-       LINVRNT(dst->pl_owner == current);
-       LINVRNT(src->pl_owner == current);
 
        ENTRY;
        list_move(&page->cp_batch, &dst->pl_pages);
@@ -879,8 +881,6 @@ void cl_page_list_splice(struct cl_page_list *list, struct cl_page_list *head)
        struct cl_page *page;
        struct cl_page *tmp;
 
-       LINVRNT(list->pl_owner == current);
-       LINVRNT(head->pl_owner == current);
 
        ENTRY;
        cl_page_list_for_each_safe(page, tmp, list)
@@ -898,7 +898,6 @@ void cl_page_list_disown(const struct lu_env *env,
        struct cl_page *page;
        struct cl_page *temp;
 
-       LINVRNT(plist->pl_owner == current);
 
        ENTRY;
        cl_page_list_for_each_safe(page, temp, plist) {
@@ -931,7 +930,6 @@ void cl_page_list_fini(const struct lu_env *env, struct cl_page_list *plist)
        struct cl_page *page;
        struct cl_page *temp;
 
-       LINVRNT(plist->pl_owner == current);
 
        ENTRY;
        cl_page_list_for_each_safe(page, temp, plist)
@@ -949,7 +947,6 @@ void cl_page_list_assume(const struct lu_env *env,
 {
        struct cl_page *page;
 
-       LINVRNT(plist->pl_owner == current);
 
        cl_page_list_for_each(page, plist)
                cl_page_assume(env, io, page);
@@ -963,7 +960,6 @@ void cl_page_list_discard(const struct lu_env *env, struct cl_io *io,
 {
        struct cl_page *page;
 
-       LINVRNT(plist->pl_owner == current);
        ENTRY;
        cl_page_list_for_each(page, plist)
                cl_page_discard(env, io, page);
@@ -1172,14 +1168,25 @@ static void cl_aio_end(const struct lu_env *env, struct cl_sync_io *anchor)
        /* release pages */
        while (aio->cda_pages.pl_nr > 0) {
                struct cl_page *page = cl_page_list_first(&aio->cda_pages);
+               struct page *vmpage = cl_page_vmpage(page);
+               struct inode *inode = vmpage ? page2inode(vmpage) : NULL;
 
                cl_page_get(page);
+               /* We end up here in case of Direct IO only. For encrypted file,
+                * mapping was set on pages in ll_direct_rw_pages(), so it has
+                * to be cleared now before page cleanup.
+                * PageChecked flag was also set there, so we clean up here.
+                */
+               if (inode && IS_ENCRYPTED(inode)) {
+                       vmpage->mapping = NULL;
+                       ClearPageChecked(vmpage);
+               }
                cl_page_list_del(env, &aio->cda_pages, page);
                cl_page_delete(env, page);
                cl_page_put(env, page);
        }
 
-       if (!is_sync_kiocb(aio->cda_iocb))
+       if (!is_sync_kiocb(aio->cda_iocb) && !aio->cda_no_aio_complete)
                aio_complete(aio->cda_iocb, ret ?: aio->cda_bytes, 0);
 
        EXIT;
@@ -1199,11 +1206,19 @@ struct cl_dio_aio *cl_aio_alloc(struct kiocb *iocb)
                                       NULL : aio, cl_aio_end);
                cl_page_list_init(&aio->cda_pages);
                aio->cda_iocb = iocb;
+               aio->cda_no_aio_complete = 0;
        }
        return aio;
 }
 EXPORT_SYMBOL(cl_aio_alloc);
 
+void cl_aio_free(struct cl_dio_aio *aio)
+{
+       if (aio)
+               OBD_SLAB_FREE_PTR(aio, cl_dio_aio_kmem);
+}
+EXPORT_SYMBOL(cl_aio_free);
+
 
 /**
  * Indicate that transfer of a single page completed.
@@ -1246,8 +1261,7 @@ void cl_sync_io_note(const struct lu_env *env, struct cl_sync_io *anchor,
                 * If anchor->csi_aio is set, we are responsible for freeing
                 * memory here rather than when cl_sync_io_wait() completes.
                 */
-               if (aio)
-                       OBD_SLAB_FREE_PTR(aio, cl_dio_aio_kmem);
+               cl_aio_free(aio);
        }
        EXIT;
 }