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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 776 - (show annotations) (download) (as text)
Wed Dec 5 05:29:11 2007 UTC (16 years, 5 months ago) by kumaneko
Original Path: trunk/1.5.x/ccs-patch/fs/syaoran_2.6.c
File MIME type: text/x-csrc
File size: 9777 byte(s)


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

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