Whamcloud - gitweb
Branch: HEAD
[fs/lustre-release.git] / lustre / smfs / mds_kml.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  Lustre filesystem abstraction routines
5  *
6  *  Copyright (C) 2004 Cluster File Systems, Inc.
7  *
8  *   This file is part of Lustre, http://www.lustre.org.
9  *
10  *   Lustre is free software; you can redistribute it and/or
11  *   modify it under the terms of version 2 of the GNU General Public
12  *   License as published by the Free Software Foundation.
13  *
14  *   Lustre is distributed in the hope that it will be useful,
15  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *   GNU General Public License for more details.
18  *
19  *   You should have received a copy of the GNU General Public License
20  *   along with Lustre; if not, write to the Free Software
21  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22  */
23
24 #define DEBUG_SUBSYSTEM S_SM
25
26 #include <linux/kmod.h>
27 #include <linux/init.h>
28 #include <linux/fs.h>
29 #include <linux/slab.h>
30 #include <linux/dcache.h>
31 #include <linux/obd_class.h>
32 #include <linux/obd_support.h>
33 #include <linux/lustre_lib.h>
34 #include <linux/lustre_idl.h>
35 #include <linux/lustre_fsfilt.h>
36 #include <linux/lustre_lite.h>
37 #include <linux/lustre_mds.h>
38 #include <linux/lustre_smfs.h>
39 #include "smfs_internal.h"
40
41 static int mds_rec_link_pack(char *buffer, struct dentry *dentry,
42                              struct inode *dir, void *data1, void *data2)
43 {
44         struct dentry *src = (struct dentry *)data1;
45         struct dentry *tgt = (struct dentry *)data2;
46         struct mds_kml_pack_info *mkpi;
47         struct lustre_msg *msg = NULL;
48         struct mdc_op_data *op_data;
49         void *tmp = NULL;
50         int rc = 0;
51
52         OBD_ALLOC(op_data, sizeof(*op_data));
53         if (op_data == NULL)
54                 return -ENOMEM;
55         
56         mdc_prepare_mdc_data(op_data, src->d_inode, dir,
57                              (char *)tgt->d_name.name,
58                              tgt->d_name.len, 0);
59
60         PACK_KML_REC_INIT(buffer, MDS_REINT);
61         mkpi = (struct mds_kml_pack_info *)buffer;
62
63         mkpi->mpi_bufcount = 2;
64         mkpi->mpi_size[0] = sizeof(struct mds_rec_link);
65         mkpi->mpi_size[1] = op_data->namelen + 1;
66
67         /* the mds reint log format is: opcode + mkpi + request  */
68         msg = (struct lustre_msg *)(buffer + sizeof(*mkpi));
69         lustre_init_msg(msg, mkpi->mpi_bufcount, mkpi->mpi_size, NULL);
70
71         tmp = mdc_link_pack(msg, 0, op_data);
72         OBD_FREE(op_data, sizeof(*op_data));
73         mkpi->mpi_total_size = tmp - (void *)msg;
74         rc = mkpi->mpi_total_size + sizeof(*mkpi) + sizeof(int);
75         return rc;
76 }
77
78 static int mds_rec_setxattr_pack(char *buffer, struct dentry *dentry,
79                                 struct inode *dir, void *data1, void *data2)
80 {
81         struct mds_rec_setattr *rec = NULL;
82         struct mds_kml_pack_info *mkpi;
83         struct lustre_msg *msg = NULL;
84         char *name = (char *)data1;
85         struct kml_buffer *kbuf = (struct kml_buffer*)data2;
86         struct mdc_op_data *op_data;
87         int rc = 0;
88         void *tmp = NULL;
89         ENTRY;
90
91         OBD_ALLOC(op_data, sizeof(*op_data));
92         if (op_data == NULL)
93                 return -ENOMEM;
94         mdc_prepare_mdc_data(op_data, dir, NULL, NULL, 0, 0);
95
96         PACK_KML_REC_INIT(buffer, MDS_REINT);
97         mkpi = (struct mds_kml_pack_info*)buffer;
98
99         mkpi->mpi_bufcount = 3;
100         mkpi->mpi_size[0] = sizeof(struct mds_rec_setattr);
101         mkpi->mpi_size[1] = strlen(name);
102         mkpi->mpi_size[2] = kbuf->buf_size;       
103  
104         msg = (struct lustre_msg *)(buffer + sizeof(*mkpi));
105         lustre_init_msg(msg, mkpi->mpi_bufcount, mkpi->mpi_size, NULL);
106
107         LASSERT(kbuf && name);
108
109         tmp = mdc_setattr_pack(msg, 0, op_data, NULL, name, strlen(name), 
110                                kbuf->buf, kbuf->buf_size);
111         OBD_FREE(op_data, sizeof(*op_data));
112
113         rec = (struct mds_rec_setattr *)lustre_msg_buf(msg, 0, 0);
114         
115         rec->sa_valid = ATTR_EA_CMOBD;
116         
117         mkpi->mpi_total_size = tmp - (void *)msg;
118         rc = mkpi->mpi_total_size + sizeof(*mkpi) + sizeof(int);
119
120         RETURN(rc);
121 }
122 /* FIXME-WANGDI: did not think about EA situation. */
123 static int mds_rec_setattr_pack(char *buffer, struct dentry *dentry,
124                                 struct inode *dir, void *data1, void *data2)
125 {
126         struct iattr *iattr = (struct iattr *)data1;
127         struct mds_rec_setattr *rec = NULL;
128         struct mds_kml_pack_info *mkpi;
129         struct lustre_msg *msg = NULL;
130         struct mdc_op_data *op_data;
131         int rc = 0, ealen = 0;
132         char *ea = NULL;
133         void *tmp = NULL;
134
135         OBD_ALLOC(op_data, sizeof(*op_data));
136         if (op_data == NULL)
137                 return -ENOMEM;
138         mdc_prepare_mdc_data(op_data, dir, NULL, NULL, 0, 0);
139
140         PACK_KML_REC_INIT(buffer, MDS_REINT);
141         mkpi = (struct mds_kml_pack_info*)buffer;
142
143         mkpi->mpi_bufcount = 1;
144         mkpi->mpi_size[0] = sizeof(struct mds_rec_setattr);
145         if (data2) {
146                 mkpi->mpi_bufcount++;
147                 mkpi->mpi_size[1] = *(int *)data2;
148                 ealen = *(int *)data2;
149                 ea = data2 + sizeof(ealen);
150         }
151
152         msg = (struct lustre_msg *)(buffer + sizeof(*mkpi));
153         lustre_init_msg(msg, mkpi->mpi_bufcount, mkpi->mpi_size, NULL);
154
155         tmp = mdc_setattr_pack(msg, 0, op_data, iattr, ea, ealen, NULL, 0);
156         OBD_FREE(op_data, sizeof(*op_data));
157
158         /* FIXME-WANGDI: there are maybe some better ways to set the time
159          * attr. */
160         rec = (struct mds_rec_setattr *)lustre_msg_buf(msg, 0, 0);
161         if (rec->sa_valid & ATTR_CTIME)
162                 rec->sa_valid |= ATTR_CTIME_SET;
163         if (rec->sa_valid & ATTR_MTIME)
164                 rec->sa_valid |= ATTR_MTIME_SET;
165         if (rec->sa_valid & ATTR_ATIME)
166                 rec->sa_valid |= ATTR_ATIME_SET;
167
168         mkpi->mpi_total_size = tmp - (void *)msg;
169         rc = mkpi->mpi_total_size + sizeof(*mkpi) + sizeof(int);
170
171         return rc;
172 }
173
174 static int mds_rec_create_pack(char *buffer, struct dentry *dentry,
175                                struct inode *dir, void *data1,
176                                void *data2)
177 {
178         struct mds_kml_pack_info *mkpi;
179         struct lustre_msg *msg = NULL;
180         struct mdc_op_data *op_data;
181         struct mds_rec_create *rec;
182         struct dentry_params *param = 
183                 (struct dentry_params *) dentry->d_fsdata;
184         int rc = 0, tgt_len = 0;
185         void *tmp = NULL;
186
187         ENTRY;
188         
189         OBD_ALLOC(op_data, sizeof(*op_data));
190         if (op_data == NULL)
191                 return -ENOMEM;
192         
193         mdc_prepare_mdc_data(op_data, dir, dentry->d_inode,
194                              (char *)dentry->d_name.name,
195                              dentry->d_name.len, 0);
196
197         id_fid(&op_data->id1) = param->p_fid;
198         id_group(&op_data->id1) = param->p_group;
199         PACK_KML_REC_INIT(buffer, MDS_REINT);
200         mkpi = (struct mds_kml_pack_info *)buffer;
201
202         mkpi->mpi_bufcount = 2;
203         mkpi->mpi_size[0] = sizeof(struct mds_rec_create);
204         mkpi->mpi_size[1] = op_data->namelen + 1;
205
206         if (data1 && data2) {
207                 mkpi->mpi_size[2] = *(int *)data2;
208                 mkpi->mpi_bufcount++;
209         }
210
211         if (data1) {
212                 /* for symlink, data1 will be the tgt name. */
213                 tgt_len = *(int *)data2;
214         }
215         msg = (struct lustre_msg *)(buffer + sizeof(*mkpi));
216         lustre_init_msg(msg, mkpi->mpi_bufcount, mkpi->mpi_size, NULL);
217
218         tmp = mdc_create_pack(msg, 0, op_data, dentry->d_inode->i_mode,
219                               dentry->d_inode->i_mode, data1, tgt_len);
220
221         rec = (struct mds_rec_create *)lustre_msg_buf(msg, 0, 0);
222         rec->cr_replayid = op_data->id2;
223         rec->cr_flags |= REC_REINT_CREATE; 
224         mkpi->mpi_total_size = tmp - (void *)msg;
225         rc = mkpi->mpi_total_size + sizeof(*mkpi) + sizeof(int);
226         OBD_FREE(op_data, sizeof(*op_data));
227         
228         return rc;
229 }
230
231 static int mds_rec_unlink_pack(char *buffer, struct dentry *dentry,
232                                struct inode *dir, void *data1,
233                                void *data2)
234 {
235         struct lustre_msg *msg = NULL;
236         struct mds_kml_pack_info *mkpi;
237         struct mdc_op_data *op_data;
238         int mode = *(int*)data1;
239         void *tmp = NULL;
240         int rc = 0;
241
242         OBD_ALLOC(op_data, sizeof(*op_data));
243         if (op_data == NULL)
244                 return -ENOMEM;
245         
246         mdc_prepare_mdc_data(op_data, dir, NULL,
247                              (char *)dentry->d_name.name,
248                              dentry->d_name.len, mode);
249
250         PACK_KML_REC_INIT(buffer, MDS_REINT);
251         mkpi = (struct mds_kml_pack_info*)buffer;
252
253         mkpi->mpi_bufcount = 2;
254         mkpi->mpi_size[0] = sizeof(struct mds_rec_unlink);
255         mkpi->mpi_size[1] = op_data->namelen + 1;
256
257         msg = (struct lustre_msg *)(buffer + sizeof(*mkpi));
258         lustre_init_msg(msg, mkpi->mpi_bufcount, mkpi->mpi_size, NULL);
259
260         tmp = mdc_unlink_pack(msg, 0, op_data);
261
262         mkpi->mpi_total_size = tmp - (void*)msg;
263         rc = mkpi->mpi_total_size + sizeof(*mkpi) + sizeof(int);
264         OBD_FREE(op_data, sizeof(*op_data));
265
266         return rc;
267 }
268
269 static int mds_rec_rename_pack(char *buffer, struct dentry *dentry,
270                                struct inode *dir, void *data1, void *data2)
271 {
272         struct dentry *new_dentry = (struct dentry *)data2;
273         struct inode *new_dir = (struct inode *)data1;
274         struct mds_kml_pack_info *mkpi;
275         struct lustre_msg *msg = NULL;
276         struct mdc_op_data *op_data;
277         struct mds_rec_rename *rec;
278         void *tmp = NULL;
279         int rc = 0;
280
281         OBD_ALLOC(op_data, sizeof(*op_data));
282         if (op_data == NULL)
283                 return -ENOMEM;
284         mdc_prepare_mdc_data(op_data, dir, new_dir, NULL, 0, 0);
285
286         PACK_KML_REC_INIT(buffer, MDS_REINT);
287         mkpi = (struct mds_kml_pack_info*)buffer;
288
289         mkpi->mpi_bufcount = 3;
290         mkpi->mpi_size[0] = sizeof(struct mds_rec_rename);
291         mkpi->mpi_size[1] = dentry->d_name.len + 1;
292         mkpi->mpi_size[2] = new_dentry->d_name.len + 1;
293
294         rec = (struct mds_rec_rename *)(buffer + sizeof(*mkpi));
295
296
297         msg = (struct lustre_msg *)(buffer + sizeof(*mkpi));
298         lustre_init_msg(msg, mkpi->mpi_bufcount, mkpi->mpi_size, NULL);
299
300         tmp = mdc_rename_pack(msg, 0, op_data, (char *)dentry->d_name.name,
301                               dentry->d_name.len, (char *)new_dentry->d_name.name,
302                               new_dentry->d_name.len);
303
304         mkpi->mpi_total_size = tmp - (void*)msg;
305         rc = mkpi->mpi_total_size + sizeof(*mkpi) + sizeof(int);
306         OBD_FREE(op_data, sizeof(*op_data));
307         return rc;
308 }
309
310 typedef int (*mds_pack_rec_func)(char *, struct dentry*, struct inode *, void *, void*);
311
312 static mds_pack_rec_func mds_kml_pack[REINT_MAX + 1] = {
313         [REINT_LINK]    mds_rec_link_pack,
314         [REINT_SETATTR] mds_rec_setattr_pack,
315         [REINT_CREATE]  mds_rec_create_pack,
316         [REINT_UNLINK]  mds_rec_unlink_pack,
317         [REINT_RENAME]  mds_rec_rename_pack,
318         [REINT_SETXATTR] mds_rec_setxattr_pack,
319 };
320
321 int mds_rec_pack(int op, char *buffer, struct dentry *dentry, 
322                  struct inode *dir, void * arg, void * arg2)
323 {
324         return mds_kml_pack[op](buffer, dentry, dir, arg, arg2);
325 }
326
327
328