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, NULL, 0);
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, 
156                                NULL, 0, NULL, 0);
157         OBD_FREE(op_data, sizeof(*op_data));
158
159         /* FIXME-WANGDI: there are maybe some better ways to set the time
160          * attr. */
161         rec = (struct mds_rec_setattr *)lustre_msg_buf(msg, 0, 0);
162         if (rec->sa_valid & ATTR_CTIME)
163                 rec->sa_valid |= ATTR_CTIME_SET;
164         if (rec->sa_valid & ATTR_MTIME)
165                 rec->sa_valid |= ATTR_MTIME_SET;
166         if (rec->sa_valid & ATTR_ATIME)
167                 rec->sa_valid |= ATTR_ATIME_SET;
168
169         mkpi->mpi_total_size = tmp - (void *)msg;
170         rc = mkpi->mpi_total_size + sizeof(*mkpi) + sizeof(int);
171
172         return rc;
173 }
174
175 static int mds_rec_create_pack(char *buffer, struct dentry *dentry,
176                                struct inode *dir, void *data1,
177                                void *data2)
178 {
179         struct mds_kml_pack_info *mkpi;
180         struct lustre_msg *msg = NULL;
181         struct mdc_op_data *op_data;
182         struct mds_rec_create *rec;
183         struct dentry_params *param = 
184                 (struct dentry_params *) dentry->d_fsdata;
185         int rc = 0, tgt_len = 0;
186         void *tmp = NULL;
187
188         ENTRY;
189         
190         OBD_ALLOC(op_data, sizeof(*op_data));
191         if (op_data == NULL)
192                 return -ENOMEM;
193         
194         mdc_prepare_mdc_data(op_data, dir, dentry->d_inode,
195                              (char *)dentry->d_name.name,
196                              dentry->d_name.len, 0);
197
198         id_fid(&op_data->id1) = param->p_fid;
199         id_group(&op_data->id1) = param->p_group;
200         PACK_KML_REC_INIT(buffer, MDS_REINT);
201         mkpi = (struct mds_kml_pack_info *)buffer;
202
203         mkpi->mpi_bufcount = 2;
204         mkpi->mpi_size[0] = sizeof(struct mds_rec_create);
205         mkpi->mpi_size[1] = op_data->namelen + 1;
206
207         if (data1 && data2) {
208                 mkpi->mpi_size[2] = *(int *)data2;
209                 mkpi->mpi_bufcount++;
210         }
211
212         if (data1) {
213                 /* for symlink, data1 will be the tgt name. */
214                 tgt_len = *(int *)data2;
215         }
216         msg = (struct lustre_msg *)(buffer + sizeof(*mkpi));
217         lustre_init_msg(msg, mkpi->mpi_bufcount, mkpi->mpi_size, NULL);
218
219         tmp = mdc_create_pack(msg, 0, op_data, dentry->d_inode->i_mode,
220                               dentry->d_inode->i_mode, data1, tgt_len);
221
222         rec = (struct mds_rec_create *)lustre_msg_buf(msg, 0, 0);
223         rec->cr_replayid = op_data->id2;
224         rec->cr_flags |= REC_REINT_CREATE; 
225         mkpi->mpi_total_size = tmp - (void *)msg;
226         rc = mkpi->mpi_total_size + sizeof(*mkpi) + sizeof(int);
227         OBD_FREE(op_data, sizeof(*op_data));
228         
229         return rc;
230 }
231
232 static int mds_rec_unlink_pack(char *buffer, struct dentry *dentry,
233                                struct inode *dir, void *data1,
234                                void *data2)
235 {
236         struct lustre_msg *msg = NULL;
237         struct mds_kml_pack_info *mkpi;
238         struct mdc_op_data *op_data;
239         int mode = *(int*)data1;
240         void *tmp = NULL;
241         int rc = 0;
242
243         OBD_ALLOC(op_data, sizeof(*op_data));
244         if (op_data == NULL)
245                 return -ENOMEM;
246         
247         mdc_prepare_mdc_data(op_data, dir, NULL,
248                              (char *)dentry->d_name.name,
249                              dentry->d_name.len, mode);
250
251         PACK_KML_REC_INIT(buffer, MDS_REINT);
252         mkpi = (struct mds_kml_pack_info*)buffer;
253
254         mkpi->mpi_bufcount = 2;
255         mkpi->mpi_size[0] = sizeof(struct mds_rec_unlink);
256         mkpi->mpi_size[1] = op_data->namelen + 1;
257
258         msg = (struct lustre_msg *)(buffer + sizeof(*mkpi));
259         lustre_init_msg(msg, mkpi->mpi_bufcount, mkpi->mpi_size, NULL);
260
261         tmp = mdc_unlink_pack(msg, 0, op_data);
262
263         mkpi->mpi_total_size = tmp - (void*)msg;
264         rc = mkpi->mpi_total_size + sizeof(*mkpi) + sizeof(int);
265         OBD_FREE(op_data, sizeof(*op_data));
266
267         return rc;
268 }
269
270 static int mds_rec_rename_pack(char *buffer, struct dentry *dentry,
271                                struct inode *dir, void *data1, void *data2)
272 {
273         struct dentry *new_dentry = (struct dentry *)data2;
274         struct inode *new_dir = (struct inode *)data1;
275         struct mds_kml_pack_info *mkpi;
276         struct lustre_msg *msg = NULL;
277         struct mdc_op_data *op_data;
278         struct mds_rec_rename *rec;
279         void *tmp = NULL;
280         int rc = 0;
281
282         OBD_ALLOC(op_data, sizeof(*op_data));
283         if (op_data == NULL)
284                 return -ENOMEM;
285         mdc_prepare_mdc_data(op_data, dir, new_dir, NULL, 0, 0);
286
287         PACK_KML_REC_INIT(buffer, MDS_REINT);
288         mkpi = (struct mds_kml_pack_info*)buffer;
289
290         mkpi->mpi_bufcount = 3;
291         mkpi->mpi_size[0] = sizeof(struct mds_rec_rename);
292         mkpi->mpi_size[1] = dentry->d_name.len + 1;
293         mkpi->mpi_size[2] = new_dentry->d_name.len + 1;
294
295         rec = (struct mds_rec_rename *)(buffer + sizeof(*mkpi));
296
297
298         msg = (struct lustre_msg *)(buffer + sizeof(*mkpi));
299         lustre_init_msg(msg, mkpi->mpi_bufcount, mkpi->mpi_size, NULL);
300
301         tmp = mdc_rename_pack(msg, 0, op_data, (char *)dentry->d_name.name,
302                               dentry->d_name.len, (char *)new_dentry->d_name.name,
303                               new_dentry->d_name.len);
304
305         mkpi->mpi_total_size = tmp - (void*)msg;
306         rc = mkpi->mpi_total_size + sizeof(*mkpi) + sizeof(int);
307         OBD_FREE(op_data, sizeof(*op_data));
308         return rc;
309 }
310
311 typedef int (*mds_pack_rec_func)(char *, struct dentry*, struct inode *, void *, void*);
312
313 static mds_pack_rec_func mds_kml_pack[REINT_MAX + 1] = {
314         [REINT_LINK]    mds_rec_link_pack,
315         [REINT_SETATTR] mds_rec_setattr_pack,
316         [REINT_CREATE]  mds_rec_create_pack,
317         [REINT_UNLINK]  mds_rec_unlink_pack,
318         [REINT_RENAME]  mds_rec_rename_pack,
319         [REINT_SETXATTR] mds_rec_setxattr_pack,
320 };
321
322 int mds_rec_pack(int op, char *buffer, struct dentry *dentry, 
323                  struct inode *dir, void * arg, void * arg2)
324 {
325         return mds_kml_pack[op](buffer, dentry, dir, arg, arg2);
326 }
327
328
329