Whamcloud - gitweb
- tagging RC_CURRENT
[fs/lustre-release.git] / lustre / smfs / journal_ext3.c
1 /*
2  *  smfs/journal_ext3.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 <linux/smp_lock.h>
14 #include <linux/lustre_idl.h>
15 #if defined(CONFIG_EXT3_FS) || defined (CONFIG_EXT3_FS_MODULE)
16 #include <linux/jbd.h>
17 #include <linux/ext3_fs.h>
18 #include <linux/ext3_jbd.h>
19 #endif
20                                                                                                                                                                                                      
21 #include "smfs_internal.h" 
22 #include "kml_idl.h" 
23                                                                                                                                                                                                      
24 #if defined(CONFIG_EXT3_FS) || defined (CONFIG_EXT3_FS_MODULE)
25
26 #define MAX_PATH_BLOCKS(inode) (PATH_MAX >> EXT3_BLOCK_SIZE_BITS((inode)->i_sb))
27 #define MAX_NAME_BLOCKS(inode) (NAME_MAX >> EXT3_BLOCK_SIZE_BITS((inode)->i_sb))
28
29 static void *smfs_e3_trans_start(struct inode *inode, 
30                                 int op)
31 {
32         
33         int trunc_blks, one_path_blks, extra_path_blks;
34         int extra_name_blks, lml_blks, jblocks;
35         __u32 avail_kmlblocks;
36         handle_t *handle;
37         
38         avail_kmlblocks = inode->i_sb->u.ext3_sb.s_es->s_free_blocks_count;
39                                                                                                                                                                                                      
40         if ( avail_kmlblocks < 3 ) {
41                 return ERR_PTR(-ENOSPC);
42         }
43                                                                                                                                                                                                      
44         if ((op != KML_OPCODE_UNLINK && op != KML_OPCODE_RMDIR)
45              && avail_kmlblocks < 6 ) {
46                 return ERR_PTR(-ENOSPC);
47         }
48         /* Need journal space for:
49              at least three writes to KML (two one block writes, one a path)
50              possibly a second name (unlink, rmdir)
51              possibly a second path (symlink, rename)
52              a one block write to the last rcvd file
53         */
54                                                                                                                                                                                                      
55         trunc_blks = EXT3_DATA_TRANS_BLOCKS + 1;
56         one_path_blks = 4*EXT3_DATA_TRANS_BLOCKS + MAX_PATH_BLOCKS(inode) + 3;
57         lml_blks = 4*EXT3_DATA_TRANS_BLOCKS + MAX_PATH_BLOCKS(inode) + 2;
58         extra_path_blks = EXT3_DATA_TRANS_BLOCKS + MAX_PATH_BLOCKS(inode);
59         extra_name_blks = EXT3_DATA_TRANS_BLOCKS + MAX_NAME_BLOCKS(inode);
60                                                                                                                                                                                                      
61         /* additional blocks appear for "two pathname" operations
62            and operations involving the LML records
63         */
64
65         switch (op) {
66         case KML_OPCODE_MKDIR:
67                 jblocks = one_path_blks + trunc_blks
68                           + EXT3_DATA_TRANS_BLOCKS + 4 + 2;
69                 break;
70         default:
71                 CDEBUG(D_INODE, "invalid operation %d for journal\n", op);
72                 return NULL;
73         }
74
75         CDEBUG(D_INODE, "creating journal handle (%d blocks)\n", jblocks);
76         
77         lock_kernel();
78         handle = journal_start(EXT3_JOURNAL(inode), jblocks);
79         unlock_kernel();
80
81         return handle;
82 }  
83
84 static void smfs_e3_trans_commit(void *handle)
85 {
86         lock_kernel();
87         journal_stop(handle);
88         unlock_kernel();
89 }
90
91 struct journal_operations smfs_ext3_journal_ops = {
92         .tr_start   = smfs_e3_trans_start, 
93         .tr_commit  = smfs_e3_trans_commit,
94 };
95 #endif
96