1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
3 *
4 * Copyright (C) 1998 Peter J. Braam <braam@clusterfs.com>
5 * Copyright (C) 2000 Red Hat, Inc.
6 * Copyright (C) 2000 Los Alamos National Laboratory
7 * Copyright (C) 2000 TurboLinux, Inc.
8 * Copyright (C) 2001 Mountain View Data, Inc.
9 *
10 * This file is part of InterMezzo, http://www.inter-mezzo.org.
11 *
12 * InterMezzo is free software; you can redistribute it and/or
13 * modify it under the terms of version 2 of the GNU General Public
14 * License as published by the Free Software Foundation.
15 *
16 * InterMezzo is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with InterMezzo; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26 #include <linux/types.h>
27 #include <linux/param.h>
28 #include <linux/kernel.h>
29 #include <linux/sched.h>
30 #include <linux/fs.h>
31 #include <linux/slab.h>
32 #include <linux/vmalloc.h>
33 #include <linux/stat.h>
34 #include <linux/errno.h>
35 #include <linux/locks.h>
36 #include <asm/segment.h>
37 #include <asm/uaccess.h>
38 #include <linux/string.h>
39 #ifdef CONFIG_OBDFS_FS
40 #include /usr/src/obd/include/linux/obdfs.h
41 #endif
42
43 #include <linux/intermezzo_fs.h>
44 #include <linux/intermezzo_psdev.h>
45
46 #ifdef CONFIG_OBDFS_FS
47
48
presto_obdfs_freespace(struct presto_file_set * fset,struct super_block * sb)49 static unsigned long presto_obdfs_freespace(struct presto_file_set *fset,
50 struct super_block *sb)
51 {
52 return 0x0fffff;
53 }
54
55 /* start the filesystem journal operations */
presto_obdfs_trans_start(struct presto_file_set * fset,struct inode * inode,int op)56 static void *presto_obdfs_trans_start(struct presto_file_set *fset,
57 struct inode *inode,
58 int op)
59 {
60
61 return (void *) 1;
62 }
63
64 #if 0
65 int jblocks;
66 int trunc_blks, one_path_blks, extra_path_blks,
67 extra_name_blks, lml_blks;
68 __u32 avail_kmlblocks;
69
70 if ( presto_no_journal(fset) ||
71 strcmp(fset->fset_cache->cache_type, "ext3"))
72 {
73 CDEBUG(D_JOURNAL, "got cache_type \"%s\"\n",
74 fset->fset_cache->cache_type);
75 return NULL;
76 }
77
78 avail_kmlblocks = inode->i_sb->u.ext3_sb.s_es->s_free_blocks_count;
79
80 if ( avail_kmlblocks < 3 ) {
81 return ERR_PTR(-ENOSPC);
82 }
83
84 if ( (op != PRESTO_OP_UNLINK && op != PRESTO_OP_RMDIR)
85 && avail_kmlblocks < 6 ) {
86 return ERR_PTR(-ENOSPC);
87 }
88
89 /* Need journal space for:
90 at least three writes to KML (two one block writes, one a path)
91 possibly a second name (unlink, rmdir)
92 possibly a second path (symlink, rename)
93 a one block write to the last rcvd file
94 */
95
96 trunc_blks = EXT3_DATA_TRANS_BLOCKS + 1;
97 one_path_blks = 4*EXT3_DATA_TRANS_BLOCKS + MAX_PATH_BLOCKS(inode) + 3;
98 lml_blks = 4*EXT3_DATA_TRANS_BLOCKS + MAX_PATH_BLOCKS(inode) + 2;
99 extra_path_blks = EXT3_DATA_TRANS_BLOCKS + MAX_PATH_BLOCKS(inode);
100 extra_name_blks = EXT3_DATA_TRANS_BLOCKS + MAX_NAME_BLOCKS(inode);
101
102 /* additional blocks appear for "two pathname" operations
103 and operations involving the LML records
104 */
105 switch (op) {
106 case PRESTO_OP_TRUNC:
107 jblocks = one_path_blks + extra_name_blks + trunc_blks
108 + EXT3_DELETE_TRANS_BLOCKS;
109 break;
110 case PRESTO_OP_RELEASE:
111 /*
112 jblocks = one_path_blks + lml_blks + 2*trunc_blks;
113 */
114 jblocks = one_path_blks;
115 break;
116 case PRESTO_OP_SETATTR:
117 jblocks = one_path_blks + trunc_blks + 1 ;
118 break;
119 case PRESTO_OP_CREATE:
120 jblocks = one_path_blks + trunc_blks
121 + EXT3_DATA_TRANS_BLOCKS + 3;
122 break;
123 case PRESTO_OP_LINK:
124 jblocks = one_path_blks + trunc_blks
125 + EXT3_DATA_TRANS_BLOCKS;
126 break;
127 case PRESTO_OP_UNLINK:
128 jblocks = one_path_blks + extra_name_blks + trunc_blks
129 + EXT3_DELETE_TRANS_BLOCKS;
130 break;
131 case PRESTO_OP_SYMLINK:
132 jblocks = one_path_blks + extra_path_blks + trunc_blks
133 + EXT3_DATA_TRANS_BLOCKS + 5;
134 break;
135 case PRESTO_OP_MKDIR:
136 jblocks = one_path_blks + trunc_blks
137 + EXT3_DATA_TRANS_BLOCKS + 4;
138 break;
139 case PRESTO_OP_RMDIR:
140 jblocks = one_path_blks + extra_name_blks + trunc_blks
141 + EXT3_DELETE_TRANS_BLOCKS;
142 break;
143 case PRESTO_OP_MKNOD:
144 jblocks = one_path_blks + trunc_blks +
145 EXT3_DATA_TRANS_BLOCKS + 3;
146 break;
147 case PRESTO_OP_RENAME:
148 jblocks = one_path_blks + extra_path_blks + trunc_blks +
149 2 * EXT3_DATA_TRANS_BLOCKS + 2;
150 break;
151 case PRESTO_OP_WRITE:
152 jblocks = one_path_blks;
153 /* add this when we can wrap our transaction with
154 that of ext3_file_write (ordered writes)
155 + EXT3_DATA_TRANS_BLOCKS;
156 */
157 break;
158 default:
159 CDEBUG(D_JOURNAL, "invalid operation %d for journal\n", op);
160 return NULL;
161 }
162
163 CDEBUG(D_JOURNAL, "creating journal handle (%d blocks)\n", jblocks);
164 return journal_start(EXT3_JOURNAL(inode), jblocks);
165 }
166 #endif
167
presto_obdfs_trans_commit(struct presto_file_set * fset,void * handle)168 void presto_obdfs_trans_commit(struct presto_file_set *fset, void *handle)
169 {
170 #if 0
171 if ( presto_no_journal(fset) || !handle)
172 return;
173
174 journal_stop(handle);
175 #endif
176 }
177
presto_obdfs_journal_file_data(struct inode * inode)178 void presto_obdfs_journal_file_data(struct inode *inode)
179 {
180 #ifdef EXT3_JOURNAL_DATA_FL
181 inode->u.ext3_i.i_flags |= EXT3_JOURNAL_DATA_FL;
182 #else
183 #warning You must have a facility to enable journaled writes for recovery!
184 #endif
185 }
186
187 struct journal_ops presto_obdfs_journal_ops = {
188 .tr_avail = presto_obdfs_freespace,
189 .tr_start = presto_obdfs_trans_start,
190 .tr_commit = presto_obdfs_trans_commit,
191 .tr_journal_data = presto_obdfs_journal_file_data
192 };
193
194 #endif
195