Whamcloud - gitweb
smash the HEAD with the contents of b_cmd. HEAD_PRE_CMD_SMASH and
[fs/lustre-release.git] / lustre / smfs / journal.c
1 /*
2  *  smfs/inode.c
3  *
4  */
5
6 #define DEBUG_SUBSYSTEM S_SM
7
8 #include <linux/kmod.h>
9 #include <linux/init.h>
10 #include <linux/fs.h>
11 #include <linux/slab.h>
12 #include <linux/string.h>
13 #include <asm/segment.h>
14 #include <asm/uaccess.h>
15 #include <linux/lustre_idl.h>
16 #include "kml_idl.h" 
17 #include "smfs_internal.h" 
18 extern struct sm_ops smfs_operations;
19
20 #define size_round(x)  (((x)+3) & ~0x3)
21
22 void *smfs_trans_start(struct inode *inode, int op)
23 {
24
25         CDEBUG(D_INODE, "trans start %p\n", 
26                smfs_operations.sm_journal_ops.tr_start);
27         if (smfs_operations.sm_journal_ops.tr_start) {
28                 return smfs_operations.sm_journal_ops.tr_start(inode, op);      
29         }
30         return NULL;
31 }
32
33 void smfs_trans_commit(void *handle)
34 {
35         if (smfs_operations.sm_journal_ops.tr_commit) {
36                 smfs_operations.sm_journal_ops.tr_commit(handle);       
37         }
38         CDEBUG(D_SM, "trans commit %p\n", 
39                smfs_operations.sm_journal_ops.tr_commit);
40 }
41 /*The following function are gotten from intermezzo
42  * smfs_path
43  * logit
44  * journal_log_prefix_with_groups_and_ids 
45  * journal_log_prefix 
46 */
47 static char* smfs_path(struct dentry *dentry, struct dentry *root,
48                         char *buffer, int buflen)
49 {
50         char * end = buffer+buflen;
51         char * retval;
52                                                                                                                                                                                                      
53         *--end = '\0';
54         buflen--;
55         if (dentry->d_parent != dentry && list_empty(&dentry->d_hash)) {
56                 buflen -= 10;
57                 end -= 10;
58                 memcpy(end, " (deleted)", 10);
59         }
60                                                                                                                                                                                                      
61         /* Get '/' right */
62         retval = end-1;
63         *retval = '/';
64                                                                                                                                                                                                      
65         for (;;) {
66                 struct dentry * parent;
67                 int namelen;
68                                                                                                                                                                                                      
69                 if (dentry == root)
70                         break;
71                 parent = dentry->d_parent;
72                 if (dentry == parent)
73                         break;
74                 namelen = dentry->d_name.len;
75                 buflen -= namelen + 1;
76                 if (buflen < 0)
77                         break;
78                 end -= namelen;
79                 memcpy(end, dentry->d_name.name, namelen);
80                 *--end = '/';
81                 retval = end;
82                 dentry = parent;
83         }
84         return retval;
85 }
86                                                                                                                                                                                                      
87 static inline char *logit(char *buf, const void *value, int size)
88 {
89         char *ptr = (char *)value;
90                                                                                                                                                                                                      
91         memcpy(buf, ptr, size);
92         buf += size;
93         return buf;
94 }
95 static inline char *
96 journal_log_prefix_with_groups_and_ids(char *buf, int opcode,
97                                        __u32 ngroups, gid_t *groups,
98                                        __u32 fsuid, __u32 fsgid)
99 {
100         struct kml_prefix_hdr p;
101         u32 loggroups[NGROUPS_MAX];
102                                                                                                                                                                                                      
103         int i;
104                                                                                                                                                                                                      
105         p.version = KML_MAJOR_VERSION | KML_MINOR_VERSION;
106         p.pid = cpu_to_le32(current->pid);
107         p.auid = cpu_to_le32(current->uid);
108         p.fsuid = cpu_to_le32(fsuid);
109         p.fsgid = cpu_to_le32(fsgid);
110         p.ngroups = cpu_to_le32(ngroups);
111         p.opcode = cpu_to_le32(opcode);
112         for (i=0 ; i < ngroups ; i++)
113                 loggroups[i] = cpu_to_le32((__u32) groups[i]);
114                                                                                                                                                                                                      
115         buf = logit(buf, &p, sizeof(struct kml_prefix_hdr));
116         buf = logit(buf, &loggroups, sizeof(__u32) * ngroups);
117         return buf;
118 }
119                                                                                                                                                                                                      
120 static inline char *
121 journal_log_prefix(char *buf, int opcode)
122 {
123         __u32 groups[NGROUPS_MAX];
124         int i;
125                                                                                                                                                                                                      
126         /* convert 16 bit gid's to 32 bit gid's */
127         for (i=0; i<current->ngroups; i++)
128                 groups[i] = (__u32) current->groups[i];
129                                                                                                                                                                                                      
130         return journal_log_prefix_with_groups_and_ids(buf, opcode, 
131                                                       (__u32)current->ngroups,
132                                                       groups,
133                                                       (__u32)current->fsuid,
134                                                       (__u32)current->fsgid);
135 }
136                                                                                                                                                                                                      
137 static inline char *
138 journal_log_prefix_with_groups(char *buf, int opcode, 
139                                __u32 ngroups, gid_t *groups)
140 {
141         return journal_log_prefix_with_groups_and_ids(buf, opcode,
142                                                       ngroups, groups,
143                                                       (__u32)current->fsuid,
144                                                       (__u32)current->fsgid);
145 }
146
147 static inline char *log_dentry_version(char *buf, struct dentry *dentry)
148 {
149         struct smfs_version version;
150                                                                                                                                                                                                      
151         smfs_getversion(&version, dentry->d_inode);
152                                                                                                                                                                                                      
153         version.sm_mtime = HTON__u64(version.sm_mtime);
154         version.sm_ctime = HTON__u64(version.sm_ctime);
155         version.sm_size = HTON__u64(version.sm_size);
156                                                                                                                                                                                                      
157         return logit(buf, &version, sizeof(version));
158 }
159                                                                                                                                                                                                      
160 static inline char *log_version(char *buf, struct smfs_version *pv)
161 {
162         struct smfs_version version;
163                                                                                                                                                                                                      
164         memcpy(&version, pv, sizeof(version));
165                                                                                                                                                                                                      
166         version.sm_mtime = HTON__u64(version.sm_mtime);
167         version.sm_ctime = HTON__u64(version.sm_ctime);
168         version.sm_size = HTON__u64(version.sm_size);
169                                                                                                                                                                                                      
170         return logit(buf, &version, sizeof(version));
171 }
172 static inline char *journal_log_suffix(char *buf, char *log,
173                                        struct dentry *dentry)
174 {
175         struct kml_suffix s;
176         struct kml_prefix_hdr *p = (struct kml_prefix_hdr *)log;
177                                                                                                                                                                                                      
178         s.prevrec = 0;
179                                                                                                                                                                                                      
180         /* record number needs to be filled in after reservation
181            s.recno = cpu_to_le32(rec->recno); */
182         s.time = cpu_to_le32(CURRENT_TIME);
183         s.len = p->len;
184         return logit(buf, &s, sizeof(s));
185 }
186
187 int smfs_kml_log(struct smfs_super_info *smfs_info,
188                  const char *buf, size_t size,
189                  const char *string1, int len1,
190                  const char *string2, int len2,
191                  const char *string3, int len3)
192 {
193         int rc = 0;     
194         /*should pack the record and dispatch it
195          *create llog handle write to the log*/
196         return rc;
197 }
198
199 int smfs_journal_mkdir(struct dentry *dentry,
200                        struct smfs_version *tgt_dir_ver,
201                        struct smfs_version *new_dir_ver, 
202                        int mode)
203 {
204         int opcode = KML_OPCODE_MKDIR;
205         char *buffer, *path, *logrecord, record[292];
206         struct dentry *root;
207         __u32 uid, gid, lmode, pathlen;
208         struct smfs_super_info *smfs_info;             
209         struct super_block* sb;
210         int error, size;
211  
212         ENTRY;
213        
214         sb = dentry->d_inode->i_sb;
215         root = sb->s_root;
216         smfs_info = S2SMI(sb);
217         
218         uid = cpu_to_le32(dentry->d_inode->i_uid);
219         gid = cpu_to_le32(dentry->d_inode->i_gid);
220         lmode = cpu_to_le32(mode);
221                                                                                                                                                                                                      
222         SM_ALLOC(buffer, PAGE_SIZE);
223         path = smfs_path(dentry, root, buffer, PAGE_SIZE);
224         pathlen = cpu_to_le32(MYPATHLEN(buffer, path));
225         size = sizeof(__u32) * current->ngroups +
226                sizeof(struct kml_prefix_hdr) + 3 * sizeof(*tgt_dir_ver) +
227                sizeof(lmode) + sizeof(uid) + sizeof(gid) + sizeof(pathlen) +
228                sizeof(struct kml_suffix);
229                                                                                                                                                                                                      
230         if ( size > sizeof(record) )
231                 CERROR("InterMezzo: BUFFER OVERFLOW in %s!\n", __FUNCTION__);
232                                                                                                                                                                                                      
233         logrecord = journal_log_prefix(record, opcode);
234                                                                                                                                                                                                      
235         logrecord = log_version(logrecord, tgt_dir_ver);
236         logrecord = log_dentry_version(logrecord, dentry->d_parent);
237         logrecord = log_version(logrecord, new_dir_ver);
238         logrecord = logit(logrecord, &lmode, sizeof(lmode));
239         logrecord = logit(logrecord, &uid, sizeof(uid));
240         logrecord = logit(logrecord, &gid, sizeof(gid));
241         logrecord = logit(logrecord, &pathlen, sizeof(pathlen));
242         logrecord = journal_log_suffix(logrecord, record, dentry);
243                                                                                                                                                                                                      
244         error = smfs_kml_log(smfs_info, record, size,
245                          path, size_round(le32_to_cpu(pathlen)),
246                          NULL, 0, NULL, 0);
247         SM_FREE(buffer, PAGE_SIZE);
248         RETURN(error);
249 }