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