shmem.c (44835d20b2a0c9b4c0c3fb96e90f4e2fd4a4e41d) shmem.c (41139aa4c3a31ee7e072fc63353c74035aade2ff)
1/*
2 * Resizable virtual memory filesystem for Linux.
3 *
4 * Copyright (C) 2000 Linus Torvalds.
5 * 2000 Transmeta Corp.
6 * 2000-2001 Christoph Rohland
7 * 2000-2001 SAP AG
8 * 2002 Red Hat Inc.

--- 2654 unchanged lines hidden (view full) ---

2663 cond_resched();
2664 }
2665
2666 *ppos = ((loff_t) index << PAGE_SHIFT) + offset;
2667 file_accessed(file);
2668 return retval ? retval : error;
2669}
2670
1/*
2 * Resizable virtual memory filesystem for Linux.
3 *
4 * Copyright (C) 2000 Linus Torvalds.
5 * 2000 Transmeta Corp.
6 * 2000-2001 Christoph Rohland
7 * 2000-2001 SAP AG
8 * 2002 Red Hat Inc.

--- 2654 unchanged lines hidden (view full) ---

2663 cond_resched();
2664 }
2665
2666 *ppos = ((loff_t) index << PAGE_SHIFT) + offset;
2667 file_accessed(file);
2668 return retval ? retval : error;
2669}
2670
2671/*
2672 * llseek SEEK_DATA or SEEK_HOLE through the page cache.
2673 */
2674static pgoff_t shmem_seek_hole_data(struct address_space *mapping,
2675 pgoff_t index, pgoff_t end, int whence)
2676{
2677 struct page *page;
2678 struct pagevec pvec;
2679 pgoff_t indices[PAGEVEC_SIZE];
2680 bool done = false;
2681 int i;
2682
2683 pagevec_init(&pvec);
2684 pvec.nr = 1; /* start small: we may be there already */
2685 while (!done) {
2686 pvec.nr = find_get_entries(mapping, index,
2687 pvec.nr, pvec.pages, indices);
2688 if (!pvec.nr) {
2689 if (whence == SEEK_DATA)
2690 index = end;
2691 break;
2692 }
2693 for (i = 0; i < pvec.nr; i++, index++) {
2694 if (index < indices[i]) {
2695 if (whence == SEEK_HOLE) {
2696 done = true;
2697 break;
2698 }
2699 index = indices[i];
2700 }
2701 page = pvec.pages[i];
2702 if (page && !xa_is_value(page)) {
2703 if (!PageUptodate(page))
2704 page = NULL;
2705 }
2706 if (index >= end ||
2707 (page && whence == SEEK_DATA) ||
2708 (!page && whence == SEEK_HOLE)) {
2709 done = true;
2710 break;
2711 }
2712 }
2713 pagevec_remove_exceptionals(&pvec);
2714 pagevec_release(&pvec);
2715 pvec.nr = PAGEVEC_SIZE;
2716 cond_resched();
2717 }
2718 return index;
2719}
2720
2721static loff_t shmem_file_llseek(struct file *file, loff_t offset, int whence)
2722{
2723 struct address_space *mapping = file->f_mapping;
2724 struct inode *inode = mapping->host;
2671static loff_t shmem_file_llseek(struct file *file, loff_t offset, int whence)
2672{
2673 struct address_space *mapping = file->f_mapping;
2674 struct inode *inode = mapping->host;
2725 pgoff_t start, end;
2726 loff_t new_offset;
2727
2728 if (whence != SEEK_DATA && whence != SEEK_HOLE)
2729 return generic_file_llseek_size(file, offset, whence,
2730 MAX_LFS_FILESIZE, i_size_read(inode));
2675
2676 if (whence != SEEK_DATA && whence != SEEK_HOLE)
2677 return generic_file_llseek_size(file, offset, whence,
2678 MAX_LFS_FILESIZE, i_size_read(inode));
2679 if (offset < 0)
2680 return -ENXIO;
2681
2731 inode_lock(inode);
2732 /* We're holding i_mutex so we can access i_size directly */
2682 inode_lock(inode);
2683 /* We're holding i_mutex so we can access i_size directly */
2733
2734 if (offset < 0 || offset >= inode->i_size)
2735 offset = -ENXIO;
2736 else {
2737 start = offset >> PAGE_SHIFT;
2738 end = (inode->i_size + PAGE_SIZE - 1) >> PAGE_SHIFT;
2739 new_offset = shmem_seek_hole_data(mapping, start, end, whence);
2740 new_offset <<= PAGE_SHIFT;
2741 if (new_offset > offset) {
2742 if (new_offset < inode->i_size)
2743 offset = new_offset;
2744 else if (whence == SEEK_DATA)
2745 offset = -ENXIO;
2746 else
2747 offset = inode->i_size;
2748 }
2749 }
2750
2684 offset = mapping_seek_hole_data(mapping, offset, inode->i_size, whence);
2751 if (offset >= 0)
2752 offset = vfs_setpos(file, offset, MAX_LFS_FILESIZE);
2753 inode_unlock(inode);
2754 return offset;
2755}
2756
2757static long shmem_fallocate(struct file *file, int mode, loff_t offset,
2758 loff_t len)

--- 1575 unchanged lines hidden ---
2685 if (offset >= 0)
2686 offset = vfs_setpos(file, offset, MAX_LFS_FILESIZE);
2687 inode_unlock(inode);
2688 return offset;
2689}
2690
2691static long shmem_fallocate(struct file *file, int mode, loff_t offset,
2692 loff_t len)

--- 1575 unchanged lines hidden ---