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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1507 - (show annotations) (download) (as text)
Tue Sep 2 06:45:13 2008 UTC (15 years, 9 months ago) by kumaneko
File MIME type: text/x-csrc
File size: 9962 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.5.5 2008/09/03
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 | BDI_CAP_EXEC_MAP,
71 #endif
72 };
73
74 #include <linux/syaoran.h>
75
76 static struct inode *syaoran_get_inode(struct super_block *sb, int mode, dev_t dev)
77 {
78 struct inode * inode = new_inode(sb);
79
80 if (inode) {
81 inode->i_mode = mode;
82 inode->i_uid = current->fsuid;
83 inode->i_gid = current->fsgid;
84 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
85 #if !defined(RHEL_MAJOR) || RHEL_MAJOR != 5
86 inode->i_blksize = PAGE_CACHE_SIZE;
87 #endif
88 #endif
89 inode->i_blocks = 0;
90 inode->i_mapping->a_ops = &syaoran_aops;
91 inode->i_mapping->backing_dev_info = &syaoran_backing_dev_info;
92 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
93 switch (mode & S_IFMT) {
94 default:
95 init_special_inode(inode, mode, dev);
96 if (S_ISBLK(mode)) inode->i_fop = &wrapped_def_blk_fops;
97 else if (S_ISCHR(mode)) inode->i_fop = &wrapped_def_chr_fops;
98 inode->i_op = &syaoran_file_inode_operations;
99 break;
100 case S_IFREG:
101 inode->i_op = &syaoran_file_inode_operations;
102 inode->i_fop = &syaoran_file_operations;
103 break;
104 case S_IFDIR:
105 inode->i_op = &syaoran_dir_inode_operations;
106 inode->i_fop = &simple_dir_operations;
107
108 /* directory inodes start off with i_nlink == 2 (for "." entry) */
109 inode->i_nlink++;
110 break;
111 case S_IFLNK:
112 inode->i_op = &syaoran_symlink_inode_operations;
113 break;
114 }
115 }
116 return inode;
117 }
118
119 /*
120 * File creation. Allocate an inode, and we're done..
121 */
122 /* SMP-safe */
123 static int syaoran_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
124 {
125 struct inode * inode;
126 int error = -ENOSPC;
127 if (MayCreateNode(dentry, mode, dev) < 0) return -EPERM;
128 inode = syaoran_get_inode(dir->i_sb, mode, dev);
129 if (inode) {
130 if (dir->i_mode & S_ISGID) {
131 inode->i_gid = dir->i_gid;
132 if (S_ISDIR(mode))
133 inode->i_mode |= S_ISGID;
134 }
135 d_instantiate(dentry, inode);
136 dget(dentry); /* Extra count - pin the dentry in core */
137 error = 0;
138 }
139 return error;
140 }
141
142 static int syaoran_mkdir(struct inode * dir, struct dentry * dentry, int mode)
143 {
144 int retval = syaoran_mknod(dir, dentry, mode | S_IFDIR, 0);
145 if (!retval)
146 dir->i_nlink++;
147 return retval;
148 }
149
150 static int syaoran_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd)
151 {
152 return syaoran_mknod(dir, dentry, mode | S_IFREG, 0);
153 }
154
155 static int syaoran_symlink(struct inode * dir, struct dentry *dentry, const char * symname)
156 {
157 struct inode *inode;
158 int error = -ENOSPC;
159 if (MayCreateNode(dentry, S_IFLNK, 0) < 0) return -EPERM;
160 inode = syaoran_get_inode(dir->i_sb, S_IFLNK|S_IRWXUGO, 0);
161 if (inode) {
162 int l = strlen(symname)+1;
163 error = page_symlink(inode, symname, l);
164 if (!error) {
165 if (dir->i_mode & S_ISGID)
166 inode->i_gid = dir->i_gid;
167 d_instantiate(dentry, inode);
168 dget(dentry);
169 } else
170 iput(inode);
171 }
172 return error;
173 }
174
175 static int syaoran_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
176 {
177 struct inode *inode = old_dentry->d_inode;
178 if (!inode || MayCreateNode(dentry, inode->i_mode, inode->i_rdev) < 0) return -EPERM;
179 return simple_link(old_dentry, dir, dentry);
180 }
181
182 static int syaoran_unlink(struct inode * dir, struct dentry *dentry)
183 {
184 if (MayModifyNode(dentry, MAY_DELETE) < 0) return -EPERM;
185 return simple_unlink(dir, dentry);
186 }
187
188 static int syaoran_rename(struct inode * old_dir, struct dentry *old_dentry, struct inode * new_dir,struct dentry *new_dentry)
189 {
190 struct inode *inode = old_dentry->d_inode;
191 if (!inode || MayModifyNode(old_dentry, MAY_DELETE) < 0 || MayCreateNode(new_dentry, inode->i_mode, inode->i_rdev) < 0) return -EPERM;
192 return simple_rename(old_dir, old_dentry, new_dir, new_dentry);
193 }
194
195 static int syaoran_rmdir(struct inode *dir, struct dentry *dentry)
196 {
197 if (MayModifyNode(dentry, MAY_DELETE) < 0) return -EPERM;
198 return simple_rmdir(dir, dentry);
199 }
200
201 static int syaoran_setattr(struct dentry * dentry, struct iattr * attr)
202 {
203 struct inode *inode = dentry->d_inode;
204 int error = inode_change_ok(inode, attr);
205 if (!error) {
206 unsigned int ia_valid = attr->ia_valid;
207 unsigned int flags = 0;
208 if (ia_valid & (ATTR_UID | ATTR_GID)) flags |= MAY_CHOWN;
209 if (ia_valid & ATTR_MODE) flags |= MAY_CHMOD;
210 if (MayModifyNode(dentry, flags) < 0) return -EPERM;
211 if (!error) error = inode_setattr(inode, attr);
212 }
213 return error;
214 }
215
216 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
217 static struct address_space_operations syaoran_aops = {
218 .readpage = simple_readpage,
219 .prepare_write = simple_prepare_write,
220 .commit_write = simple_commit_write
221 };
222 #else
223 static int syaoran_set_page_dirty_no_writeback(struct page *page)
224 {
225 if (!PageDirty(page))
226 SetPageDirty(page);
227 return 0;
228 }
229 static struct address_space_operations syaoran_aops = {
230 .readpage = simple_readpage,
231 .write_begin = simple_write_begin,
232 .write_end = simple_write_end,
233 .set_page_dirty = syaoran_set_page_dirty_no_writeback,
234 };
235 #endif
236
237 static struct file_operations syaoran_file_operations = {
238 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
239 .read = generic_file_read,
240 .write = generic_file_write,
241 #else
242 .aio_read = generic_file_aio_read,
243 .read = do_sync_read,
244 .aio_write = generic_file_aio_write,
245 .write = do_sync_write,
246 #endif
247 .mmap = generic_file_mmap,
248 .fsync = simple_sync_file,
249 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
250 .sendfile = generic_file_sendfile,
251 #else
252 .splice_read = generic_file_splice_read,
253 #endif
254 .llseek = generic_file_llseek,
255 };
256
257 static struct inode_operations syaoran_file_inode_operations = {
258 .getattr = simple_getattr,
259 .setattr = syaoran_setattr,
260 };
261
262 static struct inode_operations syaoran_dir_inode_operations = {
263 .create = syaoran_create,
264 .lookup = simple_lookup,
265 .link = syaoran_link,
266 .unlink = syaoran_unlink,
267 .symlink = syaoran_symlink,
268 .mkdir = syaoran_mkdir,
269 .rmdir = syaoran_rmdir,
270 .mknod = syaoran_mknod,
271 .rename = syaoran_rename,
272 .setattr = syaoran_setattr,
273 };
274
275 static struct inode_operations syaoran_symlink_inode_operations = {
276 .readlink = generic_readlink,
277 .follow_link = page_follow_link_light,
278 .put_link = page_put_link,
279 .setattr = syaoran_setattr,
280 };
281
282 static struct super_operations syaoran_ops = {
283 .statfs = simple_statfs,
284 .drop_inode = generic_delete_inode,
285 .put_super = syaoran_put_super,
286 };
287
288 static int syaoran_fill_super(struct super_block * sb, void * data, int silent)
289 {
290 struct inode * inode;
291 struct dentry * root;
292
293 sb->s_maxbytes = MAX_LFS_FILESIZE;
294 sb->s_blocksize = PAGE_CACHE_SIZE;
295 sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
296 sb->s_magic = SYAORAN_MAGIC;
297 sb->s_op = &syaoran_ops;
298 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 9)
299 sb->s_time_gran = 1;
300 #endif
301 {
302 int error;
303 if ((error = Syaoran_Initialize(sb, data)) < 0) return error;
304 }
305 inode = syaoran_get_inode(sb, S_IFDIR | 0755, 0);
306 if (!inode)
307 return -ENOMEM;
308
309 root = d_alloc_root(inode);
310 if (!root) {
311 iput(inode);
312 return -ENOMEM;
313 }
314 sb->s_root = root;
315 MakeInitialNodes(sb);
316 return 0;
317 }
318
319 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)
320 static struct super_block *syaoran_get_sb(struct file_system_type *fs_type,
321 int flags, const char *dev_name, void *data)
322 {
323 return get_sb_nodev(fs_type, flags, data, syaoran_fill_super);
324 }
325 #else
326 static int syaoran_get_sb(struct file_system_type *fs_type,
327 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
328 {
329 return get_sb_nodev(fs_type, flags, data, syaoran_fill_super, mnt);
330 }
331 #endif
332
333 static struct file_system_type syaoran_fs_type = {
334 .owner = THIS_MODULE,
335 .name = "syaoran",
336 .get_sb = syaoran_get_sb,
337 .kill_sb = kill_litter_super,
338 };
339
340 static int __init init_syaoran_fs(void)
341 {
342 return register_filesystem(&syaoran_fs_type);
343 }
344
345 static void __exit exit_syaoran_fs(void)
346 {
347 unregister_filesystem(&syaoran_fs_type);
348 }
349
350 module_init(init_syaoran_fs);
351 module_exit(exit_syaoran_fs);
352
353 MODULE_LICENSE("GPL");

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