* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2012, 2013, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
/* prerequisite for linux/xattr.h */
#include <linux/fs.h>
-/* ext_depth() */
-#include <ldiskfs/ldiskfs.h>
-#include <ldiskfs/ldiskfs_jbd2.h>
-#include <ldiskfs/ldiskfs_extents.h>
-
/*
* struct OBD_{ALLOC,FREE}*()
* OBD_FAIL_CHECK
#include "osd_internal.h"
-#ifndef HAVE_PAGE_CONSTANT
-#define mapping_cap_page_constant_write(mapping) 0
-#define SetPageConstant(page) do {} while (0)
-#define ClearPageConstant(page) do {} while (0)
-#endif
-
-#ifndef HAS_GENERIC_ERROR_REMOVE_PAGE
-int generic_error_remove_page(struct address_space *mapping, struct page *page)
-{
- if (mapping == NULL)
- return -EINVAL;
-
- if (mapping != page->mapping)
- return -EIO;
- /*
- * Only punch for normal data pages for now.
- * Handling other types like directories would need more auditing.
- */
- if (!S_ISREG(mapping->host->i_mode))
- return -EIO;
-
- if (page_mapped(page)) {
- unmap_mapping_range(mapping,
- (loff_t)page->index << PAGE_CACHE_SHIFT,
- PAGE_CACHE_SIZE, 0);
- }
- truncate_complete_page(mapping, page);
- return 0;
-}
-#endif
+/* ext_depth() */
+#include <ldiskfs/ldiskfs_extents.h>
static int __osd_init_iobuf(struct osd_device *d, struct osd_iobuf *iobuf,
int rw, int line, int pages)
iobuf->dr_init_at);
LASSERT(pages <= PTLRPC_MAX_BRW_PAGES);
- cfs_waitq_init(&iobuf->dr_wait);
- cfs_atomic_set(&iobuf->dr_numreqs, 0);
- iobuf->dr_npages = 0;
- iobuf->dr_error = 0;
- iobuf->dr_dev = d;
- iobuf->dr_frags = 0;
- iobuf->dr_elapsed = 0;
- /* must be counted before, so assert */
- iobuf->dr_rw = rw;
+ init_waitqueue_head(&iobuf->dr_wait);
+ cfs_atomic_set(&iobuf->dr_numreqs, 0);
+ iobuf->dr_npages = 0;
+ iobuf->dr_error = 0;
+ iobuf->dr_dev = d;
+ iobuf->dr_frags = 0;
+ iobuf->dr_elapsed = 0;
+ /* must be counted before, so assert */
+ iobuf->dr_rw = rw;
iobuf->dr_init_at = line;
- blocks = pages * (CFS_PAGE_SIZE >> osd_sb(d)->s_blocksize_bits);
+ blocks = pages * (PAGE_CACHE_SIZE >> osd_sb(d)->s_blocksize_bits);
if (iobuf->dr_bl_buf.lb_len >= blocks * sizeof(iobuf->dr_blocks[0])) {
LASSERT(iobuf->dr_pg_buf.lb_len >=
pages * sizeof(iobuf->dr_pages[0]));
CDEBUG(D_OTHER, "realloc %u for %u (%u) pages\n",
(unsigned)(pages * sizeof(iobuf->dr_pages[0])), i, pages);
pages = i;
- blocks = pages * (CFS_PAGE_SIZE >> osd_sb(d)->s_blocksize_bits);
+ blocks = pages * (PAGE_CACHE_SIZE >> osd_sb(d)->s_blocksize_bits);
iobuf->dr_max_pages = 0;
CDEBUG(D_OTHER, "realloc %u for %u blocks\n",
(unsigned)(blocks * sizeof(iobuf->dr_blocks[0])), blocks);
if (likely(error == 0))
SetPageUptodate(bvl->bv_page);
LASSERT(PageLocked(bvl->bv_page));
- ClearPageConstant(bvl->bv_page);
}
cfs_atomic_dec(&iobuf->dr_dev->od_r_in_flight);
} else {
- struct page *p = iobuf->dr_pages[0];
- if (p->mapping) {
- if (mapping_cap_page_constant_write(p->mapping)) {
- bio_for_each_segment(bvl, bio, i) {
- ClearPageConstant(bvl->bv_page);
- }
- }
- }
cfs_atomic_dec(&iobuf->dr_dev->od_w_in_flight);
}
iobuf->dr_elapsed_valid = 1;
}
if (cfs_atomic_dec_and_test(&iobuf->dr_numreqs))
- cfs_waitq_signal(&iobuf->dr_wait);
+ wake_up(&iobuf->dr_wait);
/* Completed bios used to be chained off iobuf->dr_bios and freed in
* filter_clear_dreq(). It was then possible to exhaust the biovec-256
static int osd_do_bio(struct osd_device *osd, struct inode *inode,
struct osd_iobuf *iobuf)
{
- int blocks_per_page = CFS_PAGE_SIZE >> inode->i_blkbits;
+ int blocks_per_page = PAGE_CACHE_SIZE >> inode->i_blkbits;
struct page **pages = iobuf->dr_pages;
int npages = iobuf->dr_npages;
unsigned long *blocks = iobuf->dr_blocks;
sector_bits))
nblocks++;
- /* I only set the page to be constant only if it
- * is mapped to a contiguous underlying disk block(s).
- * It will then make sure the corresponding device
- * cache of raid5 will be overwritten by this page.
- * - jay */
- if (iobuf->dr_rw && (nblocks == blocks_per_page) &&
- mapping_cap_page_constant_write(inode->i_mapping))
- SetPageConstant(page);
-
if (bio != NULL &&
can_be_merged(bio, sector) &&
bio_add_page(bio, page,
bio->bi_size >> 9, queue_max_sectors(q),
bio_phys_segments(q, bio),
queue_max_phys_segments(q),
- bio_hw_segments(q, bio),
- queue_max_hw_segments(q));
+ 0, queue_max_hw_segments(q));
record_start_io(iobuf, bio->bi_size);
osd_submit_bio(iobuf->dr_rw, bio);
* parallel and wait for IO completion once transaction is stopped
* see osd_trans_stop() for more details -bzzz */
if (iobuf->dr_rw == 0) {
- cfs_wait_event(iobuf->dr_wait,
+ wait_event(iobuf->dr_wait,
cfs_atomic_read(&iobuf->dr_numreqs) == 0);
}
*nrpages = 0;
while (len > 0) {
- int poff = offset & (CFS_PAGE_SIZE - 1);
- int plen = CFS_PAGE_SIZE - poff;
+ int poff = offset & (PAGE_CACHE_SIZE - 1);
+ int plen = PAGE_CACHE_SIZE - poff;
if (plen > len)
plen = len;
LASSERT(inode);
- page = find_or_create_page(inode->i_mapping, offset >> CFS_PAGE_SHIFT,
+ page = find_or_create_page(inode->i_mapping, offset >> PAGE_CACHE_SHIFT,
GFP_NOFS | __GFP_HIGHMEM);
if (unlikely(page == NULL))
lprocfs_counter_add(d->od_stats, LPROC_OSD_NO_PAGE, 1);
RETURN(rc);
isize = i_size_read(inode);
- maxidx = ((isize + CFS_PAGE_SIZE - 1) >> CFS_PAGE_SHIFT) - 1;
+ maxidx = ((isize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT) - 1;
if (osd->od_writethrough_cache)
cache = 1;
if (isize > osd->od_readcache_max_filesize)
cache = 0;
- cfs_gettimeofday(&start);
- for (i = 0; i < npages; i++) {
+ do_gettimeofday(&start);
+ for (i = 0; i < npages; i++) {
if (cache == 0)
generic_error_remove_page(inode->i_mapping,
*/
ClearPageUptodate(lnb[i].page);
- if (lnb[i].len == CFS_PAGE_SIZE)
+ if (lnb[i].len == PAGE_CACHE_SIZE)
continue;
if (maxidx >= lnb[i].page->index) {
off = (lnb[i].lnb_page_offset + lnb[i].len) &
~CFS_PAGE_MASK;
if (off)
- memset(p + off, 0, CFS_PAGE_SIZE - off);
+ memset(p + off, 0, PAGE_CACHE_SIZE - off);
kunmap(lnb[i].page);
- }
- }
- cfs_gettimeofday(&end);
- timediff = cfs_timeval_sub(&end, &start, NULL);
- lprocfs_counter_add(osd->od_stats, LPROC_OSD_GET_PAGE, timediff);
+ }
+ }
+ do_gettimeofday(&end);
+ timediff = cfs_timeval_sub(&end, &start, NULL);
+ lprocfs_counter_add(osd->od_stats, LPROC_OSD_GET_PAGE, timediff);
if (iobuf->dr_npages) {
rc = osd->od_fsops->fs_map_inode_pages(inode, iobuf->dr_pages,
extents++;
if (!osd_is_mapped(inode, lnb[i].lnb_file_offset))
- quota_space += CFS_PAGE_SIZE;
+ quota_space += PAGE_CACHE_SIZE;
/* ignore quota for the whole request if any page is from
* client cache or written by root.
*
+ * XXX once we drop the 1.8 client support, the checking
+ * for whether page is from cache can be simplified as:
+ * !(lnb[i].flags & OBD_BRW_SYNC)
+ *
* XXX we could handle this on per-lnb basis as done by
* grant. */
if ((lnb[i].flags & OBD_BRW_NOQUOTA) ||
- !(lnb[i].flags & OBD_BRW_SYNC))
+ (lnb[i].flags & (OBD_BRW_FROM_GRANT | OBD_BRW_SYNC)) ==
+ OBD_BRW_FROM_GRANT)
ignore_quota = true;
}
if (isize > i_size_read(inode)) {
i_size_write(inode, isize);
LDISKFS_I(inode)->i_disksize = isize;
- inode->i_sb->s_op->dirty_inode(inode);
+ ll_dirty_inode(inode, I_DIRTY_DATASYNC);
}
rc = osd_do_bio(osd, inode, iobuf);
if (i_size_read(inode) > osd->od_readcache_max_filesize)
cache = 0;
- cfs_gettimeofday(&start);
- for (i = 0; i < npages; i++) {
+ do_gettimeofday(&start);
+ for (i = 0; i < npages; i++) {
if (i_size_read(inode) <= lnb[i].lnb_file_offset)
/* If there's no more data, abort early.
LPROC_OSD_CACHE_MISS, 1);
osd_iobuf_add_page(iobuf, lnb[i].page);
}
- if (cache == 0)
- generic_error_remove_page(inode->i_mapping,lnb[i].page);
- }
- cfs_gettimeofday(&end);
- timediff = cfs_timeval_sub(&end, &start, NULL);
- lprocfs_counter_add(osd->od_stats, LPROC_OSD_GET_PAGE, timediff);
+ if (cache == 0)
+ generic_error_remove_page(inode->i_mapping,lnb[i].page);
+ }
+ do_gettimeofday(&end);
+ timediff = cfs_timeval_sub(&end, &start, NULL);
+ lprocfs_counter_add(osd->od_stats, LPROC_OSD_GET_PAGE, timediff);
if (iobuf->dr_npages) {
rc = osd->od_fsops->fs_map_inode_pages(inode, iobuf->dr_pages,
oh = container_of0(handle, struct osd_thandle, ot_super);
LASSERT(oh->ot_handle == NULL);
- /* XXX: size == 0 or INT_MAX indicating a catalog header update or
- * llog write, see comment in mdd_declare_llog_record().
- *
- * This hack will be removed with llog over OSD landing
- */
- if (size == DECLARE_LLOG_REWRITE)
- credits = 2;
- else if (size == DECLARE_LLOG_WRITE)
- credits = 6;
- else
- credits = osd_dto_credits_noquota[DTO_WRITE_BLOCK];
+ credits = osd_dto_credits_noquota[DTO_WRITE_BLOCK];
osd_trans_declare_op(env, oh, OSD_OT_WRITE, credits);
memcpy((char *)&LDISKFS_I(inode)->i_data, (char *)buffer, buflen);
LDISKFS_I(inode)->i_disksize = buflen;
i_size_write(inode, buflen);
- inode->i_sb->s_op->dirty_inode(inode);
+ ll_dirty_inode(inode, I_DIRTY_DATASYNC);
return 0;
}
dirty_inode = 1;
}
spin_unlock(&inode->i_lock);
- if (dirty_inode)
- inode->i_sb->s_op->dirty_inode(inode);
+ if (dirty_inode)
+ ll_dirty_inode(inode, I_DIRTY_DATASYNC);
}
if (err == 0)
struct inode *inode = obj->oo_inode;
handle_t *h;
tid_t tid;
- int rc, rc2 = 0;
+ loff_t oldsize;
+ int rc = 0, rc2 = 0;
ENTRY;
LASSERT(end == OBD_OBJECT_EOF);
tid = oh->ot_handle->h_transaction->t_tid;
- rc = vmtruncate(inode, start);
+ oldsize=inode->i_size;
+ i_size_write(inode, start);
+ truncate_pagecache(inode, oldsize, start);
+ if (inode->i_op->truncate)
+ inode->i_op->truncate(inode);
/*
* For a partial-page truncate, flush the page to disk immediately to
* avoid data corruption during direct disk write. b=17397
*/
- if (rc == 0 && (start & ~CFS_PAGE_MASK) != 0)
+ if ((start & ~CFS_PAGE_MASK) != 0)
rc = filemap_fdatawrite_range(inode->i_mapping, start, start+1);
h = journal_current_handle();
LASSERT(inode);
dentry->d_inode = inode;
+ dentry->d_sb = inode->i_sb;
file->f_dentry = dentry;
file->f_mapping = inode->i_mapping;
file->f_op = inode->i_fop;
.dbo_declare_write_commit = osd_declare_write_commit,
.dbo_write_commit = osd_write_commit,
.dbo_read_prep = osd_read_prep,
- .do_declare_punch = osd_declare_punch,
- .do_punch = osd_punch,
+ .dbo_declare_punch = osd_declare_punch,
+ .dbo_punch = osd_punch,
.dbo_fiemap_get = osd_fiemap_get,
};