Ejemplo n.º 1
0
static void osc_io_setattr_end(const struct lu_env *env,
			       const struct cl_io_slice *slice)
{
	struct cl_io     *io  = slice->cis_io;
	struct osc_io    *oio = cl2osc_io(env, slice);
	struct cl_object *obj = slice->cis_obj;
	struct osc_async_cbargs *cbargs = &oio->oi_cbarg;
	int result = 0;

	if (cbargs->opc_rpc_sent) {
		wait_for_completion(&cbargs->opc_sync);
		result = io->ci_result = cbargs->opc_rc;
	}
	if (result == 0) {
		if (oio->oi_lockless) {
			/* lockless truncate */
			struct osc_device *osd = lu2osc_dev(obj->co_lu.lo_dev);

			LASSERT(cl_io_is_trunc(io));
			/* XXX: Need a lock. */
			osd->od_stats.os_lockless_truncates++;
		}
	}

	if (cl_io_is_trunc(io)) {
		__u64 size = io->u.ci_setattr.sa_attr.lvb_size;

		osc_trunc_check(env, io, oio, size);
		if (oio->oi_trunc != NULL) {
			osc_cache_truncate_end(env, oio, cl2osc(obj));
			oio->oi_trunc = NULL;
		}
	}
}
Ejemplo n.º 2
0
static void vvp_io_setattr_end(const struct lu_env *env,
                               const struct cl_io_slice *ios)
{
	struct cl_io *io    = ios->cis_io;
	struct inode *inode = ccc_object_inode(io->ci_obj);

	if (cl_io_is_trunc(io)) {
		/* Truncate in memory pages - they must be clean pages
		 * because osc has already notified to destroy osc_extents. */
		vvp_do_vmtruncate(inode, io->u.ci_setattr.sa_attr.lvb_size);
		inode_dio_write_done(inode);
	}
	mutex_unlock(&inode->i_mutex);
}
Ejemplo n.º 3
0
static int vvp_io_setattr_start(const struct lu_env *env,
				const struct cl_io_slice *ios)
{
	struct cl_io	*io    = ios->cis_io;
	struct inode	*inode = ccc_object_inode(io->ci_obj);
	int result = 0;

	mutex_lock(&inode->i_mutex);
	if (cl_io_is_trunc(io))
		result = vvp_io_setattr_trunc(env, ios, inode,
					io->u.ci_setattr.sa_attr.lvb_size);
	if (result == 0)
		result = vvp_io_setattr_time(env, ios);
	return result;
}
Ejemplo n.º 4
0
/**
 * Implementation of cl_io_operations::cio_lock() method for CIT_SETATTR io.
 *
 * Handles "lockless io" mode when extent locking is done by server.
 */
static int vvp_io_setattr_lock(const struct lu_env *env,
                               const struct cl_io_slice *ios)
{
	struct ccc_io *cio = ccc_env_io(env);
	struct cl_io  *io  = ios->cis_io;
	__u64 new_size;
	__u32 enqflags = 0;

        if (cl_io_is_trunc(io)) {
                new_size = io->u.ci_setattr.sa_attr.lvb_size;
                if (new_size == 0)
                        enqflags = CEF_DISCARD_DATA;
        } else {
                if ((io->u.ci_setattr.sa_attr.lvb_mtime >=
                     io->u.ci_setattr.sa_attr.lvb_ctime) ||
                    (io->u.ci_setattr.sa_attr.lvb_atime >=
                     io->u.ci_setattr.sa_attr.lvb_ctime))
                        return 0;
                new_size = 0;
        }
        cio->u.setattr.cui_local_lock = SETATTR_EXTENT_LOCK;
        return ccc_io_one_lock(env, io, enqflags, CLM_WRITE,
                               new_size, OBD_OBJECT_EOF);
}
Ejemplo n.º 5
0
static int osc_io_setattr_start(const struct lu_env *env,
				const struct cl_io_slice *slice)
{
	struct cl_io	    *io     = slice->cis_io;
	struct osc_io	   *oio    = cl2osc_io(env, slice);
	struct cl_object	*obj    = slice->cis_obj;
	struct lov_oinfo	*loi    = cl2osc(obj)->oo_oinfo;
	struct cl_attr	  *attr   = &osc_env_info(env)->oti_attr;
	struct obdo	     *oa     = &oio->oi_oa;
	struct osc_async_cbargs *cbargs = &oio->oi_cbarg;
	__u64		    size   = io->u.ci_setattr.sa_attr.lvb_size;
	unsigned int	     ia_valid = io->u.ci_setattr.sa_valid;
	int		      result = 0;
	struct obd_info	  oinfo = { { { 0 } } };

	/* truncate cache dirty pages first */
	if (cl_io_is_trunc(io))
		result = osc_cache_truncate_start(env, oio, cl2osc(obj), size);

	if (result == 0 && oio->oi_lockless == 0) {
		cl_object_attr_lock(obj);
		result = cl_object_attr_get(env, obj, attr);
		if (result == 0) {
			struct ost_lvb *lvb = &io->u.ci_setattr.sa_attr;
			unsigned int cl_valid = 0;

			if (ia_valid & ATTR_SIZE) {
				attr->cat_size = attr->cat_kms = size;
				cl_valid = (CAT_SIZE | CAT_KMS);
			}
			if (ia_valid & ATTR_MTIME_SET) {
				attr->cat_mtime = lvb->lvb_mtime;
				cl_valid |= CAT_MTIME;
			}
			if (ia_valid & ATTR_ATIME_SET) {
				attr->cat_atime = lvb->lvb_atime;
				cl_valid |= CAT_ATIME;
			}
			if (ia_valid & ATTR_CTIME_SET) {
				attr->cat_ctime = lvb->lvb_ctime;
				cl_valid |= CAT_CTIME;
			}
			result = cl_object_attr_set(env, obj, attr, cl_valid);
		}
		cl_object_attr_unlock(obj);
	}
	memset(oa, 0, sizeof(*oa));
	if (result == 0) {
		oa->o_oi = loi->loi_oi;
		oa->o_mtime = attr->cat_mtime;
		oa->o_atime = attr->cat_atime;
		oa->o_ctime = attr->cat_ctime;
		oa->o_valid = OBD_MD_FLID | OBD_MD_FLGROUP | OBD_MD_FLATIME |
			OBD_MD_FLCTIME | OBD_MD_FLMTIME;
		if (ia_valid & ATTR_SIZE) {
			oa->o_size = size;
			oa->o_blocks = OBD_OBJECT_EOF;
			oa->o_valid |= OBD_MD_FLSIZE | OBD_MD_FLBLOCKS;

			if (oio->oi_lockless) {
				oa->o_flags = OBD_FL_SRVLOCK;
				oa->o_valid |= OBD_MD_FLFLAGS;
			}
		} else {
			LASSERT(oio->oi_lockless == 0);
		}

		oinfo.oi_oa = oa;
		oinfo.oi_capa = io->u.ci_setattr.sa_capa;
		init_completion(&cbargs->opc_sync);

		if (ia_valid & ATTR_SIZE)
			result = osc_punch_base(osc_export(cl2osc(obj)),
						&oinfo, osc_async_upcall,
						cbargs, PTLRPCD_SET);
		else
			result = osc_setattr_async_base(osc_export(cl2osc(obj)),
							&oinfo, NULL,
							osc_async_upcall,
							cbargs, PTLRPCD_SET);
		cbargs->opc_rpc_sent = result == 0;
	}
	return result;
}