static errcode_t ocfs2_try_to_write_inline_data(ocfs2_cached_inode *ci, void *buf, uint32_t count, uint64_t offset) { int ret; uint64_t end = offset + count; ocfs2_filesys *fs = ci->ci_fs; struct ocfs2_dinode *di = ci->ci_inode; /* Handle inodes which already have inline data 1st. */ if (di->i_dyn_features & OCFS2_INLINE_DATA_FL) { if (ocfs2_size_fits_inline_data(ci->ci_inode, end)) goto do_inline_write; /* * The write won't fit - we have to give this inode an * inline extent list now. */ ret = ocfs2_convert_inline_data_to_extents(ci); if (!ret) ret = OCFS2_ET_CANNOT_INLINE_DATA; goto out; } if (di->i_clusters > 0 || end > ocfs2_max_inline_data(fs->fs_blocksize)) return OCFS2_ET_CANNOT_INLINE_DATA; ocfs2_set_inode_data_inline(fs, ci->ci_inode); ci->ci_inode->i_dyn_features |= OCFS2_INLINE_DATA_FL; do_inline_write: ret = ocfs2_inline_data_write(di, buf, count, offset); if (ret) goto out; ret = ocfs2_write_cached_inode(fs, ci); out: return ret; }
int ocfs2_read_inline_data(struct inode *inode, struct page *page, struct buffer_head *di_bh) { void *kaddr; loff_t size; struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data; if (!(le16_to_cpu(di->i_dyn_features) & OCFS2_INLINE_DATA_FL)) { ocfs2_error(inode->i_sb, "Inode %llu lost inline data flag", (unsigned long long)OCFS2_I(inode)->ip_blkno); return -EROFS; } size = i_size_read(inode); if (size > PAGE_CACHE_SIZE || size > ocfs2_max_inline_data(inode->i_sb)) { ocfs2_error(inode->i_sb, "Inode %llu has with inline data has bad size: %Lu", (unsigned long long)OCFS2_I(inode)->ip_blkno, (unsigned long long)size); return -EROFS; } kaddr = kmap_atomic(page, KM_USER0); if (size) memcpy(kaddr, di->id2.i_data.id_data, size); /* Clear the remaining part of the page */ memset(kaddr + size, 0, PAGE_CACHE_SIZE - size); flush_dcache_page(page); kunmap_atomic(kaddr, KM_USER0); SetPageUptodate(page); return 0; }