Whamcloud - gitweb
LU-13528 llite: prevent MAX_DIO_SIZE 32-bit truncation
[fs/lustre-release.git] / lustre / llite / rw26.c
index 6e889a1..5c4dd7b 100644 (file)
@@ -384,7 +384,7 @@ ll_direct_rw_pages(const struct lu_env *env, struct cl_io *io, size_t size,
  * then truncate this to be a full-sized RPC.  For 4kB PAGE_SIZE this is
  * up to 22MB for 128kB kmalloc and up to 682MB for 4MB kmalloc. */
 #define MAX_DIO_SIZE ((MAX_MALLOC / sizeof(struct brw_page) * PAGE_SIZE) & \
-                     ~(DT_MAX_BRW_SIZE - 1))
+                     ~((size_t)DT_MAX_BRW_SIZE - 1))
 
 static ssize_t
 ll_direct_IO_impl(struct kiocb *iocb, struct iov_iter *iter, int rw)
@@ -598,11 +598,11 @@ out:
        return result;
 }
 
-static int ll_tiny_write_begin(struct page *vmpage)
+static int ll_tiny_write_begin(struct page *vmpage, struct address_space *mapping)
 {
        /* Page must be present, up to date, dirty, and not in writeback. */
        if (!vmpage || !PageUptodate(vmpage) || !PageDirty(vmpage) ||
-           PageWriteback(vmpage))
+           PageWriteback(vmpage) || vmpage->mapping != mapping)
                return -ENODATA;
 
        return 0;
@@ -630,7 +630,7 @@ static int ll_write_begin(struct file *file, struct address_space *mapping,
        lcc = ll_cl_find(file);
        if (lcc == NULL) {
                vmpage = grab_cache_page_nowait(mapping, index);
-               result = ll_tiny_write_begin(vmpage);
+               result = ll_tiny_write_begin(vmpage, mapping);
                GOTO(out, result);
        }
 
@@ -689,6 +689,15 @@ again:
                }
        }
 
+       /* page was truncated */
+       if (mapping != vmpage->mapping) {
+               CDEBUG(D_VFSTRACE, "page: %lu was truncated\n", index);
+               unlock_page(vmpage);
+               put_page(vmpage);
+               vmpage = NULL;
+               goto again;
+       }
+
        page = cl_page_find(env, clob, vmpage->index, vmpage, CPT_CACHEABLE);
        if (IS_ERR(page))
                GOTO(out, result = PTR_ERR(page));