Whamcloud - gitweb
land b_md onto HEAD:
[fs/lustre-release.git] / lustre / mds / mds_lov.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  linux/mds/mds_lov.c
5  *
6  *  Lustre Metadata Server (mds) handling of striped file data
7  *
8  *  Copyright (C) 2001, 2002 Cluster File Systems, Inc.
9  *
10  *  This code is issued under the GNU General Public License.
11  *  See the file COPYING in this distribution
12  *
13  *  by Peter Braam <braam@clusterfs.com> &
14  *
15  */
16
17 #define EXPORT_SYMTAB
18 #define DEBUG_SUBSYSTEM S_MDS
19
20 #include <linux/module.h>
21 #include <linux/lustre_mds.h>
22 #include <linux/lustre_idl.h>
23 #include <linux/obd_class.h>
24 #include <linux/obd_lov.h>
25 #include <linux/lustre_lib.h>
26
27 /* lov_unpackdesc() is in lov/lov_pack.c */
28
29 void lov_packdesc(struct lov_desc *ld)
30 {
31         ld->ld_tgt_count = HTON__u32(ld->ld_tgt_count);
32         ld->ld_default_stripe_count = HTON__u32(ld->ld_default_stripe_count);
33         ld->ld_default_stripe_size = HTON__u32(ld->ld_default_stripe_size);
34         ld->ld_pattern = HTON__u32(ld->ld_pattern);
35 }
36
37 int mds_set_lovdesc(struct obd_device *obd, struct lov_desc *desc,
38                     obd_uuid_t *uuidarray)
39 {
40         struct mds_obd *mds = &obd->u.mds;
41         struct obd_run_ctxt saved;
42         struct file *f;
43         int tgt_count;
44         int rc;
45         int i;
46         ENTRY;
47
48         tgt_count = desc->ld_tgt_count;
49         lov_packdesc(desc);
50
51         push_ctxt(&saved, &mds->mds_ctxt, NULL);
52         f = filp_open("LOVDESC", O_CREAT|O_RDWR, 0644);
53         if (IS_ERR(f)) {
54                 CERROR("Cannot open/create LOVDESC file\n");
55                 GOTO(out, rc = PTR_ERR(f));
56         }
57
58         rc = lustre_fwrite(f, (char *)desc, sizeof(*desc), &f->f_pos);
59         if (filp_close(f, 0))
60                 CERROR("Error closing LOVDESC file\n");
61         if (rc != sizeof(*desc)) {
62                 CERROR("Cannot open/create LOVDESC file\n");
63                 GOTO(out, rc = PTR_ERR(f));
64         }
65
66         f = filp_open("LOVTGTS", O_CREAT|O_RDWR, 0644);
67         if (IS_ERR(f)) {
68                 CERROR("Cannot open/create LOVTGTS file\n");
69                 GOTO(out, rc = PTR_ERR(f));
70         }
71
72         rc = 0;
73         for (i = 0; i < tgt_count ; i++) {
74                 rc = lustre_fwrite(f, uuidarray[i],
75                                    sizeof(uuidarray[i]), &f->f_pos);
76                 if (rc != sizeof(uuidarray[i])) {
77                         CERROR("cannot write LOV UUID %s (%d)\n",
78                                uuidarray[i], i);
79                         if (rc >= 0)
80                                 rc = -EIO;
81                         break;
82                 } else
83                         rc = 0;
84         }
85         if (filp_close(f, 0))
86                 CERROR("Error closing LOVTGTS file\n");
87
88 out:
89         pop_ctxt(&saved, &mds->mds_ctxt, NULL);
90         RETURN(rc);
91 }
92
93 int mds_get_lovdesc(struct mds_obd *mds, struct lov_desc *desc)
94 {
95         struct obd_run_ctxt saved;
96         struct file *f;
97         int rc;
98         ENTRY;
99
100         push_ctxt(&saved, &mds->mds_ctxt, NULL);
101         f = filp_open("LOVDESC", O_RDONLY, 0644);
102         if (IS_ERR(f)) {
103                 CERROR("Cannot open LOVDESC file\n");
104                 GOTO(out, rc = PTR_ERR(f));
105         }
106
107         rc = lustre_fread(f, (char *)desc, sizeof(*desc), &f->f_pos);
108         if (filp_close(f, 0))
109                 CERROR("Error closing LOVDESC file\n");
110
111         if (rc != sizeof(*desc)) {
112                 CERROR("Cannot read LOVDESC file: rc = %d\n", rc);
113                 GOTO(out, rc = -EIO);
114         } else
115                 rc = 0;
116         EXIT;
117 out:
118         pop_ctxt(&saved, &mds->mds_ctxt, NULL);
119
120         return rc;
121 }
122
123 int mds_get_lovtgts(struct mds_obd *mds, int tgt_count,obd_uuid_t *uuidarray)
124 {
125         struct obd_run_ctxt saved;
126         struct file *f;
127         int rc;
128         int rc2;
129
130         push_ctxt(&saved, &mds->mds_ctxt, NULL);
131         f = filp_open("LOVTGTS", O_RDONLY, 0644);
132         if (IS_ERR(f)) {
133                 CERROR("Cannot open LOVTGTS file\n");
134                 GOTO(out, rc = PTR_ERR(f));
135         }
136
137         rc = lustre_fread(f, (char *)uuidarray, tgt_count * sizeof(*uuidarray),
138                           &f->f_pos);
139         rc2 = filp_close(f, 0);
140         if (rc2)
141                 CERROR("Error closing LOVTGTS file: rc = %d\n", rc2);
142
143         if (rc != tgt_count * sizeof(*uuidarray)) {
144                 CERROR("Error reading LOVTGTS file: rc = %d\n", rc);
145                 if (rc >= 0)
146                         rc = -EIO;
147                 GOTO(out, rc);
148         } else
149                 rc = 0;
150         EXIT;
151 out:
152         pop_ctxt(&saved, &mds->mds_ctxt, NULL);
153
154         RETURN(rc);
155 }
156
157 int mds_iocontrol(unsigned int cmd, struct lustre_handle *conn,
158                           int len, void *karg, void *uarg)
159 {
160         struct obd_device *obd = class_conn2obd(conn);
161         struct obd_ioctl_data *data = karg;
162         struct lov_desc *desc;
163         obd_uuid_t *uuidarray;
164         int count;
165         int rc;
166
167
168         switch (cmd) {
169         case OBD_IOC_LOV_SET_CONFIG:
170                 desc = (struct lov_desc *)data->ioc_inlbuf1;
171                 if (sizeof(*desc) > data->ioc_inllen1) {
172                         CERROR("descriptor size wrong\n");
173                         RETURN(-EINVAL);
174                 }
175
176                 count = desc->ld_tgt_count;
177                 uuidarray = (obd_uuid_t *)data->ioc_inlbuf2;
178                 if (sizeof(*uuidarray) * count != data->ioc_inllen2) {
179                         CERROR("UUID array size wrong\n");
180                         RETURN(-EINVAL);
181                 }
182                 rc = mds_set_lovdesc(obd, desc, uuidarray);
183
184                 RETURN(rc);
185         case OBD_IOC_LOV_GET_CONFIG:
186                 desc = (struct lov_desc *)data->ioc_inlbuf1;
187                 if (sizeof(*desc) > data->ioc_inllen1) {
188                         CERROR("descriptor size wrong\n");
189                         RETURN(-EINVAL);
190                 }
191
192                 count = desc->ld_tgt_count;
193                 uuidarray = (obd_uuid_t *)data->ioc_inlbuf2;
194                 if (sizeof(*uuidarray) * count != data->ioc_inllen2) {
195                         CERROR("UUID array size wrong\n");
196                         RETURN(-EINVAL);
197                 }
198                 rc = mds_get_lovdesc(&obd->u.mds, desc);
199                 if (desc->ld_tgt_count > count) {
200                         CERROR("UUID array size too small\n");
201                         RETURN(-ENOSPC);
202                 }
203                 rc = mds_get_lovtgts(&obd->u.mds, desc->ld_tgt_count, uuidarray);
204
205                 RETURN(rc);
206         default:
207                 RETURN(-EINVAL);
208         }
209
210         RETURN(0);
211 }