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