6 #define DEBUG_SUBSYSTEM S_SM
8 #include <linux/kmod.h>
9 #include <linux/init.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>
17 #include "smfs_internal.h"
18 extern struct sm_ops smfs_operations;
20 #define size_round(x) (((x)+3) & ~0x3)
22 void *smfs_trans_start(struct inode *inode, int op)
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);
33 void smfs_trans_commit(void *handle)
35 if (smfs_operations.sm_journal_ops.tr_commit) {
36 smfs_operations.sm_journal_ops.tr_commit(handle);
38 CDEBUG(D_SM, "trans commit %p\n",
39 smfs_operations.sm_journal_ops.tr_commit);
41 /*The following function are gotten from intermezzo
44 * journal_log_prefix_with_groups_and_ids
47 static char* smfs_path(struct dentry *dentry, struct dentry *root,
48 char *buffer, int buflen)
50 char * end = buffer+buflen;
55 if (dentry->d_parent != dentry && list_empty(&dentry->d_hash)) {
58 memcpy(end, " (deleted)", 10);
66 struct dentry * parent;
71 parent = dentry->d_parent;
74 namelen = dentry->d_name.len;
75 buflen -= namelen + 1;
79 memcpy(end, dentry->d_name.name, namelen);
87 static inline char *logit(char *buf, const void *value, int size)
89 char *ptr = (char *)value;
91 memcpy(buf, ptr, size);
96 journal_log_prefix_with_groups_and_ids(char *buf, int opcode,
97 __u32 ngroups, gid_t *groups,
98 __u32 fsuid, __u32 fsgid)
100 struct kml_prefix_hdr p;
101 u32 loggroups[NGROUPS_MAX];
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]);
115 buf = logit(buf, &p, sizeof(struct kml_prefix_hdr));
116 buf = logit(buf, &loggroups, sizeof(__u32) * ngroups);
121 journal_log_prefix(char *buf, int opcode)
123 __u32 groups[NGROUPS_MAX];
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];
130 return journal_log_prefix_with_groups_and_ids(buf, opcode,
131 (__u32)current->ngroups,
133 (__u32)current->fsuid,
134 (__u32)current->fsgid);
138 journal_log_prefix_with_groups(char *buf, int opcode,
139 __u32 ngroups, gid_t *groups)
141 return journal_log_prefix_with_groups_and_ids(buf, opcode,
143 (__u32)current->fsuid,
144 (__u32)current->fsgid);
147 static inline char *log_dentry_version(char *buf, struct dentry *dentry)
149 struct smfs_version version;
151 smfs_getversion(&version, dentry->d_inode);
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);
157 return logit(buf, &version, sizeof(version));
160 static inline char *log_version(char *buf, struct smfs_version *pv)
162 struct smfs_version version;
164 memcpy(&version, pv, sizeof(version));
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);
170 return logit(buf, &version, sizeof(version));
172 static inline char *journal_log_suffix(char *buf, char *log,
173 struct dentry *dentry)
176 struct kml_prefix_hdr *p = (struct kml_prefix_hdr *)log;
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);
184 return logit(buf, &s, sizeof(s));
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)
194 /*should pack the record and dispatch it
195 *create llog handle write to the log*/
199 int smfs_journal_mkdir(struct dentry *dentry,
200 struct smfs_version *tgt_dir_ver,
201 struct smfs_version *new_dir_ver,
204 int opcode = KML_OPCODE_MKDIR;
205 char *buffer, *path, *logrecord, record[292];
207 __u32 uid, gid, lmode, pathlen;
208 struct smfs_super_info *smfs_info;
209 struct super_block* sb;
214 sb = dentry->d_inode->i_sb;
216 smfs_info = S2SMI(sb);
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);
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);
230 if ( size > sizeof(record) )
231 CERROR("InterMezzo: BUFFER OVERFLOW in %s!\n", __FUNCTION__);
233 logrecord = journal_log_prefix(record, opcode);
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);
244 error = smfs_kml_log(smfs_info, record, size,
245 path, size_round(le32_to_cpu(pathlen)),
247 SM_FREE(buffer, PAGE_SIZE);