4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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.
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).
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
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
27 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
30 * Copyright (c) 2011, 2012, Intel Corporation.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
37 #define DEBUG_SUBSYSTEM S_LMV
38 #include <linux/slab.h>
39 #include <linux/module.h>
40 #include <linux/init.h>
41 #include <linux/pagemap.h>
42 #include <asm/div64.h>
43 #include <linux/seq_file.h>
44 #include <linux/namei.h>
45 #include <linux/lustre_intent.h>
47 #include <obd_support.h>
48 #include <lustre/lustre_idl.h>
49 #include <lustre_lib.h>
50 #include <lustre_net.h>
51 #include <lustre_dlm.h>
52 #include <obd_class.h>
53 #include <lprocfs_status.h>
54 #include "lmv_internal.h"
56 static int lmv_intent_remote(struct obd_export
*exp
, void *lmm
,
57 int lmmsize
, struct lookup_intent
*it
,
58 const struct lu_fid
*parent_fid
, int flags
,
59 struct ptlrpc_request
**reqp
,
60 ldlm_blocking_callback cb_blocking
,
61 __u64 extra_lock_flags
)
63 struct obd_device
*obd
= exp
->exp_obd
;
64 struct lmv_obd
*lmv
= &obd
->u
.lmv
;
65 struct ptlrpc_request
*req
= NULL
;
66 struct lustre_handle plock
;
67 struct md_op_data
*op_data
;
68 struct lmv_tgt_desc
*tgt
;
69 struct mdt_body
*body
;
73 body
= req_capsule_server_get(&(*reqp
)->rq_pill
, &RMF_MDT_BODY
);
77 LASSERT((body
->valid
& OBD_MD_MDS
));
80 * Unfortunately, we have to lie to MDC/MDS to retrieve
81 * attributes llite needs and provideproper locking.
83 if (it
->it_op
& IT_LOOKUP
)
84 it
->it_op
= IT_GETATTR
;
87 * We got LOOKUP lock, but we really need attrs.
89 pmode
= it
->d
.lustre
.it_lock_mode
;
91 plock
.cookie
= it
->d
.lustre
.it_lock_handle
;
92 it
->d
.lustre
.it_lock_mode
= 0;
93 it
->d
.lustre
.it_data
= NULL
;
96 LASSERT(fid_is_sane(&body
->fid1
));
98 tgt
= lmv_find_target(lmv
, &body
->fid1
);
100 GOTO(out
, rc
= PTR_ERR(tgt
));
102 OBD_ALLOC_PTR(op_data
);
104 GOTO(out
, rc
= -ENOMEM
);
106 op_data
->op_fid1
= body
->fid1
;
107 /* Sent the parent FID to the remote MDT */
108 if (parent_fid
!= NULL
) {
109 /* The parent fid is only for remote open to
110 * check whether the open is from OBF,
111 * see mdt_cross_open */
112 LASSERT(it
->it_op
& IT_OPEN
);
113 op_data
->op_fid2
= *parent_fid
;
114 /* Add object FID to op_fid3, in case it needs to check stale
115 * (M_CHECK_STALE), see mdc_finish_intent_lock */
116 op_data
->op_fid3
= body
->fid1
;
119 op_data
->op_bias
= MDS_CROSS_REF
;
120 CDEBUG(D_INODE
, "REMOTE_INTENT with fid="DFID
" -> mds #%d\n",
121 PFID(&body
->fid1
), tgt
->ltd_idx
);
123 it
->d
.lustre
.it_disposition
&= ~DISP_ENQ_COMPLETE
;
124 rc
= md_intent_lock(tgt
->ltd_exp
, op_data
, lmm
, lmmsize
, it
,
125 flags
, &req
, cb_blocking
, extra_lock_flags
);
127 GOTO(out_free_op_data
, rc
);
130 * LLite needs LOOKUP lock to track dentry revocation in order to
131 * maintain dcache consistency. Thus drop UPDATE|PERM lock here
132 * and put LOOKUP in request.
134 if (it
->d
.lustre
.it_lock_mode
!= 0) {
135 it
->d
.lustre
.it_remote_lock_handle
=
136 it
->d
.lustre
.it_lock_handle
;
137 it
->d
.lustre
.it_remote_lock_mode
= it
->d
.lustre
.it_lock_mode
;
140 it
->d
.lustre
.it_lock_handle
= plock
.cookie
;
141 it
->d
.lustre
.it_lock_mode
= pmode
;
144 OBD_FREE_PTR(op_data
);
147 ldlm_lock_decref(&plock
, pmode
);
149 ptlrpc_req_finished(*reqp
);
155 * IT_OPEN is intended to open (and create, possible) an object. Parent (pid)
158 int lmv_intent_open(struct obd_export
*exp
, struct md_op_data
*op_data
,
159 void *lmm
, int lmmsize
, struct lookup_intent
*it
,
160 int flags
, struct ptlrpc_request
**reqp
,
161 ldlm_blocking_callback cb_blocking
,
162 __u64 extra_lock_flags
)
164 struct obd_device
*obd
= exp
->exp_obd
;
165 struct lmv_obd
*lmv
= &obd
->u
.lmv
;
166 struct lmv_tgt_desc
*tgt
;
167 struct mdt_body
*body
;
170 tgt
= lmv_locate_mds(lmv
, op_data
, &op_data
->op_fid1
);
174 /* If it is ready to open the file by FID, do not need
175 * allocate FID at all, otherwise it will confuse MDT */
176 if ((it
->it_op
& IT_CREAT
) &&
177 !(it
->it_flags
& MDS_OPEN_BY_FID
)) {
179 * For open with IT_CREATE and for IT_CREATE cases allocate new
180 * fid and setup FLD for it.
182 op_data
->op_fid3
= op_data
->op_fid2
;
183 rc
= lmv_fid_alloc(exp
, &op_data
->op_fid2
, op_data
);
188 CDEBUG(D_INODE
, "OPEN_INTENT with fid1="DFID
", fid2="DFID
","
189 " name='%s' -> mds #%d\n", PFID(&op_data
->op_fid1
),
190 PFID(&op_data
->op_fid2
), op_data
->op_name
, tgt
->ltd_idx
);
192 rc
= md_intent_lock(tgt
->ltd_exp
, op_data
, lmm
, lmmsize
, it
, flags
,
193 reqp
, cb_blocking
, extra_lock_flags
);
197 * Nothing is found, do not access body->fid1 as it is zero and thus
200 if ((it
->d
.lustre
.it_disposition
& DISP_LOOKUP_NEG
) &&
201 !(it
->d
.lustre
.it_disposition
& DISP_OPEN_CREATE
) &&
202 !(it
->d
.lustre
.it_disposition
& DISP_OPEN_OPEN
))
205 body
= req_capsule_server_get(&(*reqp
)->rq_pill
, &RMF_MDT_BODY
);
209 * Not cross-ref case, just get out of here.
211 if (likely(!(body
->valid
& OBD_MD_MDS
)))
215 * Okay, MDS has returned success. Probably name has been resolved in
218 rc
= lmv_intent_remote(exp
, lmm
, lmmsize
, it
, &op_data
->op_fid1
, flags
,
219 reqp
, cb_blocking
, extra_lock_flags
);
223 * This is possible, that some userspace application will try to
224 * open file as directory and we will have -ENOTDIR here. As
225 * this is normal situation, we should not print error here,
228 CDEBUG(D_INODE
, "Can't handle remote %s: dir "DFID
"("DFID
"):"
229 "%*s: %d\n", LL_IT2STR(it
), PFID(&op_data
->op_fid2
),
230 PFID(&op_data
->op_fid1
), op_data
->op_namelen
,
231 op_data
->op_name
, rc
);
239 * Handler for: getattr, lookup and revalidate cases.
241 int lmv_intent_lookup(struct obd_export
*exp
, struct md_op_data
*op_data
,
242 void *lmm
, int lmmsize
, struct lookup_intent
*it
,
243 int flags
, struct ptlrpc_request
**reqp
,
244 ldlm_blocking_callback cb_blocking
,
245 __u64 extra_lock_flags
)
247 struct obd_device
*obd
= exp
->exp_obd
;
248 struct lmv_obd
*lmv
= &obd
->u
.lmv
;
249 struct lmv_tgt_desc
*tgt
= NULL
;
250 struct mdt_body
*body
;
253 tgt
= lmv_locate_mds(lmv
, op_data
, &op_data
->op_fid1
);
257 if (!fid_is_sane(&op_data
->op_fid2
))
258 fid_zero(&op_data
->op_fid2
);
260 CDEBUG(D_INODE
, "LOOKUP_INTENT with fid1="DFID
", fid2="DFID
261 ", name='%s' -> mds #%d\n", PFID(&op_data
->op_fid1
),
262 PFID(&op_data
->op_fid2
),
263 op_data
->op_name
? op_data
->op_name
: "<NULL>",
266 op_data
->op_bias
&= ~MDS_CROSS_REF
;
268 rc
= md_intent_lock(tgt
->ltd_exp
, op_data
, lmm
, lmmsize
, it
,
269 flags
, reqp
, cb_blocking
, extra_lock_flags
);
271 if (rc
< 0 || *reqp
== NULL
)
275 * MDS has returned success. Probably name has been resolved in
276 * remote inode. Let's check this.
278 body
= req_capsule_server_get(&(*reqp
)->rq_pill
, &RMF_MDT_BODY
);
281 /* Not cross-ref case, just get out of here. */
282 if (likely(!(body
->valid
& OBD_MD_MDS
)))
285 rc
= lmv_intent_remote(exp
, lmm
, lmmsize
, it
, NULL
, flags
, reqp
,
286 cb_blocking
, extra_lock_flags
);
291 int lmv_intent_lock(struct obd_export
*exp
, struct md_op_data
*op_data
,
292 void *lmm
, int lmmsize
, struct lookup_intent
*it
,
293 int flags
, struct ptlrpc_request
**reqp
,
294 ldlm_blocking_callback cb_blocking
,
295 __u64 extra_lock_flags
)
297 struct obd_device
*obd
= exp
->exp_obd
;
301 LASSERT(fid_is_sane(&op_data
->op_fid1
));
303 CDEBUG(D_INODE
, "INTENT LOCK '%s' for '%*s' on "DFID
"\n",
304 LL_IT2STR(it
), op_data
->op_namelen
, op_data
->op_name
,
305 PFID(&op_data
->op_fid1
));
307 rc
= lmv_check_connect(obd
);
311 if (it
->it_op
& (IT_LOOKUP
| IT_GETATTR
| IT_LAYOUT
))
312 rc
= lmv_intent_lookup(exp
, op_data
, lmm
, lmmsize
, it
,
313 flags
, reqp
, cb_blocking
,
315 else if (it
->it_op
& IT_OPEN
)
316 rc
= lmv_intent_open(exp
, op_data
, lmm
, lmmsize
, it
,
317 flags
, reqp
, cb_blocking
,