オープンソース・ソフトウェアの開発とダウンロード

Subversion リポジトリの参照

Contents of /trunk/1.6.x/ccs-patch/fs/syaoran_2.6.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1903 - (show annotations) (download) (as text)
Mon Dec 1 06:16:16 2008 UTC (15 years, 5 months ago) by kumaneko
File MIME type: text/x-csrc
File size: 10198 byte(s)


1 /*
2 * fs/syaoran_2.6.c
3 *
4 * Implementation of the Tamper-Proof Device Filesystem.
5 *
6 * Portions Copyright (C) 2005-2008 NTT DATA CORPORATION
7 *
8 * Version: 1.6.6-pre 2008/12/01
9 *
10 * This file is applicable to 2.6.11 and later.
11 * See README.ccs for ChangeLog.
12 * This filesystem is developed using the ramfs implementation.
13 *
14 */
15 /*
16 * Resizable simple ram filesystem for Linux.
17 *
18 * Copyright (C) 2000 Linus Torvalds.
19 * 2000 Transmeta Corp.
20 *
21 * Usage limits added by David Gibson, Linuxcare Australia.
22 * This file is released under the GPL.
23 */
24
25 /*
26 * NOTE! This filesystem is probably most useful
27 * not as a real filesystem, but as an example of
28 * how virtual filesystems can be written.
29 *
30 * It doesn't get much simpler than this. Consider
31 * that this file implements the full semantics of
32 * a POSIX-compliant read-write filesystem.
33 *
34 * Note in particular how the filesystem does not
35 * need to implement any data structures of its own
36 * to keep track of the virtual data: using the VFS
37 * caches is sufficient.
38 */
39
40 #include <linux/module.h>
41 #include <linux/fs.h>
42 #include <linux/pagemap.h>
43 #include <linux/highmem.h>
44 #include <linux/init.h>
45 #include <linux/string.h>
46 #include <linux/smp_lock.h>
47 #include <linux/backing-dev.h>
48
49 #include <asm/uaccess.h>
50
51 #include <linux/namei.h>
52 #include <linux/version.h>
53 #include <linux/sched.h>
54 #include <linux/mm.h>
55
56 static struct super_operations syaoran_ops;
57 static struct address_space_operations syaoran_aops;
58 static struct inode_operations syaoran_file_inode_operations;
59 static struct inode_operations syaoran_dir_inode_operations;
60 static struct inode_operations syaoran_symlink_inode_operations;
61 static struct file_operations syaoran_file_operations;
62
63 static struct backing_dev_info syaoran_backing_dev_info = {
64 .ra_pages = 0, /* No readahead */
65 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 12)
66 .memory_backed = 1, /* Does not contribute to dirty memory */
67 #else
68 .capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK |
69 BDI_CAP_MAP_DIRECT | BDI_CAP_MAP_COPY |
70 BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP |
71 BDI_CAP_EXEC_MAP,
72 #endif
73 };
74
75 #include <linux/syaoran.h>
76
77 static struct inode *syaoran_get_inode(struct super_block *sb, int mode,
78 dev_t dev)
79 {
80 struct inode *inode = new_inode(sb);
81
82 if (inode) {
83 inode->i_mode = mode;
84 inode->i_uid = current->fsuid;
85 inode->i_gid = current->fsgid;
86 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
87 #ifndef HAVE_NO_I_BLKSIZE_IN_INODE
88 inode->i_blksize = PAGE_CACHE_SIZE;
89 #endif
90 #endif
91 inode->i_blocks = 0;
92 inode->i_mapping->a_ops = &syaoran_aops;
93 inode->i_mapping->backing_dev_info = &syaoran_backing_dev_info;
94 inode->i_ctime = CURRENT_TIME;
95 inode->i_mtime = inode->i_ctime;
96 inode->i_atime = inode->i_mtime;
97 switch (mode & S_IFMT) {
98 default:
99 init_special_inode(inode, mode, dev);
100 if (S_ISBLK(mode))
101 inode->i_fop = &wrapped_def_blk_fops;
102 else if (S_ISCHR(mode))
103 inode->i_fop = &wrapped_def_chr_fops;
104 inode->i_op = &syaoran_file_inode_operations;
105 break;
106 case S_IFREG:
107 inode->i_op = &syaoran_file_inode_operations;
108 inode->i_fop = &syaoran_file_operations;
109 break;
110 case S_IFDIR:
111 inode->i_op = &syaoran_dir_inode_operations;
112 inode->i_fop = &simple_dir_operations;
113 /*
114 * directory inodes start off with i_nlink == 2
115 * (for "." entry)
116 */
117 inode->i_nlink++;
118 break;
119 case S_IFLNK:
120 inode->i_op = &syaoran_symlink_inode_operations;
121 break;
122 }
123 }
124 return inode;
125 }
126
127 /*
128 * File creation. Allocate an inode, and we're done..
129 */
130 /* SMP-safe */
131 static int syaoran_mknod(struct inode *dir, struct dentry *dentry, int mode,
132 dev_t dev)
133 {
134 struct inode *inode;
135 int error = -ENOSPC;
136 if (syaoran_may_create_node(dentry, mode, dev) < 0)
137 return -EPERM;
138 inode = syaoran_get_inode(dir->i_sb, mode, dev);
139 if (inode) {
140 if (dir->i_mode & S_ISGID) {
141 inode->i_gid = dir->i_gid;
142 if (S_ISDIR(mode))
143 inode->i_mode |= S_ISGID;
144 }
145 d_instantiate(dentry, inode);
146 dget(dentry); /* Extra count - pin the dentry in core */
147 error = 0;
148 }
149 return error;
150 }
151
152 static int syaoran_mkdir(struct inode *dir, struct dentry *dentry, int mode)
153 {
154 int retval = syaoran_mknod(dir, dentry, mode | S_IFDIR, 0);
155 if (!retval)
156 dir->i_nlink++;
157 return retval;
158 }
159
160 static int syaoran_create(struct inode *dir, struct dentry *dentry, int mode,
161 struct nameidata *nd)
162 {
163 return syaoran_mknod(dir, dentry, mode | S_IFREG, 0);
164 }
165
166 static int syaoran_symlink(struct inode *dir, struct dentry *dentry,
167 const char *symname)
168 {
169 struct inode *inode;
170 int error = -ENOSPC;
171 if (syaoran_may_create_node(dentry, S_IFLNK, 0) < 0)
172 return -EPERM;
173 inode = syaoran_get_inode(dir->i_sb, S_IFLNK|S_IRWXUGO, 0);
174 if (inode) {
175 int l = strlen(symname)+1;
176 error = page_symlink(inode, symname, l);
177 if (!error) {
178 if (dir->i_mode & S_ISGID)
179 inode->i_gid = dir->i_gid;
180 d_instantiate(dentry, inode);
181 dget(dentry);
182 } else
183 iput(inode);
184 }
185 return error;
186 }
187
188 static int syaoran_link(struct dentry *old_dentry, struct inode *dir,
189 struct dentry *dentry)
190 {
191 struct inode *inode = old_dentry->d_inode;
192 if (!inode || syaoran_may_create_node(dentry, inode->i_mode,
193 inode->i_rdev) < 0)
194 return -EPERM;
195 return simple_link(old_dentry, dir, dentry);
196 }
197
198 static int syaoran_unlink(struct inode *dir, struct dentry *dentry)
199 {
200 if (syaoran_may_modify_node(dentry, MAY_DELETE) < 0)
201 return -EPERM;
202 return simple_unlink(dir, dentry);
203 }
204
205 static int syaoran_rename(struct inode *old_dir, struct dentry *old_dentry,
206 struct inode *new_dir, struct dentry *new_dentry)
207 {
208 struct inode *inode = old_dentry->d_inode;
209 if (!inode || syaoran_may_modify_node(old_dentry, MAY_DELETE) < 0 ||
210 syaoran_may_create_node(new_dentry, inode->i_mode,
211 inode->i_rdev) < 0)
212 return -EPERM;
213 return simple_rename(old_dir, old_dentry, new_dir, new_dentry);
214 }
215
216 static int syaoran_rmdir(struct inode *dir, struct dentry *dentry)
217 {
218 if (syaoran_may_modify_node(dentry, MAY_DELETE) < 0)
219 return -EPERM;
220 return simple_rmdir(dir, dentry);
221 }
222
223 static int syaoran_setattr(struct dentry *dentry, struct iattr *attr)
224 {
225 struct inode *inode = dentry->d_inode;
226 int error = inode_change_ok(inode, attr);
227 if (!error) {
228 unsigned int ia_valid = attr->ia_valid;
229 unsigned int flags = 0;
230 if (ia_valid & (ATTR_UID | ATTR_GID))
231 flags |= MAY_CHOWN;
232 if (ia_valid & ATTR_MODE)
233 flags |= MAY_CHMOD;
234 if (syaoran_may_modify_node(dentry, flags) < 0)
235 return -EPERM;
236 if (!error)
237 error = inode_setattr(inode, attr);
238 }
239 return error;
240 }
241
242 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
243 static struct address_space_operations syaoran_aops = {
244 .readpage = simple_readpage,
245 .prepare_write = simple_prepare_write,
246 .commit_write = simple_commit_write
247 };
248 #else
249 static int syaoran_set_page_dirty_no_writeback(struct page *page)
250 {
251 if (!PageDirty(page))
252 SetPageDirty(page);
253 return 0;
254 }
255 static struct address_space_operations syaoran_aops = {
256 .readpage = simple_readpage,
257 .write_begin = simple_write_begin,
258 .write_end = simple_write_end,
259 .set_page_dirty = syaoran_set_page_dirty_no_writeback,
260 };
261 #endif
262
263 static struct file_operations syaoran_file_operations = {
264 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
265 .read = generic_file_read,
266 .write = generic_file_write,
267 #else
268 .aio_read = generic_file_aio_read,
269 .read = do_sync_read,
270 .aio_write = generic_file_aio_write,
271 .write = do_sync_write,
272 #endif
273 .mmap = generic_file_mmap,
274 .fsync = simple_sync_file,
275 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
276 .sendfile = generic_file_sendfile,
277 #else
278 .splice_read = generic_file_splice_read,
279 #endif
280 .llseek = generic_file_llseek,
281 };
282
283 static struct inode_operations syaoran_file_inode_operations = {
284 .getattr = simple_getattr,
285 .setattr = syaoran_setattr,
286 };
287
288 static struct inode_operations syaoran_dir_inode_operations = {
289 .create = syaoran_create,
290 .lookup = simple_lookup,
291 .link = syaoran_link,
292 .unlink = syaoran_unlink,
293 .symlink = syaoran_symlink,
294 .mkdir = syaoran_mkdir,
295 .rmdir = syaoran_rmdir,
296 .mknod = syaoran_mknod,
297 .rename = syaoran_rename,
298 .setattr = syaoran_setattr,
299 };
300
301 static struct inode_operations syaoran_symlink_inode_operations = {
302 .readlink = generic_readlink,
303 .follow_link = page_follow_link_light,
304 .put_link = page_put_link,
305 .setattr = syaoran_setattr,
306 };
307
308 static struct super_operations syaoran_ops = {
309 .statfs = simple_statfs,
310 .drop_inode = generic_delete_inode,
311 .put_super = syaoran_put_super,
312 };
313
314 static int syaoran_fill_super(struct super_block *sb, void *data, int silent)
315 {
316 struct inode *inode;
317 struct dentry *root;
318
319 sb->s_maxbytes = MAX_LFS_FILESIZE;
320 sb->s_blocksize = PAGE_CACHE_SIZE;
321 sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
322 sb->s_magic = SYAORAN_MAGIC;
323 sb->s_op = &syaoran_ops;
324 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 9)
325 sb->s_time_gran = 1;
326 #endif
327 {
328 int error = syaoran_initialize(sb, data);
329 if (error < 0)
330 return error;
331 }
332 inode = syaoran_get_inode(sb, S_IFDIR | 0755, 0);
333 if (!inode)
334 return -ENOMEM;
335
336 root = d_alloc_root(inode);
337 if (!root) {
338 iput(inode);
339 return -ENOMEM;
340 }
341 sb->s_root = root;
342 syaoran_make_initial_nodes(sb);
343 return 0;
344 }
345
346 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)
347 static struct super_block *syaoran_get_sb(struct file_system_type *fs_type,
348 int flags, const char *dev_name,
349 void *data)
350 {
351 return get_sb_nodev(fs_type, flags, data, syaoran_fill_super);
352 }
353 #else
354 static int syaoran_get_sb(struct file_system_type *fs_type,
355 int flags, const char *dev_name, void *data,
356 struct vfsmount *mnt)
357 {
358 return get_sb_nodev(fs_type, flags, data, syaoran_fill_super, mnt);
359 }
360 #endif
361
362 static struct file_system_type syaoran_fs_type = {
363 .owner = THIS_MODULE,
364 .name = "syaoran",
365 .get_sb = syaoran_get_sb,
366 .kill_sb = kill_litter_super,
367 };
368
369 static int __init init_syaoran_fs(void)
370 {
371 return register_filesystem(&syaoran_fs_type);
372 }
373
374 static void __exit exit_syaoran_fs(void)
375 {
376 unregister_filesystem(&syaoran_fs_type);
377 }
378
379 module_init(init_syaoran_fs);
380 module_exit(exit_syaoran_fs);
381
382 MODULE_LICENSE("GPL");

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26