Viewing: lcommon_cl.c

// SPDX-License-Identifier: GPL-2.0

/*
 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
 * Use is subject to license terms.
 *
 * Copyright (c) 2011, 2017, Intel Corporation.
 */

/*
 * This file is part of Lustre, http://www.lustre.org/
 *
 * Author: Nikita Danilov <nikita.danilov@sun.com>
 */

#define DEBUG_SUBSYSTEM S_LLITE

#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/quotaops.h>
#include <linux/highmem.h>
#include <linux/pagemap.h>
#include <linux/rbtree.h>

#include <obd.h>
#include <obd_support.h>
#include <lustre_fid.h>
#include <lustre_dlm.h>
#include <lustre_mdc.h>
#include <cl_object.h>

#include "llite_internal.h"
#include "vvp_internal.h"

/* An 'emergency' environment used by cl_inode_fini() when cl_env_get()
 * fails. Access to this environment is serialized by cl_inode_fini_guard
 * mutex.
 */
struct lu_env *cl_inode_fini_env;
__u16 cl_inode_fini_refcheck;

/* A mutex serializing calls to slp_inode_fini() under extreme memory
 * pressure, when environments cannot be allocated.
 */
static DEFINE_MUTEX(cl_inode_fini_guard);

int cl_setattr_ost(struct inode *inode, const struct iattr *attr,
		   enum op_xvalid xvalid, unsigned int attr_flags)
{
	struct cl_object *obj;
	struct lu_env *env;
	struct cl_io *io;
	int result;
	__u16 refcheck;

	ENTRY;

	obj = ll_i2info(inode)->lli_clob;

	env = cl_env_get(&refcheck);
	if (IS_ERR(env))
		RETURN(PTR_ERR(env));

	io = vvp_env_new_io(env);
	io->ci_obj = obj;

	io->u.ci_setattr.sa_attr.lvb_atime = attr->ia_atime.tv_sec;
	io->u.ci_setattr.sa_attr.lvb_mtime = attr->ia_mtime.tv_sec;
	io->u.ci_setattr.sa_attr.lvb_ctime = attr->ia_ctime.tv_sec;
	io->u.ci_setattr.sa_attr.lvb_size = attr->ia_size;
	io->u.ci_setattr.sa_attr_flags = attr_flags;
	io->u.ci_setattr.sa_avalid = attr->ia_valid;
	io->u.ci_setattr.sa_xvalid = xvalid;
	io->u.ci_setattr.sa_parent_fid = lu_object_fid(&obj->co_lu);
	if (attr->ia_valid & ATTR_SIZE) {
		io->u.ci_setattr.sa_subtype = CL_SETATTR_TRUNC;
		io->u.ci_setattr.sa_attr_uid =
			from_kuid(&init_user_ns, inode->i_uid);
		io->u.ci_setattr.sa_attr_gid =
			from_kgid(&init_user_ns, inode->i_gid);
		io->u.ci_setattr.sa_attr_projid = ll_i2info(inode)->lli_projid;
	}
again:
	if (attr->ia_valid & ATTR_FILE)
		ll_io_set_mirror(io, attr->ia_file);

	if (cl_io_init(env, io, CIT_SETATTR, io->ci_obj) == 0) {
		struct vvp_io *vio = vvp_env_io(env);

		if (attr->ia_valid & ATTR_FILE)
			/*
			 * populate the file descriptor for ftruncate to honor
			 * group lock - see LU-787
			 */
			vio->vui_fd = attr->ia_file->private_data;

		result = cl_io_loop(env, io);
		CFS_FAIL_TIMEOUT(OBD_FAIL_LLITE_TRUNC_PAUSE, 2);
	} else {
		result = io->ci_result;
	}
	cl_io_fini(env, io);
	if (unlikely(io->ci_need_restart))
		goto again;

	cl_env_put(env, &refcheck);
	RETURN(result);
}

/**
 * cl_file_inode_init() - Initialize or update CLIO structures for regular
 * files when new meta-data arrives from the server.
 * @inode: regular file inode
 * @md: new file metadata from MDS
 *
 * - allocates cl_object if necessary,
 * - updated layout, if object was already here.
 *
 * Return:
 * * %0: Success
 * * %-ERRNO: Failure
 */
