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>
36 void le_lov_desc_to_cpu (struct lov_desc *ld)
38 ld->ld_tgt_count = le32_to_cpu (ld->ld_tgt_count);
39 ld->ld_default_stripe_count = le32_to_cpu (ld->ld_default_stripe_count);
40 ld->ld_default_stripe_size = le32_to_cpu (ld->ld_default_stripe_size);
41 ld->ld_pattern = le32_to_cpu (ld->ld_pattern);
44 void cpu_to_le_lov_desc (struct lov_desc *ld)
46 ld->ld_tgt_count = cpu_to_le32 (ld->ld_tgt_count);
47 ld->ld_default_stripe_count = cpu_to_le32 (ld->ld_default_stripe_count);
48 ld->ld_default_stripe_size = cpu_to_le32 (ld->ld_default_stripe_size);
49 ld->ld_pattern = cpu_to_le32 (ld->ld_pattern);
52 int mds_set_lovdesc(struct obd_device *obd, struct lov_desc *desc,
53 struct obd_uuid *uuidarray)
55 struct mds_obd *mds = &obd->u.mds;
56 struct obd_run_ctxt saved;
61 struct lov_desc *disk_desc;
64 tgt_count = desc->ld_tgt_count;
65 if (desc->ld_default_stripe_count > desc->ld_tgt_count) {
66 CERROR("default stripe count %u > OST count %u\n",
67 desc->ld_default_stripe_count, desc->ld_tgt_count);
70 if (desc->ld_default_stripe_size & (PAGE_SIZE - 1)) {
71 CERROR("default stripe size "LPU64" not a multiple of %lu\n",
72 desc->ld_default_stripe_size, PAGE_SIZE);
75 if (desc->ld_default_stripe_offset > desc->ld_tgt_count) {
76 CERROR("default stripe offset "LPU64" > max OST index %u\n",
77 desc->ld_default_stripe_offset, desc->ld_tgt_count);
80 if (desc->ld_pattern != 0) {
81 CERROR("stripe pattern %u unknown\n",
86 OBD_ALLOC (disk_desc, sizeof (*disk_desc));
87 if (disk_desc == NULL) {
88 CERROR ("Can't allocate disk_desc\n");
93 cpu_to_le_lov_desc (disk_desc);
96 push_ctxt(&saved, &mds->mds_ctxt, NULL);
98 /* Bug 1186: FIXME: if there is an existing LOVDESC, verify new
100 f = filp_open("LOVDESC", O_CREAT|O_RDWR, 0644);
102 CERROR("Cannot open/create LOVDESC file\n");
103 GOTO(out, rc = PTR_ERR(f));
106 rc = lustre_fwrite(f, (char *)disk_desc, sizeof(*disk_desc), &f->f_pos);
107 if (filp_close(f, 0))
108 CERROR("Error closing LOVDESC file\n");
109 if (rc != sizeof(*desc)) {
110 CERROR("Cannot open/create LOVDESC file\n");
116 /* Bug 1186: FIXME: if there is an existing LOVTGTS, verify
117 * existing UUIDs same */
118 f = filp_open("LOVTGTS", O_CREAT|O_RDWR, 0644);
120 CERROR("Cannot open/create LOVTGTS file\n");
121 GOTO(out, rc = PTR_ERR(f));
125 for (i = 0; i < tgt_count ; i++) {
126 rc = lustre_fwrite(f, uuidarray[i].uuid,
127 sizeof(uuidarray[i]), &f->f_pos);
128 if (rc != sizeof(uuidarray[i])) {
129 CERROR("cannot write LOV UUID %s (%d)\n",
130 uuidarray[i].uuid, i);
137 if (filp_close(f, 0))
138 CERROR("Error closing LOVTGTS file\n");
140 memcpy(&mds->mds_lov_desc, desc, sizeof *desc);
141 mds->mds_has_lov_desc = 1;
142 /* XXX the MDS should not really know about this */
143 mds->mds_max_mdsize = lov_mds_md_size(desc->ld_tgt_count);
146 pop_ctxt(&saved, &mds->mds_ctxt, NULL);
147 OBD_FREE (disk_desc, sizeof (*disk_desc));
152 int mds_get_lovdesc(struct mds_obd *mds, struct lov_desc *desc)
154 struct obd_run_ctxt saved;
159 push_ctxt(&saved, &mds->mds_ctxt, NULL);
160 f = filp_open("LOVDESC", O_RDONLY, 0644);
162 CERROR("Cannot open LOVDESC file\n");
163 GOTO(out, rc = PTR_ERR(f));
166 rc = lustre_fread(f, (char *)desc, sizeof(*desc), &f->f_pos);
167 if (filp_close(f, 0))
168 CERROR("Error closing LOVDESC file\n");
170 if (rc != sizeof(*desc)) {
171 CERROR("Cannot read LOVDESC file: rc = %d\n", rc);
172 GOTO(out, rc = -EIO);
176 le_lov_desc_to_cpu (desc); /* convert to my byte order */
180 pop_ctxt(&saved, &mds->mds_ctxt, NULL);
185 int mds_get_lovtgts(struct mds_obd *mds, int tgt_count,struct obd_uuid *uuidarray)
187 struct obd_run_ctxt saved;
192 push_ctxt(&saved, &mds->mds_ctxt, NULL);
193 f = filp_open("LOVTGTS", O_RDONLY, 0644);
195 CERROR("Cannot open LOVTGTS file\n");
196 GOTO(out, rc = PTR_ERR(f));
199 rc = lustre_fread(f, (char *)uuidarray, tgt_count * sizeof(*uuidarray),
201 rc2 = filp_close(f, 0);
203 CERROR("Error closing LOVTGTS file: rc = %d\n", rc2);
205 if (rc != tgt_count * sizeof(*uuidarray)) {
206 CERROR("Error reading LOVTGTS file: rc = %d\n", rc);
214 pop_ctxt(&saved, &mds->mds_ctxt, NULL);
219 int mds_iocontrol(unsigned int cmd, struct lustre_handle *conn,
220 int len, void *karg, void *uarg)
222 struct obd_device *obd = class_conn2obd(conn);
223 struct obd_ioctl_data *data = karg;
224 struct lov_desc *desc;
225 struct obd_uuid *uuidarray;
230 case OBD_IOC_LOV_SET_CONFIG:
231 desc = (struct lov_desc *)data->ioc_inlbuf1;
232 if (sizeof(*desc) > data->ioc_inllen1) {
233 CERROR("descriptor size wrong\n");
237 count = desc->ld_tgt_count;
238 uuidarray = (struct obd_uuid *)data->ioc_inlbuf2;
239 if (sizeof(*uuidarray) * count != data->ioc_inllen2) {
240 CERROR("UUID array size wrong\n");
243 rc = mds_set_lovdesc(obd, desc, uuidarray);
246 case OBD_IOC_LOV_GET_CONFIG:
247 desc = (struct lov_desc *)data->ioc_inlbuf1;
248 if (sizeof(*desc) > data->ioc_inllen1) {
249 CERROR("descriptor size wrong\n");
253 count = desc->ld_tgt_count;
254 uuidarray = (struct obd_uuid *)data->ioc_inlbuf2;
255 if (sizeof(*uuidarray) * count != data->ioc_inllen2) {
256 CERROR("UUID array size wrong\n");
259 rc = mds_get_lovdesc(&obd->u.mds, desc);
260 if (desc->ld_tgt_count > count) {
261 CERROR("UUID array size too small\n");
264 rc = mds_get_lovtgts(&obd->u.mds, desc->ld_tgt_count,
269 case OBD_IOC_SET_READONLY:
270 CERROR("setting device %s read-only\n",
271 ll_bdevname(obd->u.mds.mds_sb->s_dev));
272 #ifdef CONFIG_DEV_RDONLY
273 dev_set_rdonly(obd->u.mds.mds_sb->s_dev, 2);
277 case OBD_IOC_ABORT_RECOVERY:
278 CERROR("aborting recovery for device %s\n", obd->obd_name);
279 target_abort_recovery(obd);