Messages in this thread Patch in this message | | | Date | Fri, 18 Oct 2002 00:47:32 +0100 (BST) | From | Hugh Dickins <> | Subject | [PATCH] tmpfs 1/9 shmem_getpage unlock_page |
| |
First of nine tmpfs patches based on 2.5.43, hoping for inclusion in 2.5.43-mm then on to mainline. The main change is in 8/9, enabling loopable tmpfs. 9/9 instates Ingo's shmem_populate above the rest.
Documentation/devices.txt | 2 Documentation/filesystems/tmpfs.txt | 17 include/asm-sparc64/page.h | 1 include/linux/fs.h | 1 include/linux/highmem.h | 11 mm/filemap.c | 2 mm/shmem.c | 683 ++++++++++++++++++++---------------- 7 files changed, 410 insertions(+), 307 deletions(-)
[PATCH] tmpfs 1/9 shmem_getpage unlock_page
shmem_getpage does need to lock its page (to secure it against shmem_writepage), but it's easier for its callers if it unlocks before returning. The only caller who appeared to be using the page lock was shmem_file_write, but it wasn't actually protecting against anything - i_sem prevents concurrent writes and truncates, and do_shmem_file_read was dropping the lock before copying anyway.
--- 2.5.43/mm/shmem.c Sat Oct 12 08:26:10 2002 +++ tmpfs1/mm/shmem.c Thu Oct 17 22:00:49 2002 @@ -737,6 +737,7 @@ repeat: page = find_lock_page(mapping, idx); if (page) { + unlock_page(page); *pagep = page; return 0; } @@ -852,6 +853,7 @@ } /* We have the page */ + unlock_page(page); *pagep = page; return 0; } @@ -879,8 +881,7 @@ } spin_unlock(&info->lock); if (swap.val) { - if (shmem_getpage(inode, idx, &page) == 0) - unlock_page(page); + (void) shmem_getpage(inode, idx, &page); } return page; } @@ -903,7 +904,6 @@ if (error) return (error == -ENOMEM)? NOPAGE_OOM: NOPAGE_SIGBUS; - unlock_page(page); flush_page_to_ram(page); return page; } @@ -1101,15 +1101,9 @@ } /* - * Bring in the user page that we will copy from _first_. - * Otherwise there's a nasty deadlock on copying from the - * same page as we're writing to, without it being marked - * up-to-date. + * We don't hold page lock across copy from user - + * what would it guard against? - so no deadlock here. */ - { volatile unsigned char dummy; - __get_user(dummy, buf); - __get_user(dummy, buf+bytes-1); - } status = shmem_getpage(inode, index, &page); if (status) @@ -1131,9 +1125,7 @@ if (pos > inode->i_size) inode->i_size = pos; } -unlock: - /* Mark it unlocked again and drop the page.. */ - unlock_page(page); +release: page_cache_release(page); if (status < 0) @@ -1152,7 +1144,7 @@ fail_write: status = -EFAULT; ClearPageUptodate(page); - goto unlock; + goto release; } static void do_shmem_file_read(struct file *filp, loff_t *ppos, read_descriptor_t *desc) @@ -1194,12 +1186,10 @@ if (index == end_index) { nr = inode->i_size & ~PAGE_CACHE_MASK; if (nr <= offset) { - unlock_page(page); page_cache_release(page); break; } } - unlock_page(page); nr -= offset; if (!list_empty(&mapping->i_mmap_shared)) @@ -1443,7 +1433,6 @@ memcpy(kaddr, symname, len); kunmap(page); set_page_dirty(page); - unlock_page(page); page_cache_release(page); } dir->i_size += BOGO_DIRENT_SIZE; @@ -1471,7 +1460,6 @@ return res; res = vfs_readlink(dentry, buffer, buflen, kmap(page)); kunmap(page); - unlock_page(page); page_cache_release(page); return res; } @@ -1484,7 +1472,6 @@ return res; res = vfs_follow_link(nd, kmap(page)); kunmap(page); - unlock_page(page); page_cache_release(page); return res; } - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |