aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph/addr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ceph/addr.c')
-rw-r--r--fs/ceph/addr.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index f2c7aa878aa4..4a3f55f27ab4 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -1318,6 +1318,49 @@ out:
1318 return ret; 1318 return ret;
1319} 1319}
1320 1320
1321void ceph_fill_inline_data(struct inode *inode, struct page *locked_page,
1322 char *data, size_t len)
1323{
1324 struct address_space *mapping = inode->i_mapping;
1325 struct page *page;
1326
1327 if (locked_page) {
1328 page = locked_page;
1329 } else {
1330 if (i_size_read(inode) == 0)
1331 return;
1332 page = find_or_create_page(mapping, 0,
1333 mapping_gfp_mask(mapping) & ~__GFP_FS);
1334 if (!page)
1335 return;
1336 if (PageUptodate(page)) {
1337 unlock_page(page);
1338 page_cache_release(page);
1339 return;
1340 }
1341 }
1342
1343 dout("fill_inline_data %p %llx.%llx len %lu locked_page %p\n",
1344 inode, ceph_vinop(inode), len, locked_page);
1345
1346 if (len > 0) {
1347 void *kaddr = kmap_atomic(page);
1348 memcpy(kaddr, data, len);
1349 kunmap_atomic(kaddr);
1350 }
1351
1352 if (page != locked_page) {
1353 if (len < PAGE_CACHE_SIZE)
1354 zero_user_segment(page, len, PAGE_CACHE_SIZE);
1355 else
1356 flush_dcache_page(page);
1357
1358 SetPageUptodate(page);
1359 unlock_page(page);
1360 page_cache_release(page);
1361 }
1362}
1363
1321static struct vm_operations_struct ceph_vmops = { 1364static struct vm_operations_struct ceph_vmops = {
1322 .fault = ceph_filemap_fault, 1365 .fault = ceph_filemap_fault,
1323 .page_mkwrite = ceph_page_mkwrite, 1366 .page_mkwrite = ceph_page_mkwrite,