Whamcloud - gitweb
b3a16df3c924d767d99959b8342e5f4d44c0f24c
[fs/lustre-release.git] / lustre / smfs / ost_kml.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  lustre/smfs/super.c
5  *  Lustre filesystem abstraction routines
6  *
7  *  Copyright (C) 2004 Cluster File Systems, Inc.
8  *
9  *   This file is part of Lustre, http://www.lustre.org.
10  *
11  *   Lustre is free software; you can redistribute it and/or
12  *   modify it under the terms of version 2 of the GNU General Public
13  *   License as published by the Free Software Foundation.
14  *
15  *   Lustre is distributed in the hope that it will be useful,
16  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *   GNU General Public License for more details.
19  *
20  *   You should have received a copy of the GNU General Public License
21  *   along with Lustre; if not, write to the Free Software
22  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  */
24
25 #ifndef EXPORT_SYMTAB
26 # define EXPORT_SYMTAB
27 #endif
28
29 #define DEBUG_SUBSYSTEM S_SM
30
31 #include <linux/kmod.h>
32 #include <linux/init.h>
33 #include <linux/fs.h>
34 #include <linux/slab.h>
35 #include <linux/obd_class.h>
36 #include <linux/obd_support.h>
37 #include <linux/lustre_lib.h>
38 #include <linux/lustre_idl.h>
39 #include <linux/lustre_fsfilt.h>
40 #include <linux/lustre_smfs.h>
41 #include "smfs_internal.h"
42
43 static int smfs_ost_get_id(obd_id *id, char *data, int size)
44 {
45         /*for obdfilter obdid is the name of the filename*/
46         char end;
47         char *endp = &end;
48         if (data)
49                 *id = simple_strtoull(data, &endp, 10);
50         else
51                 return -EINVAL;
52         CDEBUG(D_DENTRY,"name = %s\n", data);
53         return 0;
54 }
55
56 /* Group 0 is no longer a legal group, to catch uninitialized IDs */
57 #define FILTER_MIN_GROUPS 3
58 static int smfs_ost_get_group(struct dentry *dentry, struct obdo *oa)
59 {
60         struct smfs_super_info *sinfo = S2SMI(dentry->d_inode->i_sb);
61         struct obd_device *obd = class_exp2obd(sinfo->smsi_exp);
62         struct filter_obd *filter = &obd->u.filter;
63         struct dentry *dparent_subdir = dentry->d_parent;
64         struct dentry *dparent_group = dparent_subdir->d_parent;
65         int i = 0;
66
67         if (dparent_group == NULL || dparent_group == dparent_subdir)
68                 return -EINVAL;
69
70         CDEBUG(D_DENTRY,"try to find group for dentry %p\n", dparent_group);
71         for (i = 1; i < filter->fo_group_count; i++) {
72                 CDEBUG(D_DENTRY, "group[%i] = %p\n", i, filter->fo_groups[i]);
73                 if (filter->fo_groups[i] == dparent_group) {
74                         oa->o_gr = i;
75                         oa->o_valid |= OBD_MD_FLGROUP;
76                         return 0;
77                 }
78         }
79         return -ENOENT;
80 }
81
82 static int ost_rec_create_pack(char *buffer, struct dentry *dentry,
83                                struct inode *dir, void *data1, void *data2)
84 {
85         struct obdo *oa = NULL;
86         int    rc = 0;
87        
88         PACK_KML_REC_INIT(buffer, OST_CREATE);
89         oa = (struct obdo*)buffer;
90         if (data1 && data2) {
91                 struct obdo *create_oa = (struct obdo *)data2;  
92                 int    num = *((int *)data1);
93                 
94                 memcpy(oa, create_oa, sizeof(*oa));
95                 memcpy(oa->o_inline, &num, sizeof(int));
96                 oa->o_valid |= OBD_MD_REINT; 
97         } else { 
98                 oa->o_uid = 0; /* must have 0 uid / gid on OST */
99                 oa->o_gid = 0;
100                 oa->o_valid = OBD_MD_FLID | OBD_MD_FLGENER | OBD_MD_FLTYPE |
101                         OBD_MD_FLMODE | OBD_MD_FLUID | OBD_MD_FLGID;
102                 oa->o_size = 0;
103                 obdo_from_inode(oa, dentry->d_inode, OBD_MD_FLTYPE|OBD_MD_FLATIME|
104                                 OBD_MD_FLMTIME| OBD_MD_FLCTIME);
105                 rc = smfs_ost_get_id(&oa->o_id, (char*)dentry->d_name.name,
106                                      dentry->d_name.len);
107                 if (rc) {
108                         CERROR("Can not find id of node %lu\n", dentry->d_inode->i_ino);
109                         GOTO(out, rc = -ENOMEM);
110                 }
111                 rc = smfs_ost_get_group(dentry, oa);
112                 if (rc) {
113                         CERROR("Can not find group node %lu\n", dentry->d_inode->i_ino);
114                         GOTO(out, rc = -ENOMEM); 
115                 }
116         } 
117         rc = sizeof(*oa) + sizeof(int);
118 out:
119         RETURN(rc);
120 }
121
122 static int ost_rec_setattr_pack(char *buffer, struct dentry *dentry,
123                                 struct inode *dir, void *data1, void *data2)
124 {
125         struct obdo *oa = NULL;
126         struct iattr *attr = (struct iattr*)data1;
127         int rc = 0;
128
129         PACK_KML_REC_INIT(buffer, OST_SETATTR);
130         oa = (struct obdo*)buffer;
131
132         obdo_from_iattr(oa, attr, attr->ia_valid);
133
134         rc = smfs_ost_get_id(&oa->o_id, (char *)dentry->d_name.name,
135                              dentry->d_name.len);
136         if (rc)
137                 GOTO(out, rc = -ENOMEM);
138         rc = smfs_ost_get_group(dentry, oa);
139         if (rc) {
140                 CERROR("Can not find group node %lu\n", dentry->d_inode->i_ino);
141                 GOTO(out, rc = -ENOMEM); 
142         } 
143
144         rc = sizeof(*oa) + sizeof(int);
145 out:
146         RETURN(rc);
147 }
148
149 static int ost_rec_write_pack(char *buffer, struct dentry *dentry,
150                               struct inode *dir, void *data1, void *data2)
151 {
152         struct obdo *oa = NULL;
153         int          rc = 0;
154
155         PACK_KML_REC_INIT(buffer, OST_WRITE);
156         oa = (struct obdo*)buffer;
157
158         rc = smfs_ost_get_id(&oa->o_id, (char*)dentry->d_name.name,
159                              dentry->d_name.len);
160         if (rc)
161                 GOTO(out, rc = -ENOMEM);
162         memcpy(oa->o_inline, &dentry->d_inode->i_ino, sizeof(unsigned long));
163         
164         rc = smfs_ost_get_group(dentry, oa);
165         if (rc) {
166                 CERROR("Can not find group node %lu\n", dentry->d_inode->i_ino);
167                 GOTO(out, rc = -ENOMEM); 
168         } 
169         rc = sizeof(*oa) + sizeof(int);
170 out:
171         RETURN(rc);
172 }
173
174 typedef int (*ost_pack_rec_func)(char *buffer, struct dentry *dentry,
175                                  struct inode *dir, void *data1, void *data2);
176 static ost_pack_rec_func ost_kml_pack[REINT_MAX + 1] = {
177         [REINT_SETATTR] ost_rec_setattr_pack,
178         [REINT_CREATE]  ost_rec_create_pack,
179         [REINT_WRITE]   ost_rec_write_pack,
180 };
181
182 int ost_rec_pack(char *buffer, struct dentry *dentry, struct inode *dir,
183                  void *data1, void *data2, int op)
184 {
185         if (op == REINT_SETATTR || op == REINT_CREATE || op == REINT_WRITE) {
186                 return ost_kml_pack[op](buffer, dentry, dir, data1, data2);
187         }
188         return 0;
189 }
190 #if 0
191 int ost_rec_pack_init(struct smfs_super_info *smsi)
192 {
193
194         smsi->smsi_pack_rec[PACK_OST] = ost_rec_pack;
195         return 0;
196 }
197 #endif