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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
30 * Copyright (c) 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_LOV
39 #include <linux/libcfs/libcfs.h>
41 #include <obd_class.h>
44 #include "lov_internal.h"
46 /** Merge the lock value block(&lvb) attributes and KMS from each of the
47 * stripes in a file into a single lvb. It is expected that the caller
48 * initializes the current atime, mtime, ctime to avoid regressing a more
49 * uptodate time on the local client.
51 int lov_merge_lvb_kms(struct lov_stripe_md
*lsm
,
52 struct ost_lvb
*lvb
, __u64
*kms_place
)
57 obd_time current_mtime
= lvb
->lvb_mtime
;
58 obd_time current_atime
= lvb
->lvb_atime
;
59 obd_time current_ctime
= lvb
->lvb_ctime
;
63 LASSERT(spin_is_locked(&lsm
->lsm_lock
));
64 LASSERT(lsm
->lsm_lock_owner
== current_pid());
66 CDEBUG(D_INODE
, "MDT ID "DOSTID
" initial value: s="LPU64
" m="LPU64
67 " a="LPU64
" c="LPU64
" b="LPU64
"\n", POSTID(&lsm
->lsm_oi
),
68 lvb
->lvb_size
, lvb
->lvb_mtime
, lvb
->lvb_atime
, lvb
->lvb_ctime
,
70 for (i
= 0; i
< lsm
->lsm_stripe_count
; i
++) {
71 struct lov_oinfo
*loi
= lsm
->lsm_oinfo
[i
];
72 obd_size lov_size
, tmpsize
;
74 if (OST_LVB_IS_ERR(loi
->loi_lvb
.lvb_blocks
)) {
75 rc
= OST_LVB_GET_ERR(loi
->loi_lvb
.lvb_blocks
);
79 tmpsize
= loi
->loi_kms
;
80 lov_size
= lov_stripe_size(lsm
, tmpsize
, i
);
84 if (loi
->loi_lvb
.lvb_size
> tmpsize
)
85 tmpsize
= loi
->loi_lvb
.lvb_size
;
87 lov_size
= lov_stripe_size(lsm
, tmpsize
, i
);
90 /* merge blocks, mtime, atime */
91 blocks
+= loi
->loi_lvb
.lvb_blocks
;
92 if (loi
->loi_lvb
.lvb_mtime
> current_mtime
)
93 current_mtime
= loi
->loi_lvb
.lvb_mtime
;
94 if (loi
->loi_lvb
.lvb_atime
> current_atime
)
95 current_atime
= loi
->loi_lvb
.lvb_atime
;
96 if (loi
->loi_lvb
.lvb_ctime
> current_ctime
)
97 current_ctime
= loi
->loi_lvb
.lvb_ctime
;
99 CDEBUG(D_INODE
, "MDT ID "DOSTID
" on OST[%u]: s="LPU64
" m="LPU64
100 " a="LPU64
" c="LPU64
" b="LPU64
"\n", POSTID(&lsm
->lsm_oi
),
101 loi
->loi_ost_idx
, loi
->loi_lvb
.lvb_size
,
102 loi
->loi_lvb
.lvb_mtime
, loi
->loi_lvb
.lvb_atime
,
103 loi
->loi_lvb
.lvb_ctime
, loi
->loi_lvb
.lvb_blocks
);
107 lvb
->lvb_size
= size
;
108 lvb
->lvb_blocks
= blocks
;
109 lvb
->lvb_mtime
= current_mtime
;
110 lvb
->lvb_atime
= current_atime
;
111 lvb
->lvb_ctime
= current_ctime
;
115 /** Merge the lock value block(&lvb) attributes from each of the stripes in a
116 * file into a single lvb. It is expected that the caller initializes the
117 * current atime, mtime, ctime to avoid regressing a more uptodate time on
120 * If \a kms_only is set then we do not consider the recently seen size (rss)
121 * when updating the known minimum size (kms). Even when merging RSS, we will
122 * take the KMS value if it's larger. This prevents getattr from stomping on
123 * dirty cached pages which extend the file size. */
124 int lov_merge_lvb(struct obd_export
*exp
,
125 struct lov_stripe_md
*lsm
, struct ost_lvb
*lvb
, int kms_only
)
131 lov_stripe_lock(lsm
);
132 rc
= lov_merge_lvb_kms(lsm
, lvb
, &kms
);
133 lov_stripe_unlock(lsm
);
137 CDEBUG(D_INODE
, "merged for ID "DOSTID
" s="LPU64
" m="LPU64
" a="LPU64
138 " c="LPU64
" b="LPU64
"\n", POSTID(&lsm
->lsm_oi
), lvb
->lvb_size
,
139 lvb
->lvb_mtime
, lvb
->lvb_atime
, lvb
->lvb_ctime
, lvb
->lvb_blocks
);
143 /* Must be called under the lov_stripe_lock() */
144 int lov_adjust_kms(struct obd_export
*exp
, struct lov_stripe_md
*lsm
,
145 obd_off size
, int shrink
)
147 struct lov_oinfo
*loi
;
152 LASSERT(spin_is_locked(&lsm
->lsm_lock
));
153 LASSERT(lsm
->lsm_lock_owner
== current_pid());
156 for (; stripe
< lsm
->lsm_stripe_count
; stripe
++) {
157 struct lov_oinfo
*loi
= lsm
->lsm_oinfo
[stripe
];
158 kms
= lov_size_to_stripe(lsm
, size
, stripe
);
160 "stripe %d KMS %sing "LPU64
"->"LPU64
"\n",
161 stripe
, kms
> loi
->loi_kms
? "increas":"shrink",
163 loi_kms_set(loi
, loi
->loi_lvb
.lvb_size
= kms
);
169 stripe
= lov_stripe_number(lsm
, size
- 1);
170 kms
= lov_size_to_stripe(lsm
, size
, stripe
);
171 loi
= lsm
->lsm_oinfo
[stripe
];
173 CDEBUG(D_INODE
, "stripe %d KMS %sincreasing "LPU64
"->"LPU64
"\n",
174 stripe
, kms
> loi
->loi_kms
? "" : "not ", loi
->loi_kms
, kms
);
175 if (kms
> loi
->loi_kms
)
176 loi_kms_set(loi
, kms
);
181 void lov_merge_attrs(struct obdo
*tgt
, struct obdo
*src
, obd_valid valid
,
182 struct lov_stripe_md
*lsm
, int stripeno
, int *set
)
184 valid
&= src
->o_valid
;
187 if (valid
& OBD_MD_FLSIZE
) {
188 /* this handles sparse files properly */
191 lov_size
= lov_stripe_size(lsm
, src
->o_size
, stripeno
);
192 if (lov_size
> tgt
->o_size
)
193 tgt
->o_size
= lov_size
;
195 if (valid
& OBD_MD_FLBLOCKS
)
196 tgt
->o_blocks
+= src
->o_blocks
;
197 if (valid
& OBD_MD_FLBLKSZ
)
198 tgt
->o_blksize
+= src
->o_blksize
;
199 if (valid
& OBD_MD_FLCTIME
&& tgt
->o_ctime
< src
->o_ctime
)
200 tgt
->o_ctime
= src
->o_ctime
;
201 if (valid
& OBD_MD_FLMTIME
&& tgt
->o_mtime
< src
->o_mtime
)
202 tgt
->o_mtime
= src
->o_mtime
;
203 if (valid
& OBD_MD_FLDATAVERSION
)
204 tgt
->o_data_version
+= src
->o_data_version
;
206 memcpy(tgt
, src
, sizeof(*tgt
));
207 tgt
->o_oi
= lsm
->lsm_oi
;
208 if (valid
& OBD_MD_FLSIZE
)
209 tgt
->o_size
= lov_stripe_size(lsm
, src
->o_size
,
213 /* data_version needs to be valid on all stripes to be correct! */
214 if (!(valid
& OBD_MD_FLDATAVERSION
))
215 tgt
->o_valid
&= ~OBD_MD_FLDATAVERSION
;
This page took 0.052002 seconds and 6 git commands to generate.