X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Flclient%2Flcommon_cl.c;h=41ebae95d757dcb5b7c4f6cad057f41d5d0c78fd;hb=9ac37e061515ed6a3efcc8aca87ce71f6fff2a18;hp=05c348d6292331a65bdb51c46d0ab9c5a4534cd9;hpb=60b5c3e464d6b4b333506e6db6b0635bb5a06577;p=fs%2Flustre-release.git diff --git a/lustre/lclient/lcommon_cl.c b/lustre/lclient/lcommon_cl.c index 05c348d..41ebae9 100644 --- a/lustre/lclient/lcommon_cl.c +++ b/lustre/lclient/lcommon_cl.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) 2011, 2012, Whamcloud, Inc. + * Copyright (c) 2011, 2012, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -46,7 +46,6 @@ # include # include # include -# include # include # include # include @@ -290,7 +289,7 @@ static struct lu_env *ccc_inode_fini_env = NULL; * A mutex serializing calls to slp_inode_fini() under extreme memory * pressure, when environments cannot be allocated. */ -static CFS_DEFINE_MUTEX(ccc_inode_fini_guard); +static DEFINE_MUTEX(ccc_inode_fini_guard); static int dummy_refcheck; int ccc_global_init(struct lu_device_type *device_type) @@ -369,6 +368,7 @@ int ccc_object_init0(const struct lu_env *env, { vob->cob_inode = conf->coc_inode; vob->cob_transient_pages = 0; + cl_object_page_init(&vob->cob_cl, sizeof(struct ccc_page)); return 0; } @@ -457,6 +457,22 @@ int ccc_conf_set(const struct lu_env *env, struct cl_object *obj, return 0; } +static void ccc_object_size_lock(struct cl_object *obj) +{ + struct inode *inode = ccc_object_inode(obj); + + cl_isize_lock(inode); + cl_object_attr_lock(obj); +} + +static void ccc_object_size_unlock(struct cl_object *obj) +{ + struct inode *inode = ccc_object_inode(obj); + + cl_object_attr_unlock(obj); + cl_isize_unlock(inode); +} + /***************************************************************************** * * Page operations. @@ -668,24 +684,22 @@ void ccc_lock_state(const struct lu_env *env, * of finding lock in the cache. */ if (state == CLS_HELD && lock->cll_state < CLS_HELD) { - int rc; - - obj = slice->cls_obj; - inode = ccc_object_inode(obj); - attr = ccc_env_thread_attr(env); - - /* vmtruncate()->ll_truncate() first sets the i_size and then - * the kms under both a DLM lock and the - * ll_inode_size_lock(). If we don't get the - * ll_inode_size_lock() here we can match the DLM lock and - * reset i_size from the kms before the truncating path has - * updated the kms. generic_file_write can then trust the - * stale i_size when doing appending writes and effectively - * cancel the result of the truncate. Getting the - * ll_inode_size_lock() after the enqueue maintains the DLM - * -> ll_inode_size_lock() acquiring order. */ - cl_isize_lock(inode, 0); - cl_object_attr_lock(obj); + int rc; + + obj = slice->cls_obj; + inode = ccc_object_inode(obj); + attr = ccc_env_thread_attr(env); + + /* vmtruncate() sets the i_size + * under both a DLM lock and the + * ll_inode_size_lock(). If we don't get the + * ll_inode_size_lock() here we can match the DLM lock and + * reset i_size. generic_file_write can then trust the + * stale i_size when doing appending writes and effectively + * cancel the result of the truncate. Getting the + * ll_inode_size_lock() after the enqueue maintains the DLM + * -> ll_inode_size_lock() acquiring order. */ + ccc_object_size_lock(obj); rc = cl_object_attr_get(env, obj, attr); if (rc == 0) { if (lock->cll_descr.cld_start == 0 && @@ -702,10 +716,9 @@ void ccc_lock_state(const struct lu_env *env, } else { CL_LOCK_DEBUG(D_INFO, env, lock, "attr_get: %d\n", rc); } - cl_object_attr_unlock(obj); - cl_isize_unlock(inode, 0); - } - EXIT; + ccc_object_size_unlock(obj); + } + EXIT; } /***************************************************************************** @@ -825,22 +838,6 @@ void ccc_io_advance(const struct lu_env *env, } } -static void ccc_object_size_lock(struct cl_object *obj) -{ - struct inode *inode = ccc_object_inode(obj); - - cl_isize_lock(inode, 0); - cl_object_attr_lock(obj); -} - -static void ccc_object_size_unlock(struct cl_object *obj) -{ - struct inode *inode = ccc_object_inode(obj); - - cl_object_attr_unlock(obj); - cl_isize_unlock(inode, 0); -} - /** * Helper function that if necessary adjusts file size (inode->i_size), when * position at the offset \a pos is accessed. File size can be arbitrary stale @@ -978,28 +975,26 @@ void ccc_req_attr_set(const struct lu_env *env, struct obdo *oa; obd_flag valid_flags; - oa = attr->cra_oa; - inode = ccc_object_inode(obj); - valid_flags = OBD_MD_FLTYPE|OBD_MD_FLATIME; - - if (flags != (obd_valid)~0ULL) - valid_flags |= OBD_MD_FLMTIME|OBD_MD_FLCTIME|OBD_MD_FLATIME; - else { - LASSERT(attr->cra_capa == NULL); - attr->cra_capa = cl_capa_lookup(inode, - slice->crs_req->crq_type); - } - - if (slice->crs_req->crq_type == CRT_WRITE) { - if (flags & OBD_MD_FLEPOCH) { - oa->o_valid |= OBD_MD_FLEPOCH; - oa->o_ioepoch = cl_i2info(inode)->lli_ioepoch; - valid_flags |= OBD_MD_FLMTIME|OBD_MD_FLCTIME| - OBD_MD_FLUID|OBD_MD_FLGID; - } - } - obdo_from_inode(oa, inode, valid_flags & flags); - obdo_set_parent_fid(oa, &cl_i2info(inode)->lli_fid); + oa = attr->cra_oa; + inode = ccc_object_inode(obj); + valid_flags = OBD_MD_FLTYPE; + + if ((flags & OBD_MD_FLOSSCAPA) != 0) { + LASSERT(attr->cra_capa == NULL); + attr->cra_capa = cl_capa_lookup(inode, + slice->crs_req->crq_type); + } + + if (slice->crs_req->crq_type == CRT_WRITE) { + if (flags & OBD_MD_FLEPOCH) { + oa->o_valid |= OBD_MD_FLEPOCH; + oa->o_ioepoch = cl_i2info(inode)->lli_ioepoch; + valid_flags |= OBD_MD_FLMTIME | OBD_MD_FLCTIME | + OBD_MD_FLUID | OBD_MD_FLGID; + } + } + obdo_from_inode(oa, inode, valid_flags & flags); + obdo_set_parent_fid(oa, &cl_i2info(inode)->lli_fid); #ifdef __KERNEL__ memcpy(attr->cra_jobid, cl_i2info(inode)->lli_jobid, JOBSTATS_JOBID_SIZE); @@ -1035,6 +1030,7 @@ int cl_setattr_ost(struct inode *inode, const struct iattr *attr, io->u.ci_setattr.sa_valid = attr->ia_valid; io->u.ci_setattr.sa_capa = capa; +again: if (cl_io_init(env, io, CIT_SETATTR, io->ci_obj) == 0) { struct ccc_io *cio = ccc_env_io(env); @@ -1048,8 +1044,10 @@ int cl_setattr_ost(struct inode *inode, const struct iattr *attr, result = io->ci_result; } cl_io_fini(env, io); - cl_env_put(env, &refcheck); - RETURN(result); + if (unlikely(io->ci_need_restart)) + goto again; + cl_env_put(env, &refcheck); + RETURN(result); } /***************************************************************************** @@ -1196,15 +1194,16 @@ int cl_file_inode_init(struct inode *inode, struct lustre_md *md) /* * No locking is necessary, as new inode is * locked by I_NEW bit. - * - * XXX not true for call from ll_update_inode(). */ lli->lli_clob = clob; + lli->lli_has_smd = md->lsm != NULL; lu_object_ref_add(&clob->co_lu, "inode", inode); } else result = PTR_ERR(clob); - } else - result = cl_conf_set(env, lli->lli_clob, &conf); + } else { + result = cl_conf_set(env, lli->lli_clob, &conf); + } + cl_env_put(env, &refcheck); if (result != 0) @@ -1265,7 +1264,7 @@ void cl_inode_fini(struct inode *inode) env = cl_env_get(&refcheck); emergency = IS_ERR(env); if (emergency) { - cfs_mutex_lock(&ccc_inode_fini_guard); + mutex_lock(&ccc_inode_fini_guard); LASSERT(ccc_inode_fini_env != NULL); cl_env_implant(ccc_inode_fini_env, &refcheck); env = ccc_inode_fini_env; @@ -1281,7 +1280,7 @@ void cl_inode_fini(struct inode *inode) lli->lli_clob = NULL; if (emergency) { cl_env_unplant(ccc_inode_fini_env, &refcheck); - cfs_mutex_unlock(&ccc_inode_fini_guard); + mutex_unlock(&ccc_inode_fini_guard); } else cl_env_put(env, &refcheck); cl_env_reexit(cookie); @@ -1336,3 +1335,21 @@ __u32 cl_fid_build_gen(const struct lu_fid *fid) gen = (fid_flatten(fid) >> 32); RETURN(gen); } + +/* lsm is unreliable after hsm implementation as layout can be changed at + * any time. This is only to support old, non-clio-ized interfaces. It will + * cause deadlock if clio operations are called with this extra layout refcount + * because in case the layout changed during the IO, ll_layout_refresh() will + * have to wait for the refcount to become zero to destroy the older layout. + * + * Notice that the lsm returned by this function may not be valid unless called + * inside layout lock - MDS_INODELOCK_LAYOUT. */ +struct lov_stripe_md *ccc_inode_lsm_get(struct inode *inode) +{ + return lov_lsm_get(cl_i2info(inode)->lli_clob); +} + +void inline ccc_inode_lsm_put(struct inode *inode, struct lov_stripe_md *lsm) +{ + lov_lsm_put(cl_i2info(inode)->lli_clob, lsm); +}