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 /* lov_unpackdesc() is in lov/lov_pack.c */
38 void lov_packdesc(struct lov_desc *ld)
40 ld->ld_tgt_count = HTON__u32(ld->ld_tgt_count);
41 ld->ld_default_stripe_count = HTON__u32(ld->ld_default_stripe_count);
42 ld->ld_default_stripe_size = HTON__u32(ld->ld_default_stripe_size);
43 ld->ld_pattern = HTON__u32(ld->ld_pattern);
46 int mds_set_lovdesc(struct obd_device *obd, struct lov_desc *desc,
47 struct obd_uuid *uuidarray)
49 struct mds_obd *mds = &obd->u.mds;
50 struct obd_run_ctxt saved;
57 tgt_count = desc->ld_tgt_count;
58 if (desc->ld_default_stripe_count > desc->ld_tgt_count) {
59 CERROR("default stripe count %u > OST count %u\n",
60 desc->ld_default_stripe_count, desc->ld_tgt_count);
63 if (desc->ld_default_stripe_size & (PAGE_SIZE - 1)) {
64 CERROR("default stripe size "LPU64" not a multiple of %lu\n",
65 desc->ld_default_stripe_size, PAGE_SIZE);
68 if (desc->ld_default_stripe_offset > desc->ld_tgt_count) {
69 CERROR("default stripe offset "LPU64" > max OST index %u\n",
70 desc->ld_default_stripe_offset, desc->ld_tgt_count);
73 if (desc->ld_pattern != 0) {
74 CERROR("stripe pattern %u unknown\n",
79 memcpy(&mds->mds_lov_desc, desc, sizeof *desc);
80 mds->mds_has_lov_desc = 1;
81 /* XXX the MDS should not really know about this */
82 mds->mds_max_mdsize = lov_mds_md_size(desc->ld_tgt_count);
86 push_ctxt(&saved, &mds->mds_ctxt, NULL);
87 f = filp_open("LOVDESC", O_CREAT|O_RDWR, 0644);
89 CERROR("Cannot open/create LOVDESC file\n");
90 GOTO(out, rc = PTR_ERR(f));
93 #warning FIXME: if there is an existing LOVDESC, verify new tgt_count > old
94 rc = lustre_fwrite(f, (char *)desc, sizeof(*desc), &f->f_pos);
96 CERROR("Error closing LOVDESC file\n");
97 if (rc != sizeof(*desc)) {
98 CERROR("Cannot open/create LOVDESC file\n");
99 GOTO(out, rc = PTR_ERR(f));
102 f = filp_open("LOVTGTS", O_CREAT|O_RDWR, 0644);
104 CERROR("Cannot open/create LOVTGTS file\n");
105 GOTO(out, rc = PTR_ERR(f));
108 #warning FIXME: if there is an existing LOVTGTS, verify existing UUIDs same
110 for (i = 0; i < tgt_count ; i++) {
111 rc = lustre_fwrite(f, uuidarray[i].uuid,
112 sizeof(uuidarray[i]), &f->f_pos);
113 if (rc != sizeof(uuidarray[i])) {
114 CERROR("cannot write LOV UUID %s (%d)\n",
115 uuidarray[i].uuid, i);
122 if (filp_close(f, 0))
123 CERROR("Error closing LOVTGTS file\n");
126 pop_ctxt(&saved, &mds->mds_ctxt, NULL);
130 int mds_get_lovdesc(struct mds_obd *mds, struct lov_desc *desc)
132 struct obd_run_ctxt saved;
137 push_ctxt(&saved, &mds->mds_ctxt, NULL);
138 f = filp_open("LOVDESC", O_RDONLY, 0644);
140 CERROR("Cannot open LOVDESC file\n");
141 GOTO(out, rc = PTR_ERR(f));
144 rc = lustre_fread(f, (char *)desc, sizeof(*desc), &f->f_pos);
145 if (filp_close(f, 0))
146 CERROR("Error closing LOVDESC file\n");
148 if (rc != sizeof(*desc)) {
149 CERROR("Cannot read LOVDESC file: rc = %d\n", rc);
150 GOTO(out, rc = -EIO);
155 pop_ctxt(&saved, &mds->mds_ctxt, NULL);
160 int mds_get_lovtgts(struct mds_obd *mds, int tgt_count,struct obd_uuid *uuidarray)
162 struct obd_run_ctxt saved;
167 push_ctxt(&saved, &mds->mds_ctxt, NULL);
168 f = filp_open("LOVTGTS", O_RDONLY, 0644);
170 CERROR("Cannot open LOVTGTS file\n");
171 GOTO(out, rc = PTR_ERR(f));
174 rc = lustre_fread(f, (char *)uuidarray, tgt_count * sizeof(*uuidarray),
176 rc2 = filp_close(f, 0);
178 CERROR("Error closing LOVTGTS file: rc = %d\n", rc2);
180 if (rc != tgt_count * sizeof(*uuidarray)) {
181 CERROR("Error reading LOVTGTS file: rc = %d\n", rc);
189 pop_ctxt(&saved, &mds->mds_ctxt, NULL);
194 int mds_iocontrol(unsigned int cmd, struct lustre_handle *conn,
195 int len, void *karg, void *uarg)
197 struct obd_device *obd = class_conn2obd(conn);
198 struct obd_ioctl_data *data = karg;
199 struct lov_desc *desc;
200 struct obd_uuid *uuidarray;
205 case OBD_IOC_LOV_SET_CONFIG:
206 desc = (struct lov_desc *)data->ioc_inlbuf1;
207 if (sizeof(*desc) > data->ioc_inllen1) {
208 CERROR("descriptor size wrong\n");
212 count = desc->ld_tgt_count;
213 uuidarray = (struct obd_uuid *)data->ioc_inlbuf2;
214 if (sizeof(*uuidarray) * count != data->ioc_inllen2) {
215 CERROR("UUID array size wrong\n");
218 rc = mds_set_lovdesc(obd, desc, uuidarray);
221 case OBD_IOC_LOV_GET_CONFIG:
222 desc = (struct lov_desc *)data->ioc_inlbuf1;
223 if (sizeof(*desc) > data->ioc_inllen1) {
224 CERROR("descriptor size wrong\n");
228 count = desc->ld_tgt_count;
229 uuidarray = (struct obd_uuid *)data->ioc_inlbuf2;
230 if (sizeof(*uuidarray) * count != data->ioc_inllen2) {
231 CERROR("UUID array size wrong\n");
234 rc = mds_get_lovdesc(&obd->u.mds, desc);
235 if (desc->ld_tgt_count > count) {
236 CERROR("UUID array size too small\n");
239 rc = mds_get_lovtgts(&obd->u.mds, desc->ld_tgt_count, uuidarray);
243 case OBD_IOC_SET_READONLY:
244 CERROR("setting device %s read-only\n",
245 ll_bdevname(obd->u.mds.mds_sb->s_dev));
246 dev_set_rdonly(obd->u.mds.mds_sb->s_dev, 2);