X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Flclient%2Flcommon_cl.c;h=19cb4aa72cd858a8d6a7d5bfa8274e543bf6ee7e;hp=821ef6ec6df40c108fb7b29f51c890e48b15fc41;hb=53ed199c6dfe3958339a565098a607ddbd768c97;hpb=7796bdfb07954422e81b124ba176a5e431b43d8b diff --git a/lustre/lclient/lcommon_cl.c b/lustre/lclient/lcommon_cl.c index 821ef6e..19cb4aa 100644 --- a/lustre/lclient/lcommon_cl.c +++ b/lustre/lclient/lcommon_cl.c @@ -1,6 +1,4 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * +/* * GPL HEADER START * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -28,9 +26,8 @@ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. - */ -/* - * Copyright (c) 2011 Whamcloud, Inc. + * + * Copyright (c) 2011, 2012, Whamcloud, Inc. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -460,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. @@ -687,8 +700,7 @@ void ccc_lock_state(const struct lu_env *env, * 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); + ccc_object_size_lock(obj); rc = cl_object_attr_get(env, obj, attr); if (rc == 0) { if (lock->cll_descr.cld_start == 0 && @@ -705,10 +717,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; } /***************************************************************************** @@ -828,24 +839,6 @@ void ccc_io_advance(const struct lu_env *env, } } -static void ccc_object_size_lock(struct cl_object *obj, int vfslock) -{ - struct inode *inode = ccc_object_inode(obj); - - if (vfslock) - cl_isize_lock(inode, 0); - cl_object_attr_lock(obj); -} - -static void ccc_object_size_unlock(struct cl_object *obj, int vfslock) -{ - struct inode *inode = ccc_object_inode(obj); - - cl_object_attr_unlock(obj); - if (vfslock) - 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 @@ -856,13 +849,9 @@ static void ccc_object_size_unlock(struct cl_object *obj, int vfslock) * protect consistency between inode size and cl_object * attributes. cl_object_size_lock() protects consistency between cl_attr's of * top-object and sub-objects. - * - * In page fault path cl_isize_lock cannot be taken, client has to live with - * the resulting races. */ int ccc_prep_size(const struct lu_env *env, struct cl_object *obj, - struct cl_io *io, loff_t start, size_t count, int vfslock, - int *exceed) + struct cl_io *io, loff_t start, size_t count, int *exceed) { struct cl_attr *attr = ccc_env_thread_attr(env); struct inode *inode = ccc_object_inode(obj); @@ -889,7 +878,7 @@ int ccc_prep_size(const struct lu_env *env, struct cl_object *obj, * ll_inode_size_lock(). This guarantees that short reads are handled * correctly in the face of concurrent writes and truncates. */ - ccc_object_size_lock(obj, vfslock); + ccc_object_size_lock(obj); result = cl_object_attr_get(env, obj, attr); if (result == 0) { kms = attr->cat_kms; @@ -899,8 +888,8 @@ int ccc_prep_size(const struct lu_env *env, struct cl_object *obj, * return a short read (B) or some zeroes at the end * of the buffer (C) */ - ccc_object_size_unlock(obj, vfslock); - result = cl_glimpse_lock(env, io, inode, obj); + ccc_object_size_unlock(obj); + result = cl_glimpse_lock(env, io, inode, obj, 0); if (result == 0 && exceed != NULL) { /* If objective page index exceed end-of-file * page index, return directly. Do not expect @@ -926,24 +915,8 @@ int ccc_prep_size(const struct lu_env *env, struct cl_object *obj, * which will always be >= the kms value here. * b=11081 */ - /* - * XXX in a page fault path, change inode size without - * ll_inode_size_lock() held! there is a race - * condition with truncate path. (see ll_extent_lock) - */ - /* - * XXX i_size_write() is not used because it is not - * safe to take the ll_inode_size_lock() due to a - * potential lock inversion (bug 6077). And since - * it's not safe to use i_size_write() without a - * covering mutex we do the assignment directly. It - * is not critical that the size be correct. - */ if (cl_isize_read(inode) < kms) { - if (vfslock) - cl_isize_write_nolock(inode, kms); - else - cl_isize_write(inode, kms); + cl_isize_write_nolock(inode, kms); CDEBUG(D_VFSTRACE, DFID" updating i_size "LPU64"\n", PFID(lu_object_fid(&obj->co_lu)), @@ -952,7 +925,7 @@ int ccc_prep_size(const struct lu_env *env, struct cl_object *obj, } } } - ccc_object_size_unlock(obj, vfslock); + ccc_object_size_unlock(obj); return result; } @@ -1003,28 +976,30 @@ 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, &cl_i2info(inode)->lli_fid, - valid_flags & flags); + 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); +#endif } const struct cl_req_operations ccc_req_ops = { @@ -1056,10 +1031,18 @@ 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; - if (cl_io_init(env, io, CIT_SETATTR, io->ci_obj) == 0) + if (cl_io_init(env, io, CIT_SETATTR, io->ci_obj) == 0) { + struct ccc_io *cio = ccc_env_io(env); + + if (attr->ia_valid & ATTR_FILE) + /* populate the file descriptor for ftruncate to honor + * group lock - see LU-787 */ + cio->cui_fd = cl_iattr2fd(inode, attr); + result = cl_io_loop(env, io); - else + } else { result = io->ci_result; + } cl_io_fini(env, io); cl_env_put(env, &refcheck); RETURN(result); @@ -1349,3 +1332,13 @@ __u32 cl_fid_build_gen(const struct lu_fid *fid) gen = (fid_flatten(fid) >> 32); RETURN(gen); } + +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); +}