Whamcloud - gitweb
945cc3911c2f81b123820cf0775db283ee7e84d7
[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
47         tgt_count = desc->ld_tgt_count;
48         lov_packdesc(desc);
49
50         push_ctxt(&saved, &mds->mds_ctxt, NULL);
51         f = filp_open("LOVDESC", O_CREAT|O_RDWR, 0644);
52         if (IS_ERR(f)) {
53                 CERROR("Cannot open/create LOVDESC file\n");
54                 GOTO(out, rc = PTR_ERR(f));
55         }
56
57         rc = lustre_fwrite(f, (char *)desc, sizeof(*desc), &f->f_pos);
58         if (filp_close(f, 0))
59                 CERROR("Error closing LOVDESC file\n");
60         if (rc != sizeof(*desc)) {
61                 CERROR("Cannot open/create LOVDESC file\n");
62                 GOTO(out, rc = PTR_ERR(f));
63         }
64
65         f = filp_open("LOVTGTS", O_CREAT|O_RDWR, 0644);
66         if (IS_ERR(f)) {
67                 CERROR("Cannot open/create LOVTGTS file\n");
68                 GOTO(out, rc = PTR_ERR(f));
69         }
70
71         rc = 0;
72         for (i = 0; i < tgt_count ; i++) {
73                 rc = lustre_fwrite(f, uuidarray[i],
74                                    sizeof(uuidarray[i]), &f->f_pos);
75                 if (rc != sizeof(uuidarray[i])) {
76                         CERROR("cannot write LOV UUID %s (%d)\n",
77                                uuidarray[i], i);
78                         if (rc >= 0)
79                                 rc = -EIO;
80                         break;
81                 } else
82                         rc = 0;
83         }
84         if (filp_close(f, 0))
85                 CERROR("Error closing LOVTGTS file\n");
86
87 out:
88         pop_ctxt(&saved);
89         RETURN(rc);
90 }
91
92 int mds_get_lovdesc(struct mds_obd *mds, struct lov_desc *desc)
93 {
94         struct obd_run_ctxt saved;
95         struct file *f;
96         int rc;
97
98         push_ctxt(&saved, &mds->mds_ctxt, NULL);
99         f = filp_open("LOVDESC", O_RDONLY, 0644);
100         if (!f || IS_ERR(f)) {
101                 CERROR("Cannot open LOVDESC file\n");
102                 pop_ctxt(&saved);
103                 RETURN(-EIO);
104         }
105
106         rc = lustre_fread(f, (char *)desc, sizeof(*desc), &f->f_pos);
107         if (filp_close(f, 0))
108                 CERROR("Error closing LOVDESC file\n");
109
110         if (rc != sizeof(*desc)) {
111                 CERROR("Cannot read LOVDESC file\n");
112                 pop_ctxt(&saved);
113                 RETURN(-EIO);
114         }
115         pop_ctxt(&saved);
116
117         RETURN(0);
118 }
119
120 int mds_get_lovtgts(struct mds_obd *mds, int tgt_count,obd_uuid_t *uuidarray)
121 {
122         struct obd_run_ctxt saved;
123         struct file *f;
124         int rc;
125         int rc2;
126
127         push_ctxt(&saved, &mds->mds_ctxt, NULL);
128         f = filp_open("LOVTGTS", O_RDONLY, 0644);
129         if (IS_ERR(f)) {
130                 CERROR("Cannot open LOVTGTS file\n");
131                 GOTO(out, rc = PTR_ERR(f));
132         }
133
134         rc = lustre_fread(f, (char *)uuidarray, tgt_count * sizeof(*uuidarray),
135                           &f->f_pos);
136         rc2 = filp_close(f, 0);
137         if (rc2)
138                 CERROR("Error closing LOVTGTS file: rc = %d\n", rc2);
139
140         if (rc != tgt_count * sizeof(*uuidarray)) {
141                 CERROR("Error reading LOVTGTS file: rc = %d\n", rc);
142                 if (rc >= 0)
143                         rc = -EIO;
144                 GOTO(out, rc);
145         } else 
146                 rc = 0;
147         EXIT;
148 out:
149         pop_ctxt(&saved);
150
151         RETURN(rc);
152 }
153
154 int mds_iocontrol(long cmd, struct lustre_handle *conn,
155                           int len, void *karg, void *uarg)
156 {
157         struct obd_device *obd = class_conn2obd(conn);
158         struct obd_ioctl_data *data = karg;
159         struct lov_desc *desc;
160         obd_uuid_t *uuidarray;
161         int count;
162         int rc;
163
164
165         switch (cmd) {
166         case OBD_IOC_LOV_SET_CONFIG:
167                 desc = (struct lov_desc *)data->ioc_inlbuf1;
168                 if (sizeof(*desc) > data->ioc_inllen1) {
169                         CERROR("descriptor size wrong\n");
170                         RETURN(-EINVAL);
171                 }
172
173                 count = desc->ld_tgt_count;
174                 uuidarray = (obd_uuid_t *)data->ioc_inlbuf2;
175                 if (sizeof(*uuidarray) * count != data->ioc_inllen2) {
176                         CERROR("UUID array size wrong\n");
177                         RETURN(-EINVAL);
178                 }
179                 rc = mds_set_lovdesc(obd, desc, uuidarray);
180
181                 RETURN(rc);
182         case OBD_IOC_LOV_GET_CONFIG:
183                 desc = (struct lov_desc *)data->ioc_inlbuf1;
184                 if (sizeof(*desc) > data->ioc_inllen1) {
185                         CERROR("descriptor size wrong\n");
186                         RETURN(-EINVAL);
187                 }
188
189                 count = desc->ld_tgt_count;
190                 uuidarray = (obd_uuid_t *)data->ioc_inlbuf2;
191                 if (sizeof(*uuidarray) * count != data->ioc_inllen2) {
192                         CERROR("UUID array size wrong\n");
193                         RETURN(-EINVAL);
194                 }
195                 rc = mds_get_lovdesc(&obd->u.mds, desc);
196                 if (desc->ld_tgt_count > count) {
197                         CERROR("UUID array size too small\n");
198                         RETURN(-ENOSPC);
199                 }
200                 rc = mds_get_lovtgts(&obd->u.mds, desc->ld_tgt_count, uuidarray);
201
202                 RETURN(rc);
203         default:
204                 RETURN(-EINVAL);
205         }
206
207         RETURN(0);
208 }