1 /*
2 * Resizable simple shmem filesystem for Linux.
3 *
4 * Copyright (C) 2000 Linus Torvalds.
5 * 2000 Transmeta Corp.
6 * 2000 Christoph Rohland
7 *
8 * This file is released under the GPL.
9 */
10
11 /*
12 * This shared memory handling is heavily based on the ramfs. It
13 * extends the ramfs by the ability to use swap which would makes it a
14 * completely usable filesystem.
15 *
16 * But read and write are not supported (yet)
17 *
18 */
19
20 #include <linux/module.h>
21 #include <linux/init.h>
22 #include <linux/devfs_fs_kernel.h>
23 #include <linux/fs.h>
24 #include <linux/mm.h>
25 #include <linux/file.h>
26 #include <linux/swap.h>
27 #include <linux/pagemap.h>
28 #include <linux/string.h>
29 #include <linux/locks.h>
30 #include <asm/smplock.h>
31
32 #include <asm/uaccess.h>
33
34 #define SHMEM_MAGIC 0x01021994
35
36 #define ENTRIES_PER_PAGE (PAGE_SIZE/sizeof(unsigned long))
37 #define NR_SINGLE (ENTRIES_PER_PAGE + SHMEM_NR_DIRECT)
38
39 static struct super_operations shmem_ops;
40 static struct address_space_operations shmem_aops;
41 static struct file_operations shmem_file_operations;
42 static struct inode_operations shmem_inode_operations;
43 static struct file_operations shmem_dir_operations;
44 static struct inode_operations shmem_dir_inode_operations;
45 static struct vm_operations_struct shmem_shared_vm_ops;
46 static struct vm_operations_struct shmem_private_vm_ops;
47
48 LIST_HEAD (shmem_inodes);
49 static spinlock_t shmem_ilock = SPIN_LOCK_UNLOCKED;
50
51 static swp_entry_t * shmem_swp_entry (struct shmem_inode_info *info, unsigned long index)
52 {
53 if (index < SHMEM_NR_DIRECT)
54 return info->i_direct+index;
55
56 index -= SHMEM_NR_DIRECT;
57 if (index >= ENTRIES_PER_PAGE*ENTRIES_PER_PAGE)
58 return NULL;
59
60 if (!info->i_indirect) {
61 info->i_indirect = (swp_entry_t **) get_zeroed_page(GFP_USER);
62 if (!info->i_indirect)
63 return NULL;
64 }
65 if(!(info->i_indirect[index/ENTRIES_PER_PAGE])) {
66 info->i_indirect[index/ENTRIES_PER_PAGE] = (swp_entry_t *) get_zeroed_page(GFP_USER);
67 if (!info->i_indirect[index/ENTRIES_PER_PAGE])
68 return NULL;
69 }
70
71 return info->i_indirect[index/ENTRIES_PER_PAGE]+index%ENTRIES_PER_PAGE;
72 }
73
74 static int shmem_free_swp(swp_entry_t *dir, unsigned int count)
75 {
76 swp_entry_t *ptr, entry;
77 struct page * page;
78 int freed = 0;
79
80 for (ptr = dir; ptr < dir + count; ptr++) {
81 if (!ptr->val)
82 continue;
83 entry = *ptr;
84 swap_free (entry);
85 *ptr = (swp_entry_t){0};
86 freed++;
87 if (!(page = lookup_swap_cache(entry)))
88 continue;
89 delete_from_swap_cache(page);
90 page_cache_release(page);
91 }
92 return freed;
93 }
94
95 /*
96 * shmem_truncate_part - free a bunch of swap entries
97 *
98 * @dir: pointer to swp_entries
99 * @size: number of entries in dir
100 * @start: offset to start from
101 * @inode: inode for statistics
102 * @freed: counter for freed pages
103 *
104 * It frees the swap entries from dir+start til dir+size
105 *
106 * returns 0 if it truncated something, else (offset-size)
107 */
108
109 static unsigned long
110 shmem_truncate_part (swp_entry_t * dir, unsigned long size,
111 unsigned long start, struct inode * inode, unsigned long *freed) {
112 if (start > size)
113 return start - size;
114 if (dir)
115 *freed += shmem_free_swp (dir+start, size-start);
116
117 return 0;
118 }
119
120 /*
121 * shmem_recalc_inode - recalculate the size of an inode
122 *
123 * @inode: inode to recalc
124 *
125 * We have to calculate the free blocks since the mm can drop pages
126 * behind our back
127 *
128 * But we know that normally
129 * inodes->i_blocks == inode->i_mapping->nrpages + info->swapped
130 *
131 * So the mm freed
132 * inodes->i_blocks - (inode->i_mapping->nrpages + info->swapped)
133 *
134 * It has to be called with the spinlock held.
135 */
136
137 static void shmem_recalc_inode(struct inode * inode)
138 {
139 unsigned long freed;
140
141 freed = inode->i_blocks -
142 (inode->i_mapping->nrpages + inode->u.shmem_i.swapped);
143 if (freed){
144 struct shmem_sb_info * info = &inode->i_sb->u.shmem_sb;
145 inode->i_blocks -= freed;
146 spin_lock (&info->stat_lock);
147 info->free_blocks += freed;
148 spin_unlock (&info->stat_lock);
149 }
150 }
151
152 static void shmem_truncate (struct inode * inode)
153 {
154 int clear_base;
155 unsigned long start;
156 unsigned long freed = 0;
157 swp_entry_t **base, **ptr;
158 struct shmem_inode_info * info = &inode->u.shmem_i;
159
160 spin_lock (&info->lock);
161 start = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
162
163 start = shmem_truncate_part (info->i_direct, SHMEM_NR_DIRECT, start, inode, &freed);
164
165 if (!(base = info->i_indirect))
166 goto out;;
167
168 clear_base = 1;
169 for (ptr = base; ptr < base + ENTRIES_PER_PAGE; ptr++) {
170 if (!start) {
171 if (!*ptr)
172 continue;
173 freed += shmem_free_swp (*ptr, ENTRIES_PER_PAGE);
174 free_page ((unsigned long) *ptr);
175 *ptr = 0;
176 continue;
177 }
178 clear_base = 0;
179 start = shmem_truncate_part (*ptr, ENTRIES_PER_PAGE, start, inode, &freed);
180 }
181
182 if (!clear_base)
183 goto out;
184
185 free_page ((unsigned long)base);
186 info->i_indirect = 0;
187
188 out:
189 info->swapped -= freed;
190 shmem_recalc_inode(inode);
191 spin_unlock (&info->lock);
192 }
193
194 static void shmem_delete_inode(struct inode * inode)
195 {
196 struct shmem_sb_info *info = &inode->i_sb->u.shmem_sb;
197
198 spin_lock (&shmem_ilock);
199 list_del (&inode->u.shmem_i.list);
200 spin_unlock (&shmem_ilock);
201 inode->i_size = 0;
202 shmem_truncate (inode);
203 spin_lock (&info->stat_lock);
204 info->free_inodes++;
205 spin_unlock (&info->stat_lock);
206 clear_inode(inode);
207 }
208
209 /*
210 * Move the page from the page cache to the swap cache
211 */
212 static int shmem_writepage(struct page * page)
213 {
214 int error;
215 struct shmem_inode_info *info;
216 swp_entry_t *entry, swap;
217
218 info = &page->mapping->host->u.shmem_i;
219 swap = __get_swap_page(2);
220 if (!swap.val) {
221 set_page_dirty(page);
222 UnlockPage(page);
223 return -ENOMEM;
224 }
225
226 spin_lock(&info->lock);
227 shmem_recalc_inode(page->mapping->host);
228 entry = shmem_swp_entry (info, page->index);
229 if (!entry) /* this had been allocted on page allocation */
230 BUG();
231 error = -EAGAIN;
232 if (entry->val) {
233 __swap_free(swap, 2);
234 goto out;
235 }
236
237 *entry = swap;
238 error = 0;
239 /* Remove the from the page cache */
240 lru_cache_del(page);
241 remove_inode_page(page);
242
243 /* Add it to the swap cache */
244 add_to_swap_cache(page, swap);
245 page_cache_release(page);
246 set_page_dirty(page);
247 info->swapped++;
248 out:
249 spin_unlock(&info->lock);
250 UnlockPage(page);
251 return error;
252 }
253
254 /*
255 * shmem_nopage - either get the page from swap or allocate a new one
256 *
257 * If we allocate a new one we do not mark it dirty. That's up to the
258 * vm. If we swap it in we mark it dirty since we also free the swap
259 * entry since a page cannot live in both the swap and page cache
260 */
261 struct page * shmem_nopage(struct vm_area_struct * vma, unsigned long address, int no_share)
262 {
263 unsigned long size;
264 struct page * page;
265 unsigned int idx;
266 swp_entry_t *entry;
267 struct inode * inode = vma->vm_file->f_dentry->d_inode;
268 struct address_space * mapping = inode->i_mapping;
269 struct shmem_inode_info *info;
270
271 idx = (address - vma->vm_start) >> PAGE_SHIFT;
272 idx += vma->vm_pgoff;
273
274 down (&inode->i_sem);
275 size = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
276 page = NOPAGE_SIGBUS;
277 if ((idx >= size) && (vma->vm_mm == current->mm))
278 goto out;
279
280 /* retry, we may have slept */
281 page = __find_lock_page(mapping, idx, page_hash (mapping, idx));
282 if (page)
283 goto cached_page;
284
285 info = &inode->u.shmem_i;
286 entry = shmem_swp_entry (info, idx);
287 if (!entry)
288 goto oom;
289 spin_lock (&info->lock);
290 shmem_recalc_inode(inode);
291 spin_unlock (&info->lock);
292 if (entry->val) {
293 unsigned long flags;
294
295 /* Look it up and read it in.. */
296 page = lookup_swap_cache(*entry);
297 if (!page) {
298 lock_kernel();
299 swapin_readahead(*entry);
300 page = read_swap_cache(*entry);
301 unlock_kernel();
302 if (!page)
303 goto oom;
304 }
305
306 /* We have to this with page locked to prevent races */
307 spin_lock (&info->lock);
308 swap_free(*entry);
309 lock_page(page);
310 delete_from_swap_cache_nolock(page);
311 *entry = (swp_entry_t) {0};
312 flags = page->flags & ~((1 << PG_uptodate) | (1 << PG_error) | (1 << PG_referenced) | (1 << PG_arch_1));
313 page->flags = flags | (1 << PG_dirty);
314 add_to_page_cache_locked(page, mapping, idx);
315 info->swapped--;
316 spin_unlock (&info->lock);
317 } else {
318 spin_lock (&inode->i_sb->u.shmem_sb.stat_lock);
319 if (inode->i_sb->u.shmem_sb.free_blocks == 0)
320 goto no_space;
321 inode->i_sb->u.shmem_sb.free_blocks--;
322 spin_unlock (&inode->i_sb->u.shmem_sb.stat_lock);
323 /* Ok, get a new page */
324 page = page_cache_alloc();
325 if (!page)
326 goto oom;
327 clear_user_highpage(page, address);
328 inode->i_blocks++;
329 add_to_page_cache (page, mapping, idx);
330 }
331 /* We have the page */
332 SetPageUptodate (page);
333 if (info->locked)
334 page_cache_get(page);
335
336 cached_page:
337 UnlockPage (page);
338 up(&inode->i_sem);
339
340 if (no_share) {
341 struct page *new_page = page_cache_alloc();
342
343 if (new_page) {
344 copy_user_highpage(new_page, page, address);
345 flush_page_to_ram(new_page);
346 } else
347 new_page = NOPAGE_OOM;
348 page_cache_release(page);
349 return new_page;
350 }
351
352 flush_page_to_ram (page);
353 return(page);
354 no_space:
355 spin_unlock (&inode->i_sb->u.shmem_sb.stat_lock);
356 oom:
357 page = NOPAGE_OOM;
358 out:
359 up(&inode->i_sem);
360 return page;
361 }
362
363 struct inode *shmem_get_inode(struct super_block *sb, int mode, int dev)
364 {
365 struct inode * inode;
366
367 spin_lock (&sb->u.shmem_sb.stat_lock);
368 if (!sb->u.shmem_sb.free_inodes) {
369 spin_unlock (&sb->u.shmem_sb.stat_lock);
370 return NULL;
371 }
372 sb->u.shmem_sb.free_inodes--;
373 spin_unlock (&sb->u.shmem_sb.stat_lock);
374
375 inode = new_inode(sb);
376 if (inode) {
377 inode->i_mode = mode;
378 inode->i_uid = current->fsuid;
379 inode->i_gid = current->fsgid;
380 inode->i_blksize = PAGE_CACHE_SIZE;
381 inode->i_blocks = 0;
382 inode->i_rdev = to_kdev_t(dev);
383 inode->i_mapping->a_ops = &shmem_aops;
384 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
385 spin_lock_init (&inode->u.shmem_i.lock);
386 switch (mode & S_IFMT) {
387 default:
388 init_special_inode(inode, mode, dev);
389 break;
390 case S_IFREG:
391 inode->i_op = &shmem_inode_operations;
392 inode->i_fop = &shmem_file_operations;
393 break;
394 case S_IFDIR:
395 inode->i_op = &shmem_dir_inode_operations;
396 inode->i_fop = &shmem_dir_operations;
397 break;
398 case S_IFLNK:
399 BUG();
400 }
401 spin_lock (&shmem_ilock);
402 list_add (&inode->u.shmem_i.list, &shmem_inodes);
403 spin_unlock (&shmem_ilock);
404 }
405 return inode;
406 }
407
408 static int shmem_statfs(struct super_block *sb, struct statfs *buf)
409 {
410 buf->f_type = SHMEM_MAGIC;
411 buf->f_bsize = PAGE_CACHE_SIZE;
412 spin_lock (&sb->u.shmem_sb.stat_lock);
413 if (sb->u.shmem_sb.max_blocks != ULONG_MAX ||
414 sb->u.shmem_sb.max_inodes != ULONG_MAX) {
415 buf->f_blocks = sb->u.shmem_sb.max_blocks;
416 buf->f_bavail = buf->f_bfree = sb->u.shmem_sb.free_blocks;
417 buf->f_files = sb->u.shmem_sb.max_inodes;
418 buf->f_ffree = sb->u.shmem_sb.free_inodes;
419 }
420 spin_unlock (&sb->u.shmem_sb.stat_lock);
421 buf->f_namelen = 255;
422 return 0;
423 }
424
425 void shmem_lock(struct file * file, int lock)
426 {
427 struct inode * inode = file->f_dentry->d_inode;
428 struct shmem_inode_info * info = &inode->u.shmem_i;
429 struct page * page;
430 unsigned long idx, size;
431
432 if (info->locked == lock)
433 return;
434 down(&inode->i_sem);
435 info->locked = lock;
436 size = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
437 for (idx = 0; idx < size; idx++) {
438 page = find_lock_page(inode->i_mapping, idx);
439 if (!page)
440 continue;
441 if (!lock) {
442 /* release the extra count and our reference */
443 page_cache_release(page);
444 page_cache_release(page);
445 }
446 UnlockPage(page);
447 }
448 up(&inode->i_sem);
449 }
450
451 /*
452 * Lookup the data. This is trivial - if the dentry didn't already
453 * exist, we know it is negative.
454 */
455 static struct dentry * shmem_lookup(struct inode *dir, struct dentry *dentry)
456 {
457 d_add(dentry, NULL);
458 return NULL;
459 }
460
461 /*
462 * File creation. Allocate an inode, and we're done..
463 */
464 static int shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, int dev)
465 {
466 struct inode * inode = shmem_get_inode(dir->i_sb, mode, dev);
467 int error = -ENOSPC;
468
469 if (inode) {
470 d_instantiate(dentry, inode);
471 dget(dentry); /* Extra count - pin the dentry in core */
472 error = 0;
473 }
474 return error;
475 }
476
477 static int shmem_mkdir(struct inode * dir, struct dentry * dentry, int mode)
478 {
479 return shmem_mknod(dir, dentry, mode | S_IFDIR, 0);
480 }
481
482 static int shmem_create(struct inode *dir, struct dentry *dentry, int mode)
483 {
484 return shmem_mknod(dir, dentry, mode | S_IFREG, 0);
485 }
486
487 /*
488 * Link a file..
489 */
490 static int shmem_link(struct dentry *old_dentry, struct inode * dir, struct dentry * dentry)
491 {
492 struct inode *inode = old_dentry->d_inode;
493
494 if (S_ISDIR(inode->i_mode))
495 return -EPERM;
496
497 inode->i_nlink++;
498 atomic_inc(&inode->i_count); /* New dentry reference */
499 dget(dentry); /* Extra pinning count for the created dentry */
500 d_instantiate(dentry, inode);
501 return 0;
502 }
503
504 static inline int shmem_positive(struct dentry *dentry)
505 {
506 return dentry->d_inode && !d_unhashed(dentry);
507 }
508
509 /*
510 * Check that a directory is empty (this works
511 * for regular files too, they'll just always be
512 * considered empty..).
513 *
514 * Note that an empty directory can still have
515 * children, they just all have to be negative..
516 */
517 static int shmem_empty(struct dentry *dentry)
518 {
519 struct list_head *list;
520
521 spin_lock(&dcache_lock);
522 list = dentry->d_subdirs.next;
523
524 while (list != &dentry->d_subdirs) {
525 struct dentry *de = list_entry(list, struct dentry, d_child);
526
527 if (shmem_positive(de)) {
528 spin_unlock(&dcache_lock);
529 return 0;
530 }
531 list = list->next;
532 }
533 spin_unlock(&dcache_lock);
534 return 1;
535 }
536
537 /*
538 * This works for both directories and regular files.
539 * (non-directories will always have empty subdirs)
540 */
541 static int shmem_unlink(struct inode * dir, struct dentry *dentry)
542 {
543 int retval = -ENOTEMPTY;
544
545 if (shmem_empty(dentry)) {
546 struct inode *inode = dentry->d_inode;
547
548 inode->i_nlink--;
549 dput(dentry); /* Undo the count from "create" - this does all the work */
550 retval = 0;
551 }
552 return retval;
553 }
554
555 #define shmem_rmdir shmem_unlink
556
557 /*
558 * The VFS layer already does all the dentry stuff for rename,
559 * we just have to decrement the usage count for the target if
560 * it exists so that the VFS layer correctly free's it when it
561 * gets overwritten.
562 */
563 static int shmem_rename(struct inode * old_dir, struct dentry *old_dentry, struct inode * new_dir,struct dentry *new_dentry)
564 {
565 int error = -ENOTEMPTY;
566
567 if (shmem_empty(new_dentry)) {
568 struct inode *inode = new_dentry->d_inode;
569 if (inode) {
570 inode->i_nlink--;
571 dput(new_dentry);
572 }
573 error = 0;
574 }
575 return error;
576 }
577
578 static int shmem_mmap(struct file * file, struct vm_area_struct * vma)
579 {
580 struct vm_operations_struct * ops;
581 struct inode *inode = file->f_dentry->d_inode;
582
583 ops = &shmem_private_vm_ops;
584 if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_MAYWRITE))
585 ops = &shmem_shared_vm_ops;
586 if (!inode->i_sb || !S_ISREG(inode->i_mode))
587 return -EACCES;
588 UPDATE_ATIME(inode);
589 vma->vm_ops = ops;
590 return 0;
591 }
592
593 static int shmem_parse_options(char *options, int *mode, unsigned long * blocks, unsigned long *inodes)
594 {
595 char *this_char, *value;
596
597 this_char = NULL;
598 if ( options )
599 this_char = strtok(options,",");
600 for ( ; this_char; this_char = strtok(NULL,",")) {
601 if ((value = strchr(this_char,'=')) != NULL)
602 *value++ = 0;
603 if (!strcmp(this_char,"nr_blocks")) {
604 if (!value || !*value || !blocks)
605 return 1;
606 *blocks = simple_strtoul(value,&value,0);
607 if (*value)
608 return 1;
609 } else if (!strcmp(this_char,"nr_inodes")) {
610 if (!value || !*value || !inodes)
611 return 1;
612 *inodes = simple_strtoul(value,&value,0);
613 if (*value)
614 return 1;
615 } else if (!strcmp(this_char,"mode")) {
616 if (!value || !*value || !mode)
617 return 1;
618 *mode = simple_strtoul(value,&value,8);
619 if (*value)
620 return 1;
621 }
622 else
623 return 1;
624 }
625
626 return 0;
627 }
628
629 static struct super_block *shmem_read_super(struct super_block * sb, void * data, int silent)
630 {
631 struct inode * inode;
632 struct dentry * root;
633 unsigned long blocks = ULONG_MAX; /* unlimited */
634 unsigned long inodes = ULONG_MAX; /* unlimited */
635 int mode = S_IRWXUGO | S_ISVTX;
636
637 if (shmem_parse_options (data, &mode, &blocks, &inodes)) {
638 printk(KERN_ERR "shmem fs invalid option\n");
639 return NULL;
640 }
641
642 spin_lock_init (&sb->u.shmem_sb.stat_lock);
643 sb->u.shmem_sb.max_blocks = blocks;
644 sb->u.shmem_sb.free_blocks = blocks;
645 sb->u.shmem_sb.max_inodes = inodes;
646 sb->u.shmem_sb.free_inodes = inodes;
647 sb->s_blocksize = PAGE_CACHE_SIZE;
648 sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
649 sb->s_magic = SHMEM_MAGIC;
650 sb->s_op = &shmem_ops;
651 inode = shmem_get_inode(sb, S_IFDIR | mode, 0);
652 if (!inode)
653 return NULL;
654
655 root = d_alloc_root(inode);
656 if (!root) {
657 iput(inode);
658 return NULL;
659 }
660 sb->s_root = root;
661 return sb;
662 }
663
664 static int shmem_remount_fs (struct super_block *sb, int *flags, char *data)
665 {
666 int error;
667 unsigned long max_blocks, blocks;
668 unsigned long max_inodes, inodes;
669 struct shmem_sb_info *info = &sb->u.shmem_sb;
670
671 if (shmem_parse_options (data, NULL, &max_blocks, &max_inodes))
672 return -EINVAL;
673
674 spin_lock(&info->stat_lock);
675 blocks = info->max_blocks - info->free_blocks;
676 inodes = info->max_inodes - info->free_inodes;
677 error = -EINVAL;
678 if (max_blocks < blocks)
679 goto out;
680 if (max_inodes < inodes)
681 goto out;
682 error = 0;
683 info->max_blocks = max_blocks;
684 info->free_blocks = max_blocks - blocks;
685 info->max_inodes = max_inodes;
686 info->free_inodes = max_inodes - inodes;
687 out:
688 spin_unlock(&info->stat_lock);
689 return error;
690 }
691
692 static struct address_space_operations shmem_aops = {
693 writepage: shmem_writepage
694 };
695
696 static struct file_operations shmem_file_operations = {
697 mmap: shmem_mmap
698 };
699
700 static struct inode_operations shmem_inode_operations = {
701 truncate: shmem_truncate,
702 };
703
704 static struct file_operations shmem_dir_operations = {
705 read: generic_read_dir,
706 readdir: dcache_readdir,
707 };
708
709 static struct inode_operations shmem_dir_inode_operations = {
710 create: shmem_create,
711 lookup: shmem_lookup,
712 link: shmem_link,
713 unlink: shmem_unlink,
714 mkdir: shmem_mkdir,
715 rmdir: shmem_rmdir,
716 mknod: shmem_mknod,
717 rename: shmem_rename,
718 };
719
720 static struct super_operations shmem_ops = {
721 statfs: shmem_statfs,
722 remount_fs: shmem_remount_fs,
723 delete_inode: shmem_delete_inode,
724 put_inode: force_delete,
725 };
726
727 static struct vm_operations_struct shmem_private_vm_ops = {
728 nopage: shmem_nopage,
729 };
730
731 static struct vm_operations_struct shmem_shared_vm_ops = {
732 nopage: shmem_nopage,
733 };
734
735 static DECLARE_FSTYPE(shmem_fs_type, "shm", shmem_read_super, FS_LITTER);
736
737 static int __init init_shmem_fs(void)
738 {
739 int error;
740 struct vfsmount * res;
741
742 if ((error = register_filesystem(&shmem_fs_type))) {
743 printk (KERN_ERR "Could not register shmem fs\n");
744 return error;
745 }
746
747 res = kern_mount(&shmem_fs_type);
748 if (IS_ERR (res)) {
749 printk (KERN_ERR "could not kern_mount shmem fs\n");
750 unregister_filesystem(&shmem_fs_type);
751 return PTR_ERR(res);
752 }
753
754 devfs_mk_dir (NULL, "shm", NULL);
755 return 0;
756 }
757
758 static void __exit exit_shmem_fs(void)
759 {
760 unregister_filesystem(&shmem_fs_type);
761 }
762
763 module_init(init_shmem_fs)
764 module_exit(exit_shmem_fs)
765
766 static int shmem_clear_swp (swp_entry_t entry, swp_entry_t *ptr, int size) {
767 swp_entry_t *test;
768
769 for (test = ptr; test < ptr + size; test++) {
770 if (test->val == entry.val) {
771 swap_free (entry);
772 *test = (swp_entry_t) {0};
773 return test - ptr;
774 }
775 }
776 return -1;
777 }
778
779 static int shmem_unuse_inode (struct inode *inode, swp_entry_t entry, struct page *page)
780 {
781 swp_entry_t **base, **ptr;
782 unsigned long idx;
783 int offset;
784 struct shmem_inode_info *info = &inode->u.shmem_i;
785
786 idx = 0;
787 spin_lock (&info->lock);
788 if ((offset = shmem_clear_swp (entry,info->i_direct, SHMEM_NR_DIRECT)) >= 0)
789 goto found;
790
791 idx = SHMEM_NR_DIRECT;
792 if (!(base = info->i_indirect))
793 goto out;
794
795 for (ptr = base; ptr < base + ENTRIES_PER_PAGE; ptr++) {
796 if (*ptr &&
797 (offset = shmem_clear_swp (entry, *ptr, ENTRIES_PER_PAGE)) >= 0)
798 goto found;
799 idx += ENTRIES_PER_PAGE;
800 }
801 out:
802 spin_unlock (&info->lock);
803 return 0;
804 found:
805 add_to_page_cache(page, inode->i_mapping, offset + idx);
806 set_page_dirty(page);
807 SetPageUptodate(page);
808 UnlockPage(page);
809 info->swapped--;
810 spin_unlock(&info->lock);
811 return 1;
812 }
813
814 /*
815 * unuse_shmem() search for an eventually swapped out shmem page.
816 */
817 void shmem_unuse(swp_entry_t entry, struct page *page)
818 {
819 struct list_head *p;
820 struct inode * inode;
821
822 spin_lock (&shmem_ilock);
823 list_for_each(p, &shmem_inodes) {
824 inode = list_entry(p, struct inode, u.shmem_i.list);
825
826 if (shmem_unuse_inode(inode, entry, page))
827 break;
828 }
829 spin_unlock (&shmem_ilock);
830 }
831
832
833 /*
834 * shmem_file_setup - get an unlinked file living in shmem fs
835 *
836 * @name: name for dentry (to be seen in /proc/<pid>/maps
837 * @size: size to be set for the file
838 *
839 */
840 struct file *shmem_file_setup(char * name, loff_t size)
841 {
842 int error;
843 struct file *file;
844 struct inode * inode;
845 struct dentry *dentry, *root;
846 struct qstr this;
847 int vm_enough_memory(long pages);
848
849 error = -ENOMEM;
850 if (!vm_enough_memory((size) >> PAGE_SHIFT))
851 goto out;
852
853 this.name = name;
854 this.len = strlen(name);
855 this.hash = 0; /* will go */
856 root = shmem_fs_type.kern_mnt->mnt_root;
857 dentry = d_alloc(root, &this);
858 if (!dentry)
859 goto out;
860
861 error = -ENFILE;
862 file = get_empty_filp();
863 if (!file)
864 goto put_dentry;
865
866 error = -ENOSPC;
867 inode = shmem_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0);
868 if (!inode)
869 goto close_file;
870
871 d_instantiate(dentry, inode);
872 dentry->d_inode->i_size = size;
873 file->f_vfsmnt = mntget(shmem_fs_type.kern_mnt);
874 file->f_dentry = dentry;
875 file->f_op = &shmem_file_operations;
876 file->f_mode = FMODE_WRITE | FMODE_READ;
877 inode->i_nlink = 0; /* It is unlinked */
878 return(file);
879
880 close_file:
881 put_filp(file);
882 put_dentry:
883 dput (dentry);
884 out:
885 return ERR_PTR(error);
886 }
887 /*
888 * shmem_zero_setup - setup a shared anonymous mapping
889 *
890 * @vma: the vma to be mmapped is prepared by do_mmap_pgoff
891 */
892 int shmem_zero_setup(struct vm_area_struct *vma)
893 {
894 struct file *file;
895 loff_t size = vma->vm_end - vma->vm_start;
896
897 file = shmem_file_setup("dev/zero", size);
898 if (IS_ERR(file))
899 return PTR_ERR(file);
900
901 if (vma->vm_file)
902 fput (vma->vm_file);
903 vma->vm_file = file;
904 vma->vm_ops = &shmem_shared_vm_ops;
905 return 0;
906 }
907
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.