X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fllite%2Fvvp_io.c;h=55e21fa4e412d0b7c7b83ca560cd107d3a7871d1;hb=985de582849dfc25ccbf2ef6ea923f984ad7fd89;hp=94f989995dc2d9e984811c47aa4dde24b6f5604c;hpb=788e464a7215e09987e05eeeeac107642e80cea5;p=fs%2Flustre-release.git diff --git a/lustre/llite/vvp_io.c b/lustre/llite/vvp_io.c index 94f9899..55e21fa 100644 --- a/lustre/llite/vvp_io.c +++ b/lustre/llite/vvp_io.c @@ -37,10 +37,10 @@ #define DEBUG_SUBSYSTEM S_LLITE - #include #include #include + #include "llite_internal.h" #include "vvp_internal.h" #include @@ -648,13 +648,16 @@ static int vvp_io_setattr_lock(const struct lu_env *env, const struct cl_io_slice *ios) { struct cl_io *io = ios->cis_io; - __u64 new_size; + __u64 lock_start = 0; + __u64 lock_end = OBD_OBJECT_EOF; __u32 enqflags = 0; if (cl_io_is_trunc(io)) { - new_size = io->u.ci_setattr.sa_attr.lvb_size; - if (new_size == 0) + if (io->u.ci_setattr.sa_attr.lvb_size == 0) enqflags = CEF_DISCARD_DATA; + } else if (cl_io_is_fallocate(io)) { + lock_start = io->u.ci_setattr.sa_falloc_offset; + lock_end = lock_start + io->u.ci_setattr.sa_attr.lvb_size; } else { unsigned int valid = io->u.ci_setattr.sa_avalid; @@ -668,12 +671,10 @@ static int vvp_io_setattr_lock(const struct lu_env *env, io->u.ci_setattr.sa_attr.lvb_atime >= io->u.ci_setattr.sa_attr.lvb_ctime)) return 0; - - new_size = 0; } return vvp_io_one_lock(env, io, enqflags, CLM_WRITE, - new_size, OBD_OBJECT_EOF); + lock_start, lock_end); } static int vvp_do_vmtruncate(struct inode *inode, size_t size) @@ -732,6 +733,9 @@ static int vvp_io_setattr_start(const struct lu_env *env, trunc_sem_down_write(&lli->lli_trunc_sem); inode_lock(inode); inode_dio_wait(inode); + } else if (cl_io_is_fallocate(io)) { + inode_lock(inode); + inode_dio_wait(inode); } else { inode_lock(inode); } @@ -755,6 +759,8 @@ static void vvp_io_setattr_end(const struct lu_env *env, vvp_do_vmtruncate(inode, io->u.ci_setattr.sa_attr.lvb_size); inode_unlock(inode); trunc_sem_up_write(&lli->lli_trunc_sem); + } else if (cl_io_is_fallocate(io)) { + inode_unlock(inode); } else { inode_unlock(inode); } @@ -953,7 +959,7 @@ static inline void ll_account_page_dirtied(struct page *page, static inline void ll_page_tag_dirty(struct page *page, struct address_space *mapping) { -#ifdef HAVE___XA_SET_MARK +#ifndef HAVE_RADIX_TREE_TAG_SET __xa_set_mark(&mapping->i_pages, page_index(page), PAGECACHE_TAG_DIRTY); #else radix_tree_tag_set(&mapping->page_tree, page_index(page), @@ -986,11 +992,11 @@ void vvp_set_pagevec_dirty(struct pagevec *pvec) ClearPageReclaim(pvec->pages[i]); LASSERTF(page->mapping, - "mapping must be set. page %p, page->private (cl_page) %p", + "mapping must be set. page %p, page->private (cl_page) %p\n", page, (void *) page->private); /* Rest of code derived from __set_page_dirty_nobuffers */ - xa_lock_irqsave(&mapping->i_pages, flags); + ll_xa_lock_irqsave(&mapping->i_pages, flags); /* Notes on differences with __set_page_dirty_nobuffers: * 1. We don't need to call page_mapping because we know this is a page @@ -1020,7 +1026,7 @@ void vvp_set_pagevec_dirty(struct pagevec *pvec) dirtied++; unlock_page_memcg(page); } - xa_unlock_irqrestore(&mapping->i_pages, flags); + ll_xa_unlock_irqrestore(&mapping->i_pages, flags); CDEBUG(D_VFSTRACE, "mapping %p, count %d, dirtied %d\n", mapping, count, dirtied); @@ -1181,6 +1187,7 @@ static int vvp_io_write_start(const struct lu_env *env, size_t cnt = io->u.ci_wr.wr.crw_count; bool lock_inode = !IS_NOSEC(inode); size_t nob = io->ci_nob; + struct iov_iter iter; size_t written = 0; ENTRY; @@ -1243,6 +1250,7 @@ static int vvp_io_write_start(const struct lu_env *env, * trucates, etc. is handled in the higher layers of lustre. */ lock_inode = !IS_NOSEC(inode); + iter = *vio->vui_iter; if (unlikely(lock_inode)) inode_lock(inode); @@ -1269,12 +1277,20 @@ static int vvp_io_write_start(const struct lu_env *env, if (result > 0) { result = vvp_io_write_commit(env, io); + /* Simulate short commit */ + if (CFS_FAULT_CHECK(OBD_FAIL_LLITE_SHORT_COMMIT)) { + vio->u.write.vui_written >>= 1; + if (vio->u.write.vui_written > 0) + io->ci_need_restart = 1; + } if (vio->u.write.vui_written > 0) { result = vio->u.write.vui_written; CDEBUG(D_VFSTRACE, "%s: write nob %zd, result: %zd\n", file_dentry(file)->d_name.name, io->ci_nob, result); io->ci_nob += result; + } else { + io->ci_continue = 0; } } if (vio->vui_iocb->ki_pos != (pos + io->ci_nob - nob)) { @@ -1284,8 +1300,16 @@ static int vvp_io_write_start(const struct lu_env *env, file_dentry(file)->d_name.name, vio->vui_iocb->ki_pos, pos + io->ci_nob - nob, written, io->ci_nob - nob, result); - /* rewind ki_pos to where it has successfully committed */ + /* + * Rewind ki_pos and vui_iter to where it has + * successfully committed. + */ vio->vui_iocb->ki_pos = pos + io->ci_nob - nob; + iov_iter_advance(&iter, io->ci_nob - nob); + vio->vui_iter->iov = iter.iov; + vio->vui_iter->nr_segs = iter.nr_segs; + vio->vui_iter->iov_offset = iter.iov_offset; + vio->vui_iter->count = iter.count; } if (result > 0 || result == -EIOCBQUEUED) { ll_file_set_flag(ll_i2info(inode), LLIF_DATA_MODIFIED);