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