xref: /openbmc/linux/fs/ceph/cache.c (revision 48f930ea)
11f327613SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
299ccbd22SMilosz Tanski /*
399ccbd22SMilosz Tanski  * Ceph cache definitions.
499ccbd22SMilosz Tanski  *
599ccbd22SMilosz Tanski  *  Copyright (C) 2013 by Adfin Solutions, Inc. All Rights Reserved.
699ccbd22SMilosz Tanski  *  Written by Milosz Tanski (milosz@adfin.com)
799ccbd22SMilosz Tanski  */
899ccbd22SMilosz Tanski 
948f930eaSIlya Dryomov #include <linux/ceph/ceph_debug.h>
1048f930eaSIlya Dryomov 
1199ccbd22SMilosz Tanski #include "super.h"
1299ccbd22SMilosz Tanski #include "cache.h"
1399ccbd22SMilosz Tanski 
1499ccbd22SMilosz Tanski struct ceph_aux_inode {
15f6973c09SYan, Zheng 	u64 	version;
169bbeab41SArnd Bergmann 	u64	mtime_sec;
179bbeab41SArnd Bergmann 	u64	mtime_nsec;
1899ccbd22SMilosz Tanski };
1999ccbd22SMilosz Tanski 
2099ccbd22SMilosz Tanski struct fscache_netfs ceph_cache_netfs = {
2199ccbd22SMilosz Tanski 	.name		= "ceph",
2299ccbd22SMilosz Tanski 	.version	= 0,
2399ccbd22SMilosz Tanski };
2499ccbd22SMilosz Tanski 
251d8f8360SYan, Zheng static DEFINE_MUTEX(ceph_fscache_lock);
261d8f8360SYan, Zheng static LIST_HEAD(ceph_fscache_list);
271d8f8360SYan, Zheng 
281d8f8360SYan, Zheng struct ceph_fscache_entry {
291d8f8360SYan, Zheng 	struct list_head list;
301d8f8360SYan, Zheng 	struct fscache_cookie *fscache;
311d8f8360SYan, Zheng 	size_t uniq_len;
32402cb8ddSDavid Howells 	/* The following members must be last */
33402cb8ddSDavid Howells 	struct ceph_fsid fsid;
341d8f8360SYan, Zheng 	char uniquifier[0];
351d8f8360SYan, Zheng };
361d8f8360SYan, Zheng 
3799ccbd22SMilosz Tanski static const struct fscache_cookie_def ceph_fscache_fsid_object_def = {
3899ccbd22SMilosz Tanski 	.name		= "CEPH.fsid",
3999ccbd22SMilosz Tanski 	.type		= FSCACHE_COOKIE_TYPE_INDEX,
4099ccbd22SMilosz Tanski };
4199ccbd22SMilosz Tanski 
4257a35dfbSChengguang Xu int __init ceph_fscache_register(void)
4399ccbd22SMilosz Tanski {
4499ccbd22SMilosz Tanski 	return fscache_register_netfs(&ceph_cache_netfs);
4599ccbd22SMilosz Tanski }
4699ccbd22SMilosz Tanski 
47971f0bdeSMilosz Tanski void ceph_fscache_unregister(void)
4899ccbd22SMilosz Tanski {
4999ccbd22SMilosz Tanski 	fscache_unregister_netfs(&ceph_cache_netfs);
5099ccbd22SMilosz Tanski }
5199ccbd22SMilosz Tanski 
5299ccbd22SMilosz Tanski int ceph_fscache_register_fs(struct ceph_fs_client* fsc)
5399ccbd22SMilosz Tanski {
541d8f8360SYan, Zheng 	const struct ceph_fsid *fsid = &fsc->client->fsid;
551d8f8360SYan, Zheng 	const char *fscache_uniq = fsc->mount_options->fscache_uniq;
561d8f8360SYan, Zheng 	size_t uniq_len = fscache_uniq ? strlen(fscache_uniq) : 0;
571d8f8360SYan, Zheng 	struct ceph_fscache_entry *ent;
581d8f8360SYan, Zheng 	int err = 0;
591d8f8360SYan, Zheng 
601d8f8360SYan, Zheng 	mutex_lock(&ceph_fscache_lock);
611d8f8360SYan, Zheng 	list_for_each_entry(ent, &ceph_fscache_list, list) {
621d8f8360SYan, Zheng 		if (memcmp(&ent->fsid, fsid, sizeof(*fsid)))
631d8f8360SYan, Zheng 			continue;
641d8f8360SYan, Zheng 		if (ent->uniq_len != uniq_len)
651d8f8360SYan, Zheng 			continue;
661d8f8360SYan, Zheng 		if (uniq_len && memcmp(ent->uniquifier, fscache_uniq, uniq_len))
671d8f8360SYan, Zheng 			continue;
681d8f8360SYan, Zheng 
691d8f8360SYan, Zheng 		pr_err("fscache cookie already registered for fsid %pU\n", fsid);
701d8f8360SYan, Zheng 		pr_err("  use fsc=%%s mount option to specify a uniquifier\n");
711d8f8360SYan, Zheng 		err = -EBUSY;
721d8f8360SYan, Zheng 		goto out_unlock;
731d8f8360SYan, Zheng 	}
741d8f8360SYan, Zheng 
751d8f8360SYan, Zheng 	ent = kzalloc(sizeof(*ent) + uniq_len, GFP_KERNEL);
761d8f8360SYan, Zheng 	if (!ent) {
771d8f8360SYan, Zheng 		err = -ENOMEM;
781d8f8360SYan, Zheng 		goto out_unlock;
791d8f8360SYan, Zheng 	}
801d8f8360SYan, Zheng 
811d8f8360SYan, Zheng 	memcpy(&ent->fsid, fsid, sizeof(*fsid));
821d8f8360SYan, Zheng 	if (uniq_len > 0) {
831d8f8360SYan, Zheng 		memcpy(&ent->uniquifier, fscache_uniq, uniq_len);
841d8f8360SYan, Zheng 		ent->uniq_len = uniq_len;
851d8f8360SYan, Zheng 	}
86402cb8ddSDavid Howells 
87402cb8ddSDavid Howells 	fsc->fscache = fscache_acquire_cookie(ceph_cache_netfs.primary_index,
88402cb8ddSDavid Howells 					      &ceph_fscache_fsid_object_def,
89402cb8ddSDavid Howells 					      &ent->fsid, sizeof(ent->fsid) + uniq_len,
90402cb8ddSDavid Howells 					      NULL, 0,
91ee1235a9SDavid Howells 					      fsc, 0, true);
92402cb8ddSDavid Howells 
93402cb8ddSDavid Howells 	if (fsc->fscache) {
941d8f8360SYan, Zheng 		ent->fscache = fsc->fscache;
951d8f8360SYan, Zheng 		list_add_tail(&ent->list, &ceph_fscache_list);
961d8f8360SYan, Zheng 	} else {
971d8f8360SYan, Zheng 		kfree(ent);
981d8f8360SYan, Zheng 		pr_err("unable to register fscache cookie for fsid %pU\n",
991d8f8360SYan, Zheng 		       fsid);
1001d8f8360SYan, Zheng 		/* all other fs ignore this error */
1011d8f8360SYan, Zheng 	}
1021d8f8360SYan, Zheng out_unlock:
1031d8f8360SYan, Zheng 	mutex_unlock(&ceph_fscache_lock);
1041d8f8360SYan, Zheng 	return err;
10599ccbd22SMilosz Tanski }
10699ccbd22SMilosz Tanski 
10799ccbd22SMilosz Tanski static enum fscache_checkaux ceph_fscache_inode_check_aux(
108ee1235a9SDavid Howells 	void *cookie_netfs_data, const void *data, uint16_t dlen,
109ee1235a9SDavid Howells 	loff_t object_size)
11099ccbd22SMilosz Tanski {
11199ccbd22SMilosz Tanski 	struct ceph_aux_inode aux;
11299ccbd22SMilosz Tanski 	struct ceph_inode_info* ci = cookie_netfs_data;
11399ccbd22SMilosz Tanski 	struct inode* inode = &ci->vfs_inode;
11499ccbd22SMilosz Tanski 
115ee1235a9SDavid Howells 	if (dlen != sizeof(aux) ||
116ee1235a9SDavid Howells 	    i_size_read(inode) != object_size)
11799ccbd22SMilosz Tanski 		return FSCACHE_CHECKAUX_OBSOLETE;
11899ccbd22SMilosz Tanski 
11999ccbd22SMilosz Tanski 	memset(&aux, 0, sizeof(aux));
120f6973c09SYan, Zheng 	aux.version = ci->i_version;
1219bbeab41SArnd Bergmann 	aux.mtime_sec = inode->i_mtime.tv_sec;
1229bbeab41SArnd Bergmann 	aux.mtime_nsec = inode->i_mtime.tv_nsec;
12399ccbd22SMilosz Tanski 
12499ccbd22SMilosz Tanski 	if (memcmp(data, &aux, sizeof(aux)) != 0)
12599ccbd22SMilosz Tanski 		return FSCACHE_CHECKAUX_OBSOLETE;
12699ccbd22SMilosz Tanski 
1274c069a58SChengguang Xu 	dout("ceph inode 0x%p cached okay\n", ci);
12899ccbd22SMilosz Tanski 	return FSCACHE_CHECKAUX_OKAY;
12999ccbd22SMilosz Tanski }
13099ccbd22SMilosz Tanski 
13199ccbd22SMilosz Tanski static const struct fscache_cookie_def ceph_fscache_inode_object_def = {
13299ccbd22SMilosz Tanski 	.name		= "CEPH.inode",
13399ccbd22SMilosz Tanski 	.type		= FSCACHE_COOKIE_TYPE_DATAFILE,
13499ccbd22SMilosz Tanski 	.check_aux	= ceph_fscache_inode_check_aux,
13599ccbd22SMilosz Tanski };
13699ccbd22SMilosz Tanski 
13746b59b2bSYan, Zheng void ceph_fscache_register_inode_cookie(struct inode *inode)
13899ccbd22SMilosz Tanski {
13946b59b2bSYan, Zheng 	struct ceph_inode_info *ci = ceph_inode(inode);
14046b59b2bSYan, Zheng 	struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
141402cb8ddSDavid Howells 	struct ceph_aux_inode aux;
14299ccbd22SMilosz Tanski 
14399ccbd22SMilosz Tanski 	/* No caching for filesystem */
144d37b1d99SMarkus Elfring 	if (!fsc->fscache)
14599ccbd22SMilosz Tanski 		return;
14699ccbd22SMilosz Tanski 
14799ccbd22SMilosz Tanski 	/* Only cache for regular files that are read only */
14846b59b2bSYan, Zheng 	if (!S_ISREG(inode->i_mode))
14999ccbd22SMilosz Tanski 		return;
15099ccbd22SMilosz Tanski 
15146b59b2bSYan, Zheng 	inode_lock_nested(inode, I_MUTEX_CHILD);
15246b59b2bSYan, Zheng 	if (!ci->fscache) {
153402cb8ddSDavid Howells 		memset(&aux, 0, sizeof(aux));
154402cb8ddSDavid Howells 		aux.version = ci->i_version;
1559bbeab41SArnd Bergmann 		aux.mtime_sec = inode->i_mtime.tv_sec;
1569bbeab41SArnd Bergmann 		aux.mtime_nsec = inode->i_mtime.tv_nsec;
15799ccbd22SMilosz Tanski 		ci->fscache = fscache_acquire_cookie(fsc->fscache,
15899ccbd22SMilosz Tanski 						     &ceph_fscache_inode_object_def,
159402cb8ddSDavid Howells 						     &ci->i_vino, sizeof(ci->i_vino),
160402cb8ddSDavid Howells 						     &aux, sizeof(aux),
161ee1235a9SDavid Howells 						     ci, i_size_read(inode), false);
16246b59b2bSYan, Zheng 	}
1635955102cSAl Viro 	inode_unlock(inode);
16499ccbd22SMilosz Tanski }
16599ccbd22SMilosz Tanski 
16699ccbd22SMilosz Tanski void ceph_fscache_unregister_inode_cookie(struct ceph_inode_info* ci)
16799ccbd22SMilosz Tanski {
16899ccbd22SMilosz Tanski 	struct fscache_cookie* cookie;
16999ccbd22SMilosz Tanski 
17099ccbd22SMilosz Tanski 	if ((cookie = ci->fscache) == NULL)
17199ccbd22SMilosz Tanski 		return;
17299ccbd22SMilosz Tanski 
17399ccbd22SMilosz Tanski 	ci->fscache = NULL;
17499ccbd22SMilosz Tanski 
17599ccbd22SMilosz Tanski 	fscache_uncache_all_inode_pages(cookie, &ci->vfs_inode);
176402cb8ddSDavid Howells 	fscache_relinquish_cookie(cookie, &ci->i_vino, false);
17799ccbd22SMilosz Tanski }
17899ccbd22SMilosz Tanski 
17946b59b2bSYan, Zheng static bool ceph_fscache_can_enable(void *data)
18046b59b2bSYan, Zheng {
18146b59b2bSYan, Zheng 	struct inode *inode = data;
18246b59b2bSYan, Zheng 	return !inode_is_open_for_write(inode);
18346b59b2bSYan, Zheng }
18446b59b2bSYan, Zheng 
18546b59b2bSYan, Zheng void ceph_fscache_file_set_cookie(struct inode *inode, struct file *filp)
18646b59b2bSYan, Zheng {
18746b59b2bSYan, Zheng 	struct ceph_inode_info *ci = ceph_inode(inode);
18846b59b2bSYan, Zheng 
18946b59b2bSYan, Zheng 	if (!fscache_cookie_valid(ci->fscache))
19046b59b2bSYan, Zheng 		return;
19146b59b2bSYan, Zheng 
19246b59b2bSYan, Zheng 	if (inode_is_open_for_write(inode)) {
19346b59b2bSYan, Zheng 		dout("fscache_file_set_cookie %p %p disabling cache\n",
19446b59b2bSYan, Zheng 		     inode, filp);
195402cb8ddSDavid Howells 		fscache_disable_cookie(ci->fscache, &ci->i_vino, false);
19646b59b2bSYan, Zheng 		fscache_uncache_all_inode_pages(ci->fscache, inode);
19746b59b2bSYan, Zheng 	} else {
198ee1235a9SDavid Howells 		fscache_enable_cookie(ci->fscache, &ci->i_vino, i_size_read(inode),
199402cb8ddSDavid Howells 				      ceph_fscache_can_enable, inode);
20046b59b2bSYan, Zheng 		if (fscache_cookie_enabled(ci->fscache)) {
2010fbc5360SColin Ian King 			dout("fscache_file_set_cookie %p %p enabling cache\n",
20246b59b2bSYan, Zheng 			     inode, filp);
20346b59b2bSYan, Zheng 		}
20446b59b2bSYan, Zheng 	}
20546b59b2bSYan, Zheng }
20646b59b2bSYan, Zheng 
207dd2bc473SYan, Zheng static void ceph_readpage_from_fscache_complete(struct page *page, void *data, int error)
20899ccbd22SMilosz Tanski {
20999ccbd22SMilosz Tanski 	if (!error)
21099ccbd22SMilosz Tanski 		SetPageUptodate(page);
21199ccbd22SMilosz Tanski 
21299ccbd22SMilosz Tanski 	unlock_page(page);
21399ccbd22SMilosz Tanski }
21499ccbd22SMilosz Tanski 
2153b33f692SZhang Zhuoyu static inline bool cache_valid(struct ceph_inode_info *ci)
21699ccbd22SMilosz Tanski {
217f7f7e7a0SYan, Zheng 	return ci->i_fscache_gen == ci->i_rdcache_gen;
21899ccbd22SMilosz Tanski }
21999ccbd22SMilosz Tanski 
22099ccbd22SMilosz Tanski 
22199ccbd22SMilosz Tanski /* Atempt to read from the fscache,
22299ccbd22SMilosz Tanski  *
22399ccbd22SMilosz Tanski  * This function is called from the readpage_nounlock context. DO NOT attempt to
22499ccbd22SMilosz Tanski  * unlock the page here (or in the callback).
22599ccbd22SMilosz Tanski  */
22699ccbd22SMilosz Tanski int ceph_readpage_from_fscache(struct inode *inode, struct page *page)
22799ccbd22SMilosz Tanski {
22899ccbd22SMilosz Tanski 	struct ceph_inode_info *ci = ceph_inode(inode);
22999ccbd22SMilosz Tanski 	int ret;
23099ccbd22SMilosz Tanski 
23199ccbd22SMilosz Tanski 	if (!cache_valid(ci))
23299ccbd22SMilosz Tanski 		return -ENOBUFS;
23399ccbd22SMilosz Tanski 
23499ccbd22SMilosz Tanski 	ret = fscache_read_or_alloc_page(ci->fscache, page,
235dd2bc473SYan, Zheng 					 ceph_readpage_from_fscache_complete, NULL,
23699ccbd22SMilosz Tanski 					 GFP_KERNEL);
23799ccbd22SMilosz Tanski 
23899ccbd22SMilosz Tanski 	switch (ret) {
23999ccbd22SMilosz Tanski 		case 0: /* Page found */
24099ccbd22SMilosz Tanski 			dout("page read submitted\n");
24199ccbd22SMilosz Tanski 			return 0;
24299ccbd22SMilosz Tanski 		case -ENOBUFS: /* Pages were not found, and can't be */
24399ccbd22SMilosz Tanski 		case -ENODATA: /* Pages were not found */
24499ccbd22SMilosz Tanski 			dout("page/inode not in cache\n");
24599ccbd22SMilosz Tanski 			return ret;
24699ccbd22SMilosz Tanski 		default:
24799ccbd22SMilosz Tanski 			dout("%s: unknown error ret = %i\n", __func__, ret);
24899ccbd22SMilosz Tanski 			return ret;
24999ccbd22SMilosz Tanski 	}
25099ccbd22SMilosz Tanski }
25199ccbd22SMilosz Tanski 
25299ccbd22SMilosz Tanski int ceph_readpages_from_fscache(struct inode *inode,
25399ccbd22SMilosz Tanski 				  struct address_space *mapping,
25499ccbd22SMilosz Tanski 				  struct list_head *pages,
25599ccbd22SMilosz Tanski 				  unsigned *nr_pages)
25699ccbd22SMilosz Tanski {
25799ccbd22SMilosz Tanski 	struct ceph_inode_info *ci = ceph_inode(inode);
25899ccbd22SMilosz Tanski 	int ret;
25999ccbd22SMilosz Tanski 
26099ccbd22SMilosz Tanski 	if (!cache_valid(ci))
26199ccbd22SMilosz Tanski 		return -ENOBUFS;
26299ccbd22SMilosz Tanski 
26399ccbd22SMilosz Tanski 	ret = fscache_read_or_alloc_pages(ci->fscache, mapping, pages, nr_pages,
264dd2bc473SYan, Zheng 					  ceph_readpage_from_fscache_complete,
26599ccbd22SMilosz Tanski 					  NULL, mapping_gfp_mask(mapping));
26699ccbd22SMilosz Tanski 
26799ccbd22SMilosz Tanski 	switch (ret) {
26899ccbd22SMilosz Tanski 		case 0: /* All pages found */
26999ccbd22SMilosz Tanski 			dout("all-page read submitted\n");
27099ccbd22SMilosz Tanski 			return 0;
27199ccbd22SMilosz Tanski 		case -ENOBUFS: /* Some pages were not found, and can't be */
27299ccbd22SMilosz Tanski 		case -ENODATA: /* some pages were not found */
27399ccbd22SMilosz Tanski 			dout("page/inode not in cache\n");
27499ccbd22SMilosz Tanski 			return ret;
27599ccbd22SMilosz Tanski 		default:
27699ccbd22SMilosz Tanski 			dout("%s: unknown error ret = %i\n", __func__, ret);
27799ccbd22SMilosz Tanski 			return ret;
27899ccbd22SMilosz Tanski 	}
27999ccbd22SMilosz Tanski }
28099ccbd22SMilosz Tanski 
28199ccbd22SMilosz Tanski void ceph_readpage_to_fscache(struct inode *inode, struct page *page)
28299ccbd22SMilosz Tanski {
28399ccbd22SMilosz Tanski 	struct ceph_inode_info *ci = ceph_inode(inode);
28499ccbd22SMilosz Tanski 	int ret;
28599ccbd22SMilosz Tanski 
2869b8dd1e8SMilosz Tanski 	if (!PageFsCache(page))
2879b8dd1e8SMilosz Tanski 		return;
2889b8dd1e8SMilosz Tanski 
28999ccbd22SMilosz Tanski 	if (!cache_valid(ci))
29099ccbd22SMilosz Tanski 		return;
29199ccbd22SMilosz Tanski 
292ee1235a9SDavid Howells 	ret = fscache_write_page(ci->fscache, page, i_size_read(inode),
293ee1235a9SDavid Howells 				 GFP_KERNEL);
29499ccbd22SMilosz Tanski 	if (ret)
29599ccbd22SMilosz Tanski 		 fscache_uncache_page(ci->fscache, page);
29699ccbd22SMilosz Tanski }
29799ccbd22SMilosz Tanski 
29899ccbd22SMilosz Tanski void ceph_invalidate_fscache_page(struct inode* inode, struct page *page)
29999ccbd22SMilosz Tanski {
30099ccbd22SMilosz Tanski 	struct ceph_inode_info *ci = ceph_inode(inode);
30199ccbd22SMilosz Tanski 
302ffc79664SMilosz Tanski 	if (!PageFsCache(page))
303ffc79664SMilosz Tanski 		return;
304ffc79664SMilosz Tanski 
30599ccbd22SMilosz Tanski 	fscache_wait_on_page_write(ci->fscache, page);
30699ccbd22SMilosz Tanski 	fscache_uncache_page(ci->fscache, page);
30799ccbd22SMilosz Tanski }
30899ccbd22SMilosz Tanski 
30999ccbd22SMilosz Tanski void ceph_fscache_unregister_fs(struct ceph_fs_client* fsc)
31099ccbd22SMilosz Tanski {
3111d8f8360SYan, Zheng 	if (fscache_cookie_valid(fsc->fscache)) {
3121d8f8360SYan, Zheng 		struct ceph_fscache_entry *ent;
3131d8f8360SYan, Zheng 		bool found = false;
3141d8f8360SYan, Zheng 
3151d8f8360SYan, Zheng 		mutex_lock(&ceph_fscache_lock);
3161d8f8360SYan, Zheng 		list_for_each_entry(ent, &ceph_fscache_list, list) {
3171d8f8360SYan, Zheng 			if (ent->fscache == fsc->fscache) {
3181d8f8360SYan, Zheng 				list_del(&ent->list);
3191d8f8360SYan, Zheng 				kfree(ent);
3201d8f8360SYan, Zheng 				found = true;
3211d8f8360SYan, Zheng 				break;
3221d8f8360SYan, Zheng 			}
3231d8f8360SYan, Zheng 		}
3241d8f8360SYan, Zheng 		WARN_ON_ONCE(!found);
3251d8f8360SYan, Zheng 		mutex_unlock(&ceph_fscache_lock);
3261d8f8360SYan, Zheng 
327402cb8ddSDavid Howells 		__fscache_relinquish_cookie(fsc->fscache, NULL, false);
3281d8f8360SYan, Zheng 	}
32999ccbd22SMilosz Tanski 	fsc->fscache = NULL;
33099ccbd22SMilosz Tanski }
33199ccbd22SMilosz Tanski 
332f7f7e7a0SYan, Zheng /*
333f7f7e7a0SYan, Zheng  * caller should hold CEPH_CAP_FILE_{RD,CACHE}
334f7f7e7a0SYan, Zheng  */
335f7f7e7a0SYan, Zheng void ceph_fscache_revalidate_cookie(struct ceph_inode_info *ci)
33699ccbd22SMilosz Tanski {
337f7f7e7a0SYan, Zheng 	if (cache_valid(ci))
338e81568ebSMilosz Tanski 		return;
339e81568ebSMilosz Tanski 
340f7f7e7a0SYan, Zheng 	/* resue i_truncate_mutex. There should be no pending
341f7f7e7a0SYan, Zheng 	 * truncate while the caller holds CEPH_CAP_FILE_RD */
342f7f7e7a0SYan, Zheng 	mutex_lock(&ci->i_truncate_mutex);
343f7f7e7a0SYan, Zheng 	if (!cache_valid(ci)) {
344402cb8ddSDavid Howells 		if (fscache_check_consistency(ci->fscache, &ci->i_vino))
345f7f7e7a0SYan, Zheng 			fscache_invalidate(ci->fscache);
346f7f7e7a0SYan, Zheng 		spin_lock(&ci->i_ceph_lock);
347f7f7e7a0SYan, Zheng 		ci->i_fscache_gen = ci->i_rdcache_gen;
348f7f7e7a0SYan, Zheng 		spin_unlock(&ci->i_ceph_lock);
34999ccbd22SMilosz Tanski 	}
350f7f7e7a0SYan, Zheng 	mutex_unlock(&ci->i_truncate_mutex);
35199ccbd22SMilosz Tanski }
352