int cl_file_inode_init(struct inode *inode, struct lustre_md *md)
{
	struct lu_env        *env;
	struct ll_inode_info *lli;
	struct cl_object     *clob;
	struct lu_site       *site;
	struct lu_fid        *fid;
	struct cl_object_conf conf = {
		.coc_inode = inode,
		.u = {
			.coc_layout = md->layout,
		}
	};
	int result = 0;
	__u16 refcheck;

	if (!(md->body->mbo_valid & OBD_MD_FLID) || !S_ISREG(inode->i_mode))
		return 0;

	env = cl_env_get(&refcheck);
	if (IS_ERR(env))
		return PTR_ERR(env);

	site = ll_i2sbi(inode)->ll_site;
	lli  = ll_i2info(inode);
	fid  = &lli->lli_fid;
	LASSERT(fid_is_sane(fid));

	if (lli->lli_clob == NULL) {
		/* clob is slave of inode, empty lli_clob means for new inode,
		 * there is no clob in cache with the given fid, so it is
		 * unnecessary to perform lookup-alloc-lookup-insert, just
		 * alloc and insert directly.
		 */
		if (!(inode_state_read_once(inode) & I_NEW)) {
			result = -EIO;
			CERROR("%s: unexpected not-NEW inode "DFID": rc = %d\n",
			       ll_i2sbi(inode)->ll_fsname, PFID(fid), result);
			goto out;
		}

		conf.coc_lu.loc_flags = LOC_F_NEW;
		clob = cl_object_find(env, lu2cl_dev(site->ls_top_dev),
				      fid, &conf);
		if (!IS_ERR(clob)) {
			/*
			 * No locking is necessary, as new inode is
			 * locked by I_NEW bit.
			 */
			lli->lli_clob = clob;
		} else {
			result = PTR_ERR(clob);
		}
	} else {
		result = cl_conf_set(env, lli->lli_clob, &conf);
		if (result == -EBUSY) {
			/* ignore the error since I/O will handle it later */
			result = 0;
		}
	}

	if (result != 0)
		CERROR("%s: failed to initialize cl_object "DFID": rc = %d\n",
		       ll_i2sbi(inode)->ll_fsname, PFID(fid), result);

out:
	cl_env_put(env, &refcheck);

	return result;
}

/*
 * Wait for others drop their references of the object at first, then we drop
 * the last one, which will lead to the object be destroyed immediately.
 * Must be called after cl_object_kill() against this object.
 *
 * The reason we want to do this is: destroying top object will wait for sub
 * objects being destroyed first, so we can't let bottom layer (e.g. from ASTs)
 * to initiate top object destroying which may deadlock. See bz22520.
 */
static void cl_object_put_last(struct lu_env *env, struct cl_object *obj)
{
	struct lu_object_header *header = obj->co_lu.lo_header;

	if (unlikely(atomic_read(&header->loh_ref) != 1)) {
		struct lu_site *site = obj->co_lu.lo_dev->ld_site;
		wait_queue_head_t *wq;

		wq = lu_site_wq_from_fid(site, &header->loh_fid);

		/* LU_OBJECT_HEARD_BANSHEE is set in cl_object_kill(), in case
		 * someone is waiting on this, wake up and then wait for object
		 * refcount becomes one.
		 */
		wake_up(wq);
		wait_event(*wq, atomic_read(&header->loh_ref) == 1);
	}

	cl_object_put(env, obj);
}

void cl_inode_fini(struct inode *inode)
{
	struct lu_env           *env;
	struct ll_inode_info    *lli  = ll_i2info(inode);
	struct cl_object        *clob = lli->lli_clob;
	__u16  refcheck;
	int emergency;

	if (clob != NULL) {
		env = cl_env_get(&refcheck);
		emergency = IS_ERR(env);
		if (emergency) {
			mutex_lock(&cl_inode_fini_guard);
			LASSERT(cl_inode_fini_env != NULL);
			env = cl_inode_fini_env;
		}

		/*
		 * cl_object cache is a slave to inode cache (which, in turn
		 * is a slave to dentry cache), don't keep cl_object in memory
		 * when its master is evicted.
		 */
		cl_object_kill(env, clob);
		cl_object_put_last(env, clob);
		lli->lli_clob = NULL;
		if (emergency)
			mutex_unlock(&cl_inode_fini_guard);
		else
			cl_env_put(env, &refcheck);
	}
}

/**
 * cl_fid_build_ino() - build inode number from passed @fid.
 * @fid: FID(Unique File Identifier)
 * @api32: 1 for 32bit otherwise it is 64bit
 *
 * For 32-bit systems or syscalls limit the inode number to a 32-bit value
 * to avoid EOVERFLOW errors.  This will inevitably result in inode number
 * collisions, but fid_flatten32() tries hard to avoid this if possible.
 *
 * Return:
 * * map FID(Unique File Identifier) to 32bit for inode on 32bit systems or
 * map FID to 64bit for inode on 32bit systems
 */
__u64 cl_fid_build_ino(const struct lu_fid *fid, int api32)
{
	if (BITS_PER_LONG == 32 || api32)
		RETURN(fid_flatten32(fid));

	RETURN(fid_flatten64(fid));
}

/**
 * cl_fid_build_gen() - build inode generation from passed @fid.
 * @fid: Unique File Identifier
 *
 * build inode generation from passed @fid.  If our FID overflows the 32-bit
 * inode number then return a non-zero generation to distinguish them.
 *
 * Return:
 * * >0 generation number which will get incremented/changed on @fid reuse
 *
 */
__u32 cl_fid_build_gen(const struct lu_fid *fid)
{
	if (fid_is_igif(fid))
		RETURN(lu_igif_gen(fid));

	RETURN(fid_flatten64(fid) >> 32);
}