1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
5 * Lustre Metadata Server (mds) handling of striped file data
7 * Copyright (C) 2001-2003 Cluster File Systems, Inc.
8 * Author: Peter Braam <braam@clusterfs.com>
10 * This file is part of Lustre, http://www.lustre.org.
12 * Lustre is free software; you can redistribute it and/or
13 * modify it under the terms of version 2 of the GNU General Public
14 * License as published by the Free Software Foundation.
16 * Lustre is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with Lustre; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #define DEBUG_SUBSYSTEM S_MDS
29 #include <linux/module.h>
30 #include <linux/lustre_mds.h>
31 #include <linux/lustre_idl.h>
32 #include <linux/obd_class.h>
33 #include <linux/obd_lov.h>
34 #include <linux/lustre_lib.h>
35 #include <linux/lustre_fsfilt.h>
37 #include "mds_internal.h"
39 void le_lov_desc_to_cpu (struct lov_desc *ld)
41 ld->ld_tgt_count = le32_to_cpu (ld->ld_tgt_count);
42 ld->ld_default_stripe_count = le32_to_cpu (ld->ld_default_stripe_count);
43 ld->ld_default_stripe_size = le32_to_cpu (ld->ld_default_stripe_size);
44 ld->ld_pattern = le32_to_cpu (ld->ld_pattern);
47 void cpu_to_le_lov_desc (struct lov_desc *ld)
49 ld->ld_tgt_count = cpu_to_le32 (ld->ld_tgt_count);
50 ld->ld_default_stripe_count = cpu_to_le32 (ld->ld_default_stripe_count);
51 ld->ld_default_stripe_size = cpu_to_le32 (ld->ld_default_stripe_size);
52 ld->ld_pattern = cpu_to_le32 (ld->ld_pattern);
55 int mds_set_lovdesc(struct obd_device *obd, struct lov_desc *desc,
56 struct obd_uuid *uuidarray)
58 struct mds_obd *mds = &obd->u.mds;
59 struct obd_run_ctxt saved;
64 struct lov_desc *disk_desc;
67 tgt_count = desc->ld_tgt_count;
68 if (desc->ld_default_stripe_count > desc->ld_tgt_count) {
69 CERROR("default stripe count %u > OST count %u\n",
70 desc->ld_default_stripe_count, desc->ld_tgt_count);
73 if (desc->ld_default_stripe_size & (PAGE_SIZE - 1)) {
74 CERROR("default stripe size "LPU64" not a multiple of %lu\n",
75 desc->ld_default_stripe_size, PAGE_SIZE);
78 if (desc->ld_default_stripe_offset > desc->ld_tgt_count) {
79 CERROR("default stripe offset "LPU64" > max OST index %u\n",
80 desc->ld_default_stripe_offset, desc->ld_tgt_count);
83 if (desc->ld_pattern != 0) {
84 CERROR("stripe pattern %u unknown\n",
89 OBD_ALLOC (disk_desc, sizeof (*disk_desc));
90 if (disk_desc == NULL) {
91 CERROR ("Can't allocate disk_desc\n");
96 cpu_to_le_lov_desc (disk_desc);
99 push_ctxt(&saved, &mds->mds_ctxt, NULL);
101 /* Bug 1186: FIXME: if there is an existing LOVDESC, verify new
103 f = filp_open("LOVDESC", O_CREAT|O_RDWR, 0644);
105 CERROR("Cannot open/create LOVDESC file\n");
106 GOTO(out, rc = PTR_ERR(f));
109 rc = lustre_fwrite(f, (char *)disk_desc, sizeof(*disk_desc), &f->f_pos);
110 if (filp_close(f, 0))
111 CERROR("Error closing LOVDESC file\n");
112 if (rc != sizeof(*desc)) {
113 CERROR("Cannot open/create LOVDESC file\n");
119 /* Bug 1186: FIXME: if there is an existing LOVTGTS, verify
120 * existing UUIDs same */
121 f = filp_open("LOVTGTS", O_CREAT|O_RDWR, 0644);
123 CERROR("Cannot open/create LOVTGTS file\n");
124 GOTO(out, rc = PTR_ERR(f));
128 for (i = 0; i < tgt_count ; i++) {
129 rc = lustre_fwrite(f, uuidarray[i].uuid,
130 sizeof(uuidarray[i]), &f->f_pos);
131 if (rc != sizeof(uuidarray[i])) {
132 CERROR("cannot write LOV UUID %s (%d)\n",
133 uuidarray[i].uuid, i);
140 if (filp_close(f, 0))
141 CERROR("Error closing LOVTGTS file\n");
143 memcpy(&mds->mds_lov_desc, desc, sizeof *desc);
144 mds->mds_has_lov_desc = 1;
145 /* XXX the MDS should not really know about this */
146 mds->mds_max_mdsize = lov_mds_md_size(desc->ld_tgt_count);
147 mds->mds_max_cookiesize = desc->ld_tgt_count*sizeof(struct llog_cookie);
150 pop_ctxt(&saved, &mds->mds_ctxt, NULL);
151 OBD_FREE (disk_desc, sizeof (*disk_desc));
156 int mds_get_lovdesc(struct mds_obd *mds, struct lov_desc *desc)
158 struct obd_run_ctxt saved;
163 push_ctxt(&saved, &mds->mds_ctxt, NULL);
164 f = filp_open("LOVDESC", O_RDONLY, 0644);
166 CERROR("Cannot open LOVDESC file\n");
167 GOTO(out, rc = PTR_ERR(f));
170 rc = lustre_fread(f, (char *)desc, sizeof(*desc), &f->f_pos);
171 if (filp_close(f, 0))
172 CERROR("Error closing LOVDESC file\n");
174 if (rc != sizeof(*desc)) {
175 CERROR("Cannot read LOVDESC file: rc = %d\n", rc);
176 GOTO(out, rc = -EIO);
180 le_lov_desc_to_cpu (desc); /* convert to my byte order */
184 pop_ctxt(&saved, &mds->mds_ctxt, NULL);
189 int mds_get_lovtgts(struct mds_obd *mds, int tgt_count,
190 struct obd_uuid *uuidarray)
192 struct obd_run_ctxt saved;
197 push_ctxt(&saved, &mds->mds_ctxt, NULL);
198 f = filp_open("LOVTGTS", O_RDONLY, 0644);
200 CERROR("Cannot open LOVTGTS file\n");
201 GOTO(out, rc = PTR_ERR(f));
204 rc = lustre_fread(f, (char *)uuidarray, tgt_count * sizeof(*uuidarray),
206 rc2 = filp_close(f, 0);
208 CERROR("Error closing LOVTGTS file: rc = %d\n", rc2);
210 if (rc != tgt_count * sizeof(*uuidarray)) {
211 CERROR("Error reading LOVTGTS file: rc = %d\n", rc);
219 pop_ctxt(&saved, &mds->mds_ctxt, NULL);
224 int mds_iocontrol(unsigned int cmd, struct lustre_handle *conn,
225 int len, void *karg, void *uarg)
227 struct obd_device *obd = class_conn2obd(conn);
228 struct obd_ioctl_data *data = karg;
229 struct lov_desc *desc;
230 struct obd_uuid *uuidarray;
235 case OBD_IOC_LOV_SET_CONFIG:
236 desc = (struct lov_desc *)data->ioc_inlbuf1;
237 if (sizeof(*desc) > data->ioc_inllen1) {
238 CERROR("descriptor size wrong\n");
242 count = desc->ld_tgt_count;
243 uuidarray = (struct obd_uuid *)data->ioc_inlbuf2;
244 if (sizeof(*uuidarray) * count != data->ioc_inllen2) {
245 CERROR("UUID array size wrong\n");
248 rc = mds_set_lovdesc(obd, desc, uuidarray);
251 case OBD_IOC_LOV_GET_CONFIG:
252 desc = (struct lov_desc *)data->ioc_inlbuf1;
253 if (sizeof(*desc) > data->ioc_inllen1) {
254 CERROR("descriptor size wrong\n");
258 count = desc->ld_tgt_count;
259 uuidarray = (struct obd_uuid *)data->ioc_inlbuf2;
260 if (sizeof(*uuidarray) * count != data->ioc_inllen2) {
261 CERROR("UUID array size wrong\n");
264 rc = mds_get_lovdesc(&obd->u.mds, desc);
265 if (desc->ld_tgt_count > count) {
266 CERROR("UUID array size too small\n");
269 rc = mds_get_lovtgts(&obd->u.mds, desc->ld_tgt_count,
274 case OBD_IOC_SET_READONLY: {
275 BDEVNAME_DECLARE_STORAGE(tmp);
276 CERROR("setting device %s read-only\n",
277 ll_bdevname(obd->u.mds.mds_sb->s_dev, tmp));
278 dev_set_rdonly(obd->u.mds.mds_sb->s_dev, 2);
282 case OBD_IOC_ABORT_RECOVERY:
283 CERROR("aborting recovery for device %s\n", obd->obd_name);
284 target_abort_recovery(obd);