X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fllite%2Fvvp_object.c;h=04c8268293c6d02b81ec31b1b620f1fffc938d53;hb=f384d789b21689f72dc1ad03bfbf16b114748ea2;hp=498d3b262fc2be999a3cd88087e087e72b6d69c1;hpb=0603cc1a773dbe72f520e856743ef40fd7dfa1af;p=fs%2Flustre-release.git diff --git a/lustre/llite/vvp_object.c b/lustre/llite/vvp_object.c index 498d3b2..04c8268 100644 --- a/lustre/llite/vvp_object.c +++ b/lustre/llite/vvp_object.c @@ -27,7 +27,7 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2012, 2013, Intel Corporation. + * Copyright (c) 2012, 2014, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -40,15 +40,11 @@ #define DEBUG_SUBSYSTEM S_LLITE -#ifndef __KERNEL__ -# error This file is kernel only. -#endif #include #include -#include - +#include "llite_internal.h" #include "vvp_internal.h" /***************************************************************************** @@ -57,16 +53,26 @@ * */ +int vvp_object_invariant(const struct cl_object *obj) +{ + struct inode *inode = vvp_object_inode(obj); + struct ll_inode_info *lli = ll_i2info(inode); + + return (S_ISREG(inode->i_mode) || inode->i_mode == 0) && + lli->lli_clob == obj; +} + static int vvp_object_print(const struct lu_env *env, void *cookie, lu_printer_t p, const struct lu_object *o) { - struct ccc_object *obj = lu2ccc(o); - struct inode *inode = obj->cob_inode; + struct vvp_object *obj = lu2vvp(o); + struct inode *inode = obj->vob_inode; struct ll_inode_info *lli; (*p)(env, cookie, "(%s %d %d) inode: %p ", - list_empty(&obj->cob_pending_list) ? "-" : "+", - obj->cob_transient_pages, atomic_read(&obj->cob_mmap_cnt), + list_empty(&obj->vob_pending_list) ? "-" : "+", + atomic_read(&obj->vob_transient_pages), + atomic_read(&obj->vob_mmap_cnt), inode); if (inode) { lli = ll_i2info(inode); @@ -81,7 +87,7 @@ static int vvp_object_print(const struct lu_env *env, void *cookie, static int vvp_attr_get(const struct lu_env *env, struct cl_object *obj, struct cl_attr *attr) { - struct inode *inode = ccc_object_inode(obj); + struct inode *inode = vvp_object_inode(obj); /* * lov overwrites most of these fields in @@ -100,10 +106,10 @@ static int vvp_attr_get(const struct lu_env *env, struct cl_object *obj, return 0; /* layers below have to fill in the rest */ } -static int vvp_attr_set(const struct lu_env *env, struct cl_object *obj, - const struct cl_attr *attr, unsigned valid) +static int vvp_attr_update(const struct lu_env *env, struct cl_object *obj, + const struct cl_attr *attr, unsigned valid) { - struct inode *inode = ccc_object_inode(obj); + struct inode *inode = vvp_object_inode(obj); if (valid & CAT_UID) inode->i_uid = make_kuid(&init_user_ns, attr->cat_uid); @@ -116,7 +122,7 @@ static int vvp_attr_set(const struct lu_env *env, struct cl_object *obj, if (valid & CAT_CTIME) LTIME_S(inode->i_ctime) = attr->cat_ctime; if (0 && valid & CAT_SIZE) - cl_isize_write_nolock(inode, attr->cat_size); + i_size_write(inode, attr->cat_size); /* not currently necessary */ if (0 && valid & (CAT_UID|CAT_GID|CAT_SIZE)) mark_inode_dirty(inode); @@ -150,50 +156,137 @@ static int vvp_conf_set(const struct lu_env *env, struct cl_object *obj, static int vvp_prune(const struct lu_env *env, struct cl_object *obj) { - struct inode *inode = ccc_object_inode(obj); + struct inode *inode = vvp_object_inode(obj); int rc; ENTRY; - rc = cl_sync_file_range(inode, 0, OBD_OBJECT_EOF, CL_FSYNC_ALL, 1); - if (rc == 0) - truncate_inode_pages(inode->i_mapping, 0); + rc = cl_sync_file_range(inode, 0, OBD_OBJECT_EOF, CL_FSYNC_LOCAL, 1); + if (rc < 0) { + CDEBUG(D_VFSTRACE, DFID ": writeback failed: %d\n", + PFID(lu_object_fid(&obj->co_lu)), rc); + RETURN(rc); + } + + truncate_inode_pages(inode->i_mapping, 0); + RETURN(0); +} + +static int vvp_object_glimpse(const struct lu_env *env, + const struct cl_object *obj, struct ost_lvb *lvb) +{ + struct inode *inode = vvp_object_inode(obj); + + ENTRY; + lvb->lvb_mtime = LTIME_S(inode->i_mtime); + lvb->lvb_atime = LTIME_S(inode->i_atime); + lvb->lvb_ctime = LTIME_S(inode->i_ctime); + + /* + * LU-417: Add dirty pages block count lest i_blocks reports 0, some + * "cp" or "tar" on remote node may think it's a completely sparse file + * and skip it. + */ + if (lvb->lvb_size > 0 && lvb->lvb_blocks == 0) + lvb->lvb_blocks = dirty_cnt(inode); - RETURN(rc); + RETURN(0); } static const struct cl_object_operations vvp_ops = { - .coo_page_init = vvp_page_init, - .coo_lock_init = vvp_lock_init, - .coo_io_init = vvp_io_init, - .coo_attr_get = vvp_attr_get, - .coo_attr_set = vvp_attr_set, - .coo_conf_set = vvp_conf_set, - .coo_prune = vvp_prune, - .coo_glimpse = ccc_object_glimpse + .coo_page_init = vvp_page_init, + .coo_lock_init = vvp_lock_init, + .coo_io_init = vvp_io_init, + .coo_attr_get = vvp_attr_get, + .coo_attr_update = vvp_attr_update, + .coo_conf_set = vvp_conf_set, + .coo_prune = vvp_prune, + .coo_glimpse = vvp_object_glimpse }; +static int vvp_object_init0(const struct lu_env *env, + struct vvp_object *vob, + const struct cl_object_conf *conf) +{ + vob->vob_inode = conf->coc_inode; + atomic_set(&vob->vob_transient_pages, 0); + cl_object_page_init(&vob->vob_cl, sizeof(struct vvp_page)); + return 0; +} + +static int vvp_object_init(const struct lu_env *env, struct lu_object *obj, + const struct lu_object_conf *conf) +{ + struct vvp_device *dev = lu2vvp_dev(obj->lo_dev); + struct vvp_object *vob = lu2vvp(obj); + struct lu_object *below; + struct lu_device *under; + int result; + + under = &dev->vdv_next->cd_lu_dev; + below = under->ld_ops->ldo_object_alloc(env, obj->lo_header, under); + if (below != NULL) { + const struct cl_object_conf *cconf; + + cconf = lu2cl_conf(conf); + INIT_LIST_HEAD(&vob->vob_pending_list); + lu_object_add(obj, below); + result = vvp_object_init0(env, vob, cconf); + } else + result = -ENOMEM; + + return result; +} + +static void vvp_object_free(const struct lu_env *env, struct lu_object *obj) +{ + struct vvp_object *vob = lu2vvp(obj); + + lu_object_fini(obj); + lu_object_header_fini(obj->lo_header); + OBD_SLAB_FREE_PTR(vob, vvp_object_kmem); +} + static const struct lu_object_operations vvp_lu_obj_ops = { - .loo_object_init = ccc_object_init, - .loo_object_free = ccc_object_free, - .loo_object_print = vvp_object_print + .loo_object_init = vvp_object_init, + .loo_object_free = vvp_object_free, + .loo_object_print = vvp_object_print, }; -struct ccc_object *cl_inode2ccc(struct inode *inode) +struct vvp_object *cl_inode2vvp(struct inode *inode) { - struct cl_inode_info *lli = cl_i2info(inode); + struct ll_inode_info *lli = ll_i2info(inode); struct cl_object *obj = lli->lli_clob; struct lu_object *lu; LASSERT(obj != NULL); lu = lu_object_locate(obj->co_lu.lo_header, &vvp_device_type); LASSERT(lu != NULL); - return lu2ccc(lu); + + return lu2vvp(lu); } struct lu_object *vvp_object_alloc(const struct lu_env *env, - const struct lu_object_header *hdr, - struct lu_device *dev) + const struct lu_object_header *unused, + struct lu_device *dev) { - return ccc_object_alloc(env, hdr, dev, &vvp_ops, &vvp_lu_obj_ops); -} + struct vvp_object *vob; + struct lu_object *obj; + OBD_SLAB_ALLOC_PTR_GFP(vob, vvp_object_kmem, GFP_NOFS); + if (vob != NULL) { + struct cl_object_header *hdr; + + obj = &vob->vob_cl.co_lu; + hdr = &vob->vob_header; + cl_object_header_init(hdr); + hdr->coh_page_bufsize = cfs_size_round(sizeof(struct cl_page)); + + lu_object_init(obj, &hdr->coh_lu, dev); + lu_object_add_top(&hdr->coh_lu, obj); + + vob->vob_cl.co_ops = &vvp_ops; + obj->lo_ops = &vvp_lu_obj_ops; + } else + obj = NULL; + return obj; +}