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/slab.h>
42 #include <linux/pagemap.h>
43 #include <asm/div64.h>
44 #include <linux/seq_file.h>
45 #include <linux/namei.h>
46 #include <linux/lustre_intent.h>
48 #include <obd_support.h>
49 #include <lustre/lustre_idl.h>
50 #include <lustre_lib.h>
51 #include <lustre_net.h>
52 #include <lustre_dlm.h>
53 #include <obd_class.h>
54 #include <lprocfs_status.h>
55 #include "lmv_internal.h"
57 static int lmv_intent_remote(struct obd_export
*exp
, void *lmm
,
58 int lmmsize
, struct lookup_intent
*it
,
59 const struct lu_fid
*parent_fid
, int flags
,
60 struct ptlrpc_request
**reqp
,
61 ldlm_blocking_callback cb_blocking
,
62 __u64 extra_lock_flags
)
64 struct obd_device
*obd
= exp
->exp_obd
;
65 struct lmv_obd
*lmv
= &obd
->u
.lmv
;
66 struct ptlrpc_request
*req
= NULL
;
67 struct lustre_handle plock
;
68 struct md_op_data
*op_data
;
69 struct lmv_tgt_desc
*tgt
;
70 struct mdt_body
*body
;
75 body
= req_capsule_server_get(&(*reqp
)->rq_pill
, &RMF_MDT_BODY
);
79 LASSERT((body
->valid
& OBD_MD_MDS
));
82 * Unfortunately, we have to lie to MDC/MDS to retrieve
83 * attributes llite needs and provideproper locking.
85 if (it
->it_op
& IT_LOOKUP
)
86 it
->it_op
= IT_GETATTR
;
89 * We got LOOKUP lock, but we really need attrs.
91 pmode
= it
->d
.lustre
.it_lock_mode
;
93 plock
.cookie
= it
->d
.lustre
.it_lock_handle
;
94 it
->d
.lustre
.it_lock_mode
= 0;
95 it
->d
.lustre
.it_data
= NULL
;
98 LASSERT(fid_is_sane(&body
->fid1
));
100 tgt
= lmv_find_target(lmv
, &body
->fid1
);
102 GOTO(out
, rc
= PTR_ERR(tgt
));
104 OBD_ALLOC_PTR(op_data
);
106 GOTO(out
, rc
= -ENOMEM
);
108 op_data
->op_fid1
= body
->fid1
;
109 /* Sent the parent FID to the remote MDT */
110 if (parent_fid
!= NULL
) {
111 /* The parent fid is only for remote open to
112 * check whether the open is from OBF,
113 * see mdt_cross_open */
114 LASSERT(it
->it_op
& IT_OPEN
);
115 op_data
->op_fid2
= *parent_fid
;
116 /* Add object FID to op_fid3, in case it needs to check stale
117 * (M_CHECK_STALE), see mdc_finish_intent_lock */
118 op_data
->op_fid3
= body
->fid1
;
121 op_data
->op_bias
= MDS_CROSS_REF
;
122 CDEBUG(D_INODE
, "REMOTE_INTENT with fid="DFID
" -> mds #%d\n",
123 PFID(&body
->fid1
), tgt
->ltd_idx
);
125 it
->d
.lustre
.it_disposition
&= ~DISP_ENQ_COMPLETE
;
126 rc
= md_intent_lock(tgt
->ltd_exp
, op_data
, lmm
, lmmsize
, it
,
127 flags
, &req
, cb_blocking
, extra_lock_flags
);
129 GOTO(out_free_op_data
, rc
);
132 * LLite needs LOOKUP lock to track dentry revocation in order to
133 * maintain dcache consistency. Thus drop UPDATE|PERM lock here
134 * and put LOOKUP in request.
136 if (it
->d
.lustre
.it_lock_mode
!= 0) {
137 it
->d
.lustre
.it_remote_lock_handle
=
138 it
->d
.lustre
.it_lock_handle
;
139 it
->d
.lustre
.it_remote_lock_mode
= it
->d
.lustre
.it_lock_mode
;
142 it
->d
.lustre
.it_lock_handle
= plock
.cookie
;
143 it
->d
.lustre
.it_lock_mode
= pmode
;
147 OBD_FREE_PTR(op_data
);
150 ldlm_lock_decref(&plock
, pmode
);
152 ptlrpc_req_finished(*reqp
);
158 * IT_OPEN is intended to open (and create, possible) an object. Parent (pid)
161 int lmv_intent_open(struct obd_export
*exp
, struct md_op_data
*op_data
,
162 void *lmm
, int lmmsize
, struct lookup_intent
*it
,
163 int flags
, struct ptlrpc_request
**reqp
,
164 ldlm_blocking_callback cb_blocking
,
165 __u64 extra_lock_flags
)
167 struct obd_device
*obd
= exp
->exp_obd
;
168 struct lmv_obd
*lmv
= &obd
->u
.lmv
;
169 struct lmv_tgt_desc
*tgt
;
170 struct mdt_body
*body
;
174 tgt
= lmv_locate_mds(lmv
, op_data
, &op_data
->op_fid1
);
176 RETURN(PTR_ERR(tgt
));
178 /* If it is ready to open the file by FID, do not need
179 * allocate FID at all, otherwise it will confuse MDT */
180 if ((it
->it_op
& IT_CREAT
) &&
181 !(it
->it_flags
& MDS_OPEN_BY_FID
)) {
183 * For open with IT_CREATE and for IT_CREATE cases allocate new
184 * fid and setup FLD for it.
186 op_data
->op_fid3
= op_data
->op_fid2
;
187 rc
= lmv_fid_alloc(exp
, &op_data
->op_fid2
, op_data
);
192 CDEBUG(D_INODE
, "OPEN_INTENT with fid1="DFID
", fid2="DFID
","
193 " name='%s' -> mds #%d\n", PFID(&op_data
->op_fid1
),
194 PFID(&op_data
->op_fid2
), op_data
->op_name
, tgt
->ltd_idx
);
196 rc
= md_intent_lock(tgt
->ltd_exp
, op_data
, lmm
, lmmsize
, it
, flags
,
197 reqp
, cb_blocking
, extra_lock_flags
);
201 * Nothing is found, do not access body->fid1 as it is zero and thus
204 if ((it
->d
.lustre
.it_disposition
& DISP_LOOKUP_NEG
) &&
205 !(it
->d
.lustre
.it_disposition
& DISP_OPEN_CREATE
) &&
206 !(it
->d
.lustre
.it_disposition
& DISP_OPEN_OPEN
))
209 body
= req_capsule_server_get(&(*reqp
)->rq_pill
, &RMF_MDT_BODY
);
213 * Not cross-ref case, just get out of here.
215 if (likely(!(body
->valid
& OBD_MD_MDS
)))
219 * Okay, MDS has returned success. Probably name has been resolved in
222 rc
= lmv_intent_remote(exp
, lmm
, lmmsize
, it
, &op_data
->op_fid1
, flags
,
223 reqp
, cb_blocking
, extra_lock_flags
);
227 * This is possible, that some userspace application will try to
228 * open file as directory and we will have -ENOTDIR here. As
229 * this is normal situation, we should not print error here,
232 CDEBUG(D_INODE
, "Can't handle remote %s: dir "DFID
"("DFID
"):"
233 "%*s: %d\n", LL_IT2STR(it
), PFID(&op_data
->op_fid2
),
234 PFID(&op_data
->op_fid1
), op_data
->op_namelen
,
235 op_data
->op_name
, rc
);
243 * Handler for: getattr, lookup and revalidate cases.
245 int lmv_intent_lookup(struct obd_export
*exp
, struct md_op_data
*op_data
,
246 void *lmm
, int lmmsize
, struct lookup_intent
*it
,
247 int flags
, struct ptlrpc_request
**reqp
,
248 ldlm_blocking_callback cb_blocking
,
249 __u64 extra_lock_flags
)
251 struct obd_device
*obd
= exp
->exp_obd
;
252 struct lmv_obd
*lmv
= &obd
->u
.lmv
;
253 struct lmv_tgt_desc
*tgt
= NULL
;
254 struct mdt_body
*body
;
258 tgt
= lmv_locate_mds(lmv
, op_data
, &op_data
->op_fid1
);
260 RETURN(PTR_ERR(tgt
));
262 if (!fid_is_sane(&op_data
->op_fid2
))
263 fid_zero(&op_data
->op_fid2
);
265 CDEBUG(D_INODE
, "LOOKUP_INTENT with fid1="DFID
", fid2="DFID
266 ", name='%s' -> mds #%d\n", PFID(&op_data
->op_fid1
),
267 PFID(&op_data
->op_fid2
),
268 op_data
->op_name
? op_data
->op_name
: "<NULL>",
271 op_data
->op_bias
&= ~MDS_CROSS_REF
;
273 rc
= md_intent_lock(tgt
->ltd_exp
, op_data
, lmm
, lmmsize
, it
,
274 flags
, reqp
, cb_blocking
, extra_lock_flags
);
276 if (rc
< 0 || *reqp
== NULL
)
280 * MDS has returned success. Probably name has been resolved in
281 * remote inode. Let's check this.
283 body
= req_capsule_server_get(&(*reqp
)->rq_pill
, &RMF_MDT_BODY
);
286 /* Not cross-ref case, just get out of here. */
287 if (likely(!(body
->valid
& OBD_MD_MDS
)))
290 rc
= lmv_intent_remote(exp
, lmm
, lmmsize
, it
, NULL
, flags
, reqp
,
291 cb_blocking
, extra_lock_flags
);
296 int lmv_intent_lock(struct obd_export
*exp
, struct md_op_data
*op_data
,
297 void *lmm
, int lmmsize
, struct lookup_intent
*it
,
298 int flags
, struct ptlrpc_request
**reqp
,
299 ldlm_blocking_callback cb_blocking
,
300 __u64 extra_lock_flags
)
302 struct obd_device
*obd
= exp
->exp_obd
;
307 LASSERT(fid_is_sane(&op_data
->op_fid1
));
309 CDEBUG(D_INODE
, "INTENT LOCK '%s' for '%*s' on "DFID
"\n",
310 LL_IT2STR(it
), op_data
->op_namelen
, op_data
->op_name
,
311 PFID(&op_data
->op_fid1
));
313 rc
= lmv_check_connect(obd
);
317 if (it
->it_op
& (IT_LOOKUP
| IT_GETATTR
| IT_LAYOUT
))
318 rc
= lmv_intent_lookup(exp
, op_data
, lmm
, lmmsize
, it
,
319 flags
, reqp
, cb_blocking
,
321 else if (it
->it_op
& IT_OPEN
)
322 rc
= lmv_intent_open(exp
, op_data
, lmm
, lmmsize
, it
,
323 flags
, reqp
, cb_blocking
,