[PATCH] tmpfs 1/9 shmem_getpage unlock_page

From: Hugh Dickins (hugh@veritas.com)
Date: Thu Oct 17 2002 - 18:47:32 EST


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/



This archive was generated by hypermail 2b29 : Wed Oct 23 2002 - 22:00:38 EST