1 /* Copyright 2001, 2002, 2003, 2004 by Hans Reiser, licensing governed by
4 /* Super-block manipulations. */
9 #include "plugin/security/perm.h"
10 #include "plugin/space/space_allocator.h"
11 #include "plugin/plugin.h"
17 #include <linux/types.h> /* for __u?? */
18 #include <linux/fs.h> /* for struct super_block */
20 static __u64
reserved_for_gid(const struct super_block
*super
, gid_t gid
);
21 static __u64
reserved_for_uid(const struct super_block
*super
, uid_t uid
);
22 static __u64
reserved_for_root(const struct super_block
*super
);
24 /* Return reiser4-specific part of super block */
25 reiser4_super_info_data
*get_super_private_nocheck(const struct super_block
*super
)
27 return (reiser4_super_info_data
*) super
->s_fs_info
;
30 /* Return reiser4 fstype: value that is returned in ->f_type field by statfs()
32 long reiser4_statfs_type(const struct super_block
*super UNUSED_ARG
)
34 assert("nikita-448", super
!= NULL
);
35 assert("nikita-449", is_reiser4_super(super
));
36 return (long)REISER4_SUPER_MAGIC
;
39 /* functions to read/modify fields of reiser4_super_info_data */
41 /* get number of blocks in file system */
42 __u64
reiser4_block_count(const struct super_block
*super
/* super block
45 assert("vs-494", super
!= NULL
);
46 assert("vs-495", is_reiser4_super(super
));
47 return get_super_private(super
)->block_count
;
52 * number of blocks in the current file system
54 __u64
reiser4_current_block_count(void)
56 return get_current_super_private()->block_count
;
58 #endif /* REISER4_DEBUG */
60 /* set number of block in filesystem */
61 void reiser4_set_block_count(const struct super_block
*super
, __u64 nr
)
63 assert("vs-501", super
!= NULL
);
64 assert("vs-502", is_reiser4_super(super
));
65 get_super_private(super
)->block_count
= nr
;
67 * The proper calculation of the reserved space counter (%5 of device
68 * block counter) we need a 64 bit division which is missing in Linux
69 * on i386 platform. Because we do not need a precise calculation here
70 * we can replace a div64 operation by this combination of
71 * multiplication and shift: 51. / (2^10) == .0498 .
72 * FIXME: this is a bug. It comes up only for very small filesystems
73 * which probably are never used. Nevertheless, it is a bug. Number of
74 * reserved blocks must be not less than maximal number of blocks which
75 * get grabbed with BA_RESERVED.
77 get_super_private(super
)->blocks_reserved
= ((nr
* 51) >> 10);
80 /* amount of blocks used (allocated for data) in file system */
81 __u64
reiser4_data_blocks(const struct super_block
*super
/* super block
84 assert("nikita-452", super
!= NULL
);
85 assert("nikita-453", is_reiser4_super(super
));
86 return get_super_private(super
)->blocks_used
;
89 /* set number of block used in filesystem */
90 void reiser4_set_data_blocks(const struct super_block
*super
, __u64 nr
)
92 assert("vs-503", super
!= NULL
);
93 assert("vs-504", is_reiser4_super(super
));
94 get_super_private(super
)->blocks_used
= nr
;
97 /* amount of free blocks in file system */
98 __u64
reiser4_free_blocks(const struct super_block
*super
/* super block
101 assert("nikita-454", super
!= NULL
);
102 assert("nikita-455", is_reiser4_super(super
));
103 return get_super_private(super
)->blocks_free
;
106 /* set number of blocks free in filesystem */
107 void reiser4_set_free_blocks(const struct super_block
*super
, __u64 nr
)
109 assert("vs-505", super
!= NULL
);
110 assert("vs-506", is_reiser4_super(super
));
111 get_super_private(super
)->blocks_free
= nr
;
114 /* get mkfs unique identifier */
115 __u32
reiser4_mkfs_id(const struct super_block
*super
/* super block
118 assert("vpf-221", super
!= NULL
);
119 assert("vpf-222", is_reiser4_super(super
));
120 return get_super_private(super
)->mkfs_id
;
123 /* amount of free blocks in file system */
124 __u64
reiser4_free_committed_blocks(const struct super_block
*super
)
126 assert("vs-497", super
!= NULL
);
127 assert("vs-498", is_reiser4_super(super
));
128 return get_super_private(super
)->blocks_free_committed
;
131 /* amount of blocks in the file system reserved for @uid and @gid */
132 long reiser4_reserved_blocks(const struct super_block
*super
/* super block
134 uid_t uid
/* user id */ ,
135 gid_t gid
/* group id */)
139 assert("nikita-456", super
!= NULL
);
140 assert("nikita-457", is_reiser4_super(super
));
143 if (REISER4_SUPPORT_GID_SPACE_RESERVATION
)
144 reserved
+= reserved_for_gid(super
, gid
);
145 if (REISER4_SUPPORT_UID_SPACE_RESERVATION
)
146 reserved
+= reserved_for_uid(super
, uid
);
147 if (REISER4_SUPPORT_ROOT_SPACE_RESERVATION
&& capable(CAP_SYS_RESOURCE
))
148 reserved
+= reserved_for_root(super
);
152 /* get/set value of/to grabbed blocks counter */
153 __u64
reiser4_grabbed_blocks(const struct super_block
*super
)
155 assert("zam-512", super
!= NULL
);
156 assert("zam-513", is_reiser4_super(super
));
158 return get_super_private(super
)->blocks_grabbed
;
161 __u64
reiser4_flush_reserved(const struct super_block
*super
)
163 assert("vpf-285", super
!= NULL
);
164 assert("vpf-286", is_reiser4_super(super
));
166 return get_super_private(super
)->blocks_flush_reserved
;
169 /* get/set value of/to counter of fake allocated formatted blocks */
170 __u64
reiser4_fake_allocated(const struct super_block
*super
)
172 assert("zam-516", super
!= NULL
);
173 assert("zam-517", is_reiser4_super(super
));
175 return get_super_private(super
)->blocks_fake_allocated
;
178 /* get/set value of/to counter of fake allocated unformatted blocks */
179 __u64
reiser4_fake_allocated_unformatted(const struct super_block
*super
)
181 assert("zam-516", super
!= NULL
);
182 assert("zam-517", is_reiser4_super(super
));
184 return get_super_private(super
)->blocks_fake_allocated_unformatted
;
187 /* get/set value of/to counter of clustered blocks */
188 __u64
reiser4_clustered_blocks(const struct super_block
*super
)
190 assert("edward-601", super
!= NULL
);
191 assert("edward-602", is_reiser4_super(super
));
193 return get_super_private(super
)->blocks_clustered
;
196 /* space allocator used by this file system */
197 reiser4_space_allocator
* reiser4_get_space_allocator(const struct super_block
200 assert("nikita-1965", super
!= NULL
);
201 assert("nikita-1966", is_reiser4_super(super
));
202 return &get_super_private(super
)->space_allocator
;
205 /* return fake inode used to bind formatted nodes in the page cache */
206 struct inode
*reiser4_get_super_fake(const struct super_block
*super
)
208 assert("nikita-1757", super
!= NULL
);
209 return get_super_private(super
)->fake
;
212 /* return fake inode used to bind copied on capture nodes in the page cache */
213 struct inode
*reiser4_get_cc_fake(const struct super_block
*super
)
215 assert("nikita-1757", super
!= NULL
);
216 return get_super_private(super
)->cc
;
219 /* return fake inode used to bind bitmaps and journlal heads */
220 struct inode
*reiser4_get_bitmap_fake(const struct super_block
*super
)
222 assert("nikita-17571", super
!= NULL
);
223 return get_super_private(super
)->bitmap
;
226 /* tree used by this file system */
227 reiser4_tree
*reiser4_get_tree(const struct super_block
*super
)
229 assert("nikita-460", super
!= NULL
);
230 assert("nikita-461", is_reiser4_super(super
));
231 return &get_super_private(super
)->tree
;
234 /* Check that @super is (looks like) reiser4 super block. This is mainly for
235 use in assertions. */
236 int is_reiser4_super(const struct super_block
*super
)
240 get_super_private(super
) != NULL
&&
241 super
->s_op
== &(get_super_private(super
)->ops
.super
);
244 int reiser4_is_set(const struct super_block
*super
, reiser4_fs_flag f
)
246 return test_bit((int)f
, &get_super_private(super
)->fs_flags
);
249 /* amount of blocks reserved for given group in file system */
250 static __u64
reserved_for_gid(const struct super_block
*super UNUSED_ARG
,
251 gid_t gid UNUSED_ARG
/* group id */)
256 /* amount of blocks reserved for given user in file system */
257 static __u64
reserved_for_uid(const struct super_block
*super UNUSED_ARG
,
258 uid_t uid UNUSED_ARG
/* user id */)
263 /* amount of blocks reserved for super user in file system */
264 static __u64
reserved_for_root(const struct super_block
*super UNUSED_ARG
)
270 * true if block number @blk makes sense for the file system at @super.
273 reiser4_blocknr_is_sane_for(const struct super_block
*super
,
274 const reiser4_block_nr
* blk
)
276 reiser4_super_info_data
*sbinfo
;
278 assert("nikita-2957", super
!= NULL
);
279 assert("nikita-2958", blk
!= NULL
);
281 if (reiser4_blocknr_is_fake(blk
))
284 sbinfo
= get_super_private(super
);
285 return *blk
< sbinfo
->block_count
;
290 * true, if block number @blk makes sense for the current file system
292 int reiser4_blocknr_is_sane(const reiser4_block_nr
* blk
)
294 return reiser4_blocknr_is_sane_for(reiser4_get_current_sb(), blk
);
296 #endif /* REISER4_DEBUG */
300 c-indentation-style: "K&R"