cachefiles: implement on-demand read
[linux-2.6-microblaze.git] / fs / cachefiles / io.c
index 50a14e8..000a28f 100644 (file)
@@ -403,6 +403,7 @@ static enum netfs_io_source cachefiles_prepare_read(struct netfs_io_subrequest *
        enum netfs_io_source ret = NETFS_DOWNLOAD_FROM_SERVER;
        loff_t off, to;
        ino_t ino = file ? file_inode(file)->i_ino : 0;
+       int rc;
 
        _enter("%zx @%llx/%llx", subreq->len, subreq->start, i_size);
 
@@ -415,7 +416,8 @@ static enum netfs_io_source cachefiles_prepare_read(struct netfs_io_subrequest *
        if (test_bit(FSCACHE_COOKIE_NO_DATA_TO_READ, &cookie->flags)) {
                __set_bit(NETFS_SREQ_COPY_TO_CACHE, &subreq->flags);
                why = cachefiles_trace_read_no_data;
-               goto out_no_object;
+               if (!test_bit(NETFS_SREQ_ONDEMAND, &subreq->flags))
+                       goto out_no_object;
        }
 
        /* The object and the file may be being created in the background. */
@@ -432,7 +434,7 @@ static enum netfs_io_source cachefiles_prepare_read(struct netfs_io_subrequest *
        object = cachefiles_cres_object(cres);
        cache = object->volume->cache;
        cachefiles_begin_secure(cache, &saved_cred);
-
+retry:
        off = cachefiles_inject_read_error();
        if (off == 0)
                off = vfs_llseek(file, subreq->start, SEEK_DATA);
@@ -483,6 +485,15 @@ static enum netfs_io_source cachefiles_prepare_read(struct netfs_io_subrequest *
 
 download_and_store:
        __set_bit(NETFS_SREQ_COPY_TO_CACHE, &subreq->flags);
+       if (test_bit(NETFS_SREQ_ONDEMAND, &subreq->flags)) {
+               rc = cachefiles_ondemand_read(object, subreq->start,
+                                             subreq->len);
+               if (!rc) {
+                       __clear_bit(NETFS_SREQ_ONDEMAND, &subreq->flags);
+                       goto retry;
+               }
+               ret = NETFS_INVALID_READ;
+       }
 out:
        cachefiles_end_secure(cache, saved_cred);
 out_no_object: