ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / fs / sysv / sysv.h
1 #ifndef _SYSV_H
2 #define _SYSV_H
3
4 #include <linux/buffer_head.h>
5 #include <linux/sysv_fs.h>
6
7 /*
8  * SystemV/V7/Coherent super-block data in memory
9  *
10  * The SystemV/V7/Coherent superblock contains dynamic data (it gets modified
11  * while the system is running). This is in contrast to the Minix and Berkeley
12  * filesystems (where the superblock is never modified). This affects the
13  * sync() operation: we must keep the superblock in a disk buffer and use this
14  * one as our "working copy".
15  */
16
17 struct sysv_sb_info {
18         struct super_block *s_sb;       /* VFS superblock */
19         int            s_type;          /* file system type: FSTYPE_{XENIX|SYSV|COH} */
20         char           s_bytesex;       /* bytesex (le/be/pdp) */
21         char           s_truncate;      /* if 1: names > SYSV_NAMELEN chars are truncated */
22                                         /* if 0: they are disallowed (ENAMETOOLONG) */
23         nlink_t        s_link_max;      /* max number of hard links to a file */
24         unsigned int   s_inodes_per_block;      /* number of inodes per block */
25         unsigned int   s_inodes_per_block_1;    /* inodes_per_block - 1 */
26         unsigned int   s_inodes_per_block_bits; /* log2(inodes_per_block) */
27         unsigned int   s_ind_per_block;         /* number of indirections per block */
28         unsigned int   s_ind_per_block_bits;    /* log2(ind_per_block) */
29         unsigned int   s_ind_per_block_2;       /* ind_per_block ^ 2 */
30         unsigned int   s_toobig_block;          /* 10 + ipb + ipb^2 + ipb^3 */
31         unsigned int   s_block_base;    /* physical block number of block 0 */
32         unsigned short s_fic_size;      /* free inode cache size, NICINOD */
33         unsigned short s_flc_size;      /* free block list chunk size, NICFREE */
34         /* The superblock is kept in one or two disk buffers: */
35         struct buffer_head *s_bh1;
36         struct buffer_head *s_bh2;
37         /* These are pointers into the disk buffer, to compensate for
38            different superblock layout. */
39         char *         s_sbd1;          /* entire superblock data, for part 1 */
40         char *         s_sbd2;          /* entire superblock data, for part 2 */
41         u16            *s_sb_fic_count; /* pointer to s_sbd->s_ninode */
42         u16            *s_sb_fic_inodes; /* pointer to s_sbd->s_inode */
43         u16            *s_sb_total_free_inodes; /* pointer to s_sbd->s_tinode */
44         u16            *s_bcache_count; /* pointer to s_sbd->s_nfree */
45         u32            *s_bcache;       /* pointer to s_sbd->s_free */
46         u32            *s_free_blocks;  /* pointer to s_sbd->s_tfree */
47         u32            *s_sb_time;      /* pointer to s_sbd->s_time */
48         u32            *s_sb_state;     /* pointer to s_sbd->s_state, only FSTYPE_SYSV */
49         /* We keep those superblock entities that don't change here;
50            this saves us an indirection and perhaps a conversion. */
51         u32            s_firstinodezone; /* index of first inode zone */
52         u32            s_firstdatazone; /* same as s_sbd->s_isize */
53         u32            s_ninodes;       /* total number of inodes */
54         u32            s_ndatazones;    /* total number of data zones */
55         u32            s_nzones;        /* same as s_sbd->s_fsize */
56         u16            s_namelen;       /* max length of dir entry */
57         int            s_forced_ro;
58 };
59
60 /*
61  * SystemV/V7/Coherent FS inode data in memory
62  */
63 struct sysv_inode_info {
64         u32             i_data[13];
65         u32             i_dir_start_lookup;
66         struct inode    vfs_inode;
67 };
68
69
70 static inline struct sysv_inode_info *SYSV_I(struct inode *inode)
71 {
72         return list_entry(inode, struct sysv_inode_info, vfs_inode);
73 }
74
75 static inline struct sysv_sb_info *SYSV_SB(struct super_block *sb)
76 {
77         return sb->s_fs_info;
78 }
79
80
81 /* identify the FS in memory */
82 enum {
83         FSTYPE_NONE = 0,
84         FSTYPE_XENIX,
85         FSTYPE_SYSV4,
86         FSTYPE_SYSV2,
87         FSTYPE_COH,
88         FSTYPE_V7,
89         FSTYPE_AFS,
90         FSTYPE_END,
91 };
92
93 #define SYSV_MAGIC_BASE         0x012FF7B3
94
95 #define XENIX_SUPER_MAGIC       (SYSV_MAGIC_BASE+FSTYPE_XENIX)
96 #define SYSV4_SUPER_MAGIC       (SYSV_MAGIC_BASE+FSTYPE_SYSV4)
97 #define SYSV2_SUPER_MAGIC       (SYSV_MAGIC_BASE+FSTYPE_SYSV2)
98 #define COH_SUPER_MAGIC         (SYSV_MAGIC_BASE+FSTYPE_COH)
99
100
101 /* Admissible values for i_nlink: 0.._LINK_MAX */
102 enum {
103         XENIX_LINK_MAX  =       126,    /* ?? */
104         SYSV_LINK_MAX   =       126,    /* 127? 251? */
105         V7_LINK_MAX     =       126,    /* ?? */
106         COH_LINK_MAX    =       10000,
107 };
108
109
110 static inline void dirty_sb(struct super_block *sb)
111 {
112         struct sysv_sb_info *sbi = SYSV_SB(sb);
113
114         mark_buffer_dirty(sbi->s_bh1);
115         if (sbi->s_bh1 != sbi->s_bh2)
116                 mark_buffer_dirty(sbi->s_bh2);
117         sb->s_dirt = 1;
118 }
119
120
121 /* ialloc.c */
122 extern struct sysv_inode *sysv_raw_inode(struct super_block *, unsigned,
123                         struct buffer_head **);
124 extern struct inode * sysv_new_inode(const struct inode *, mode_t);
125 extern void sysv_free_inode(struct inode *);
126 extern unsigned long sysv_count_free_inodes(struct super_block *);
127
128 /* balloc.c */
129 extern u32 sysv_new_block(struct super_block *);
130 extern void sysv_free_block(struct super_block *, u32);
131 extern unsigned long sysv_count_free_blocks(struct super_block *);
132
133 /* itree.c */
134 extern void sysv_truncate(struct inode *);
135
136 /* inode.c */
137 extern void sysv_write_inode(struct inode *, int);
138 extern int sysv_sync_inode(struct inode *);
139 extern int sysv_sync_file(struct file *, struct dentry *, int);
140 extern void sysv_set_inode(struct inode *, dev_t);
141 extern int sysv_getattr(struct vfsmount *, struct dentry *, struct kstat *);
142
143 /* dir.c */
144 extern struct sysv_dir_entry *sysv_find_entry(struct dentry *, struct page **);
145 extern int sysv_add_link(struct dentry *, struct inode *);
146 extern int sysv_delete_entry(struct sysv_dir_entry *, struct page *);
147 extern int sysv_make_empty(struct inode *, struct inode *);
148 extern int sysv_empty_dir(struct inode *);
149 extern void sysv_set_link(struct sysv_dir_entry *, struct page *,
150                         struct inode *);
151 extern struct sysv_dir_entry *sysv_dotdot(struct inode *, struct page **);
152 extern ino_t sysv_inode_by_name(struct dentry *);
153
154
155 extern struct inode_operations sysv_file_inode_operations;
156 extern struct inode_operations sysv_dir_inode_operations;
157 extern struct inode_operations sysv_fast_symlink_inode_operations;
158 extern struct file_operations sysv_file_operations;
159 extern struct file_operations sysv_dir_operations;
160 extern struct address_space_operations sysv_aops;
161 extern struct super_operations sysv_sops;
162 extern struct dentry_operations sysv_dentry_operations;
163
164
165 enum {
166         BYTESEX_LE,
167         BYTESEX_PDP,
168         BYTESEX_BE,
169 };
170
171 static inline u32 PDP_swab(u32 x)
172 {
173 #ifdef __LITTLE_ENDIAN
174         return ((x & 0xffff) << 16) | ((x & 0xffff0000) >> 16);
175 #else
176 #ifdef __BIG_ENDIAN
177         return ((x & 0xff00ff) << 8) | ((x & 0xff00ff00) >> 8);
178 #else
179 #error BYTESEX
180 #endif
181 #endif
182 }
183
184 static inline u32 fs32_to_cpu(struct sysv_sb_info *sbi, u32 n)
185 {
186         if (sbi->s_bytesex == BYTESEX_PDP)
187                 return PDP_swab(n);
188         else if (sbi->s_bytesex == BYTESEX_LE)
189                 return le32_to_cpu(n);
190         else
191                 return be32_to_cpu(n);
192 }
193
194 static inline u32 cpu_to_fs32(struct sysv_sb_info *sbi, u32 n)
195 {
196         if (sbi->s_bytesex == BYTESEX_PDP)
197                 return PDP_swab(n);
198         else if (sbi->s_bytesex == BYTESEX_LE)
199                 return cpu_to_le32(n);
200         else
201                 return cpu_to_be32(n);
202 }
203
204 static inline u32 fs32_add(struct sysv_sb_info *sbi, u32 *n, int d)
205 {
206         if (sbi->s_bytesex == BYTESEX_PDP)
207                 return *n = PDP_swab(PDP_swab(*n)+d);
208         else if (sbi->s_bytesex == BYTESEX_LE)
209                 return *n = cpu_to_le32(le32_to_cpu(*n)+d);
210         else
211                 return *n = cpu_to_be32(be32_to_cpu(*n)+d);
212 }
213
214 static inline u16 fs16_to_cpu(struct sysv_sb_info *sbi, u16 n)
215 {
216         if (sbi->s_bytesex != BYTESEX_BE)
217                 return le16_to_cpu(n);
218         else
219                 return be16_to_cpu(n);
220 }
221
222 static inline u16 cpu_to_fs16(struct sysv_sb_info *sbi, u16 n)
223 {
224         if (sbi->s_bytesex != BYTESEX_BE)
225                 return cpu_to_le16(n);
226         else
227                 return cpu_to_be16(n);
228 }
229
230 static inline u16 fs16_add(struct sysv_sb_info *sbi, u16 *n, int d)
231 {
232         if (sbi->s_bytesex != BYTESEX_BE)
233                 return *n = cpu_to_le16(le16_to_cpu(*n)+d);
234         else
235                 return *n = cpu_to_be16(be16_to_cpu(*n)+d);
236 }
237
238 #endif /* _SYSV_H */