lustre_mdc.h revision 23f14e79ace301c1e46b52344ce02e72254c57b6
1/* 2 * GPL HEADER START 3 * 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 only, 8 * as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, but 11 * WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * General Public License version 2 for more details (a copy is included 14 * in the LICENSE file that accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License 17 * version 2 along with this program; If not, see 18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf 19 * 20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 21 * CA 95054 USA or visit www.sun.com if you need additional information or 22 * have any questions. 23 * 24 * GPL HEADER END 25 */ 26/* 27 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 28 * Use is subject to license terms. 29 */ 30/* 31 * Copyright (c) 2011, 2012, Intel Corporation. 32 */ 33/* 34 * This file is part of Lustre, http://www.lustre.org/ 35 * Lustre is a trademark of Sun Microsystems, Inc. 36 * 37 * lustre/include/lustre_mdc.h 38 * 39 * MDS data structures. 40 * See also lustre_idl.h for wire formats of requests. 41 */ 42 43#ifndef _LUSTRE_MDC_H 44#define _LUSTRE_MDC_H 45 46/** \defgroup mdc mdc 47 * 48 * @{ 49 */ 50 51# include <linux/fs.h> 52# include <linux/dcache.h> 53# ifdef CONFIG_FS_POSIX_ACL 54# include <linux/posix_acl_xattr.h> 55# endif /* CONFIG_FS_POSIX_ACL */ 56# include <linux/lustre_intent.h> 57#include <lustre_handles.h> 58#include <linux/libcfs/libcfs.h> 59#include <obd_class.h> 60#include <lustre/lustre_idl.h> 61#include <lustre_lib.h> 62#include <lustre_dlm.h> 63#include <lustre_export.h> 64 65struct ptlrpc_client; 66struct obd_export; 67struct ptlrpc_request; 68struct obd_device; 69 70struct mdc_rpc_lock { 71 struct mutex rpcl_mutex; 72 struct lookup_intent *rpcl_it; 73 int rpcl_fakes; 74}; 75 76#define MDC_FAKE_RPCL_IT ((void *)0x2c0012bfUL) 77 78static inline void mdc_init_rpc_lock(struct mdc_rpc_lock *lck) 79{ 80 mutex_init(&lck->rpcl_mutex); 81 lck->rpcl_it = NULL; 82} 83 84static inline void mdc_get_rpc_lock(struct mdc_rpc_lock *lck, 85 struct lookup_intent *it) 86{ 87 if (it != NULL && (it->it_op == IT_GETATTR || it->it_op == IT_LOOKUP || 88 it->it_op == IT_LAYOUT)) 89 return; 90 91 /* This would normally block until the existing request finishes. 92 * If fail_loc is set it will block until the regular request is 93 * done, then set rpcl_it to MDC_FAKE_RPCL_IT. Once that is set 94 * it will only be cleared when all fake requests are finished. 95 * Only when all fake requests are finished can normal requests 96 * be sent, to ensure they are recoverable again. */ 97 again: 98 mutex_lock(&lck->rpcl_mutex); 99 100 if (CFS_FAIL_CHECK_QUIET(OBD_FAIL_MDC_RPCS_SEM)) { 101 lck->rpcl_it = MDC_FAKE_RPCL_IT; 102 lck->rpcl_fakes++; 103 mutex_unlock(&lck->rpcl_mutex); 104 return; 105 } 106 107 /* This will only happen when the CFS_FAIL_CHECK() was 108 * just turned off but there are still requests in progress. 109 * Wait until they finish. It doesn't need to be efficient 110 * in this extremely rare case, just have low overhead in 111 * the common case when it isn't true. */ 112 while (unlikely(lck->rpcl_it == MDC_FAKE_RPCL_IT)) { 113 mutex_unlock(&lck->rpcl_mutex); 114 schedule_timeout(cfs_time_seconds(1) / 4); 115 goto again; 116 } 117 118 LASSERT(lck->rpcl_it == NULL); 119 lck->rpcl_it = it; 120} 121 122static inline void mdc_put_rpc_lock(struct mdc_rpc_lock *lck, 123 struct lookup_intent *it) 124{ 125 if (it != NULL && (it->it_op == IT_GETATTR || it->it_op == IT_LOOKUP || 126 it->it_op == IT_LAYOUT)) 127 return; 128 129 if (lck->rpcl_it == MDC_FAKE_RPCL_IT) { /* OBD_FAIL_MDC_RPCS_SEM */ 130 mutex_lock(&lck->rpcl_mutex); 131 132 LASSERTF(lck->rpcl_fakes > 0, "%d\n", lck->rpcl_fakes); 133 lck->rpcl_fakes--; 134 135 if (lck->rpcl_fakes == 0) 136 lck->rpcl_it = NULL; 137 138 } else { 139 LASSERTF(it == lck->rpcl_it, "%p != %p\n", it, lck->rpcl_it); 140 lck->rpcl_it = NULL; 141 } 142 143 mutex_unlock(&lck->rpcl_mutex); 144} 145 146static inline void mdc_update_max_ea_from_body(struct obd_export *exp, 147 struct mdt_body *body) 148{ 149 if (body->valid & OBD_MD_FLMODEASIZE) { 150 if (exp->exp_obd->u.cli.cl_max_mds_easize < body->max_mdsize) 151 exp->exp_obd->u.cli.cl_max_mds_easize = 152 body->max_mdsize; 153 if (exp->exp_obd->u.cli.cl_max_mds_cookiesize < 154 body->max_cookiesize) 155 exp->exp_obd->u.cli.cl_max_mds_cookiesize = 156 body->max_cookiesize; 157 } 158} 159 160 161struct mdc_cache_waiter { 162 struct list_head mcw_entry; 163 wait_queue_head_t mcw_waitq; 164}; 165 166/* mdc/mdc_locks.c */ 167int it_disposition(struct lookup_intent *it, int flag); 168void it_clear_disposition(struct lookup_intent *it, int flag); 169void it_set_disposition(struct lookup_intent *it, int flag); 170int it_open_error(int phase, struct lookup_intent *it); 171 172/** @} mdc */ 173 174#endif 175