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) 2008, 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.
36 * glimpse code shared between vvp and liblustre (and other Lustre clients in
39 * Author: Nikita Danilov <nikita.danilov@sun.com>
40 * Author: Oleg Drokin <oleg.drokin@sun.com>
43 #include <linux/libcfs/libcfs.h>
44 #include <obd_class.h>
45 #include <obd_support.h>
48 # include <lustre_dlm.h>
49 # include <lustre_lite.h>
50 # include <lustre_mdc.h>
51 # include <linux/pagemap.h>
52 # include <linux/file.h>
54 #include "cl_object.h"
56 # include "../llite/llite_internal.h"
58 static const struct cl_lock_descr whole_file
= {
60 .cld_end
= CL_PAGE_EOF
,
65 * Check whether file has possible unwriten pages.
67 * \retval 1 file is mmap-ed or has dirty pages
70 blkcnt_t
dirty_cnt(struct inode
*inode
)
73 struct ccc_object
*vob
= cl_inode2ccc(inode
);
76 if (inode
->i_mapping
!= NULL
)
77 cnt
+= radix_tree_gang_lookup_tag(&inode
->i_mapping
->page_tree
,
80 if (cnt
== 0 && atomic_read(&vob
->cob_mmap_cnt
) > 0)
83 return (cnt
> 0) ? 1 : 0;
86 int cl_glimpse_lock(const struct lu_env
*env
, struct cl_io
*io
,
87 struct inode
*inode
, struct cl_object
*clob
, int agl
)
89 struct cl_lock_descr
*descr
= &ccc_env_info(env
)->cti_descr
;
90 struct cl_inode_info
*lli
= cl_i2info(inode
);
91 const struct lu_fid
*fid
= lu_object_fid(&clob
->co_lu
);
92 struct ccc_io
*cio
= ccc_env_io(env
);
97 if (!(lli
->lli_flags
& LLIF_MDS_SIZE_LOCK
)) {
98 CDEBUG(D_DLMTRACE
, "Glimpsing inode "DFID
"\n", PFID(fid
));
99 if (lli
->lli_has_smd
) {
100 /* NOTE: this looks like DLM lock request, but it may
101 * not be one. Due to CEF_ASYNC flag (translated
102 * to LDLM_FL_HAS_INTENT by osc), this is
103 * glimpse request, that won't revoke any
104 * conflicting DLM locks held. Instead,
105 * ll_glimpse_callback() will be called on each
106 * client holding a DLM lock against this file,
107 * and resulting size will be returned for each
108 * stripe. DLM lock on [0, EOF] is acquired only
109 * if there were no conflicting locks. If there
110 * were conflicting locks, enqueuing or waiting
111 * fails with -ENAVAIL, but valid inode
112 * attributes are returned anyway. */
114 descr
->cld_obj
= clob
;
115 descr
->cld_mode
= CLM_PHANTOM
;
116 descr
->cld_enq_flags
= CEF_ASYNC
| CEF_MUST
;
118 descr
->cld_enq_flags
|= CEF_AGL
;
119 cio
->cui_glimpse
= 1;
121 * CEF_ASYNC is used because glimpse sub-locks cannot
122 * deadlock (because they never conflict with other
123 * locks) and, hence, can be enqueued out-of-order.
125 * CEF_MUST protects glimpse lock from conversion into
128 lock
= cl_lock_request(env
, io
, descr
, "glimpse",
130 cio
->cui_glimpse
= 0;
136 return PTR_ERR(lock
);
139 result
= cl_wait(env
, lock
);
141 cl_merge_lvb(env
, inode
);
142 if (cl_isize_read(inode
) > 0 &&
143 inode
->i_blocks
== 0) {
145 * LU-417: Add dirty pages block count
146 * lest i_blocks reports 0, some "cp" or
147 * "tar" may think it's a completely
148 * sparse file and skip it.
150 inode
->i_blocks
= dirty_cnt(inode
);
154 cl_lock_release(env
, lock
, "glimpse", current
);
156 CDEBUG(D_DLMTRACE
, "No objects for inode\n");
157 cl_merge_lvb(env
, inode
);
164 static int cl_io_get(struct inode
*inode
, struct lu_env
**envout
,
165 struct cl_io
**ioout
, int *refcheck
)
169 struct cl_inode_info
*lli
= cl_i2info(inode
);
170 struct cl_object
*clob
= lli
->lli_clob
;
173 if (S_ISREG(cl_inode_mode(inode
))) {
174 env
= cl_env_get(refcheck
);
176 io
= ccc_env_thread_io(env
);
182 result
= PTR_ERR(env
);
188 int cl_glimpse_size0(struct inode
*inode
, int agl
)
191 * We don't need ast_flags argument to cl_glimpse_size(), because
192 * osc_lock_enqueue() takes care of the possible deadlock that said
193 * argument was introduced to avoid.
196 * XXX but note that ll_file_seek() passes LDLM_FL_BLOCK_NOWAIT to
197 * cl_glimpse_size(), which doesn't make sense: glimpse locks are not
200 struct lu_env
*env
= NULL
;
201 struct cl_io
*io
= NULL
;
205 result
= cl_io_get(inode
, &env
, &io
, &refcheck
);
208 io
->ci_verify_layout
= 1;
209 result
= cl_io_init(env
, io
, CIT_MISC
, io
->ci_obj
);
212 * nothing to do for this io. This currently happens
213 * when stripe sub-object's are not yet created.
215 result
= io
->ci_result
;
216 else if (result
== 0)
217 result
= cl_glimpse_lock(env
, io
, inode
, io
->ci_obj
,
220 OBD_FAIL_TIMEOUT(OBD_FAIL_GLIMPSE_DELAY
, 2);
222 if (unlikely(io
->ci_need_restart
))
224 cl_env_put(env
, &refcheck
);
229 int cl_local_size(struct inode
*inode
)
231 struct lu_env
*env
= NULL
;
232 struct cl_io
*io
= NULL
;
233 struct ccc_thread_info
*cti
;
234 struct cl_object
*clob
;
235 struct cl_lock_descr
*descr
;
236 struct cl_lock
*lock
;
240 if (!cl_i2info(inode
)->lli_has_smd
)
243 result
= cl_io_get(inode
, &env
, &io
, &refcheck
);
248 result
= cl_io_init(env
, io
, CIT_MISC
, clob
);
250 result
= io
->ci_result
;
251 else if (result
== 0) {
252 cti
= ccc_env_info(env
);
253 descr
= &cti
->cti_descr
;
256 descr
->cld_obj
= clob
;
257 lock
= cl_lock_peek(env
, io
, descr
, "localsize", current
);
259 cl_merge_lvb(env
, inode
);
261 cl_lock_release(env
, lock
, "localsize", current
);
267 cl_env_put(env
, &refcheck
);
This page took 0.041741 seconds and 5 git commands to generate.