diff options
-rw-r--r-- | Documentation/filesystems/porting | 6 | ||||
-rw-r--r-- | fs/nfs/dir.c | 5 | ||||
-rw-r--r-- | mm/shmem.c | 2 |
3 files changed, 8 insertions, 5 deletions
diff --git a/Documentation/filesystems/porting b/Documentation/filesystems/porting index 0f88e6020487..f1b87d8aa2da 100644 --- a/Documentation/filesystems/porting +++ b/Documentation/filesystems/porting | |||
@@ -508,7 +508,11 @@ in your dentry operations instead. | |||
508 | [mandatory] | 508 | [mandatory] |
509 | any symlink that might use page_follow_link_light/page_put_link() must | 509 | any symlink that might use page_follow_link_light/page_put_link() must |
510 | have inode_nohighmem(inode) called before anything might start playing with | 510 | have inode_nohighmem(inode) called before anything might start playing with |
511 | its pagecache. | 511 | its pagecache. No highmem pages should end up in the pagecache of such |
512 | symlinks. That includes any preseeding that might be done during symlink | ||
513 | creation. __page_symlink() will honour the mapping gfp flags, so once | ||
514 | you've done inode_nohighmem() it's safe to use, but if you allocate and | ||
515 | insert the page manually, make sure to use the right gfp flags. | ||
512 | -- | 516 | -- |
513 | [mandatory] | 517 | [mandatory] |
514 | ->follow_link() is replaced with ->get_link(); same API, except that | 518 | ->follow_link() is replaced with ->get_link(); same API, except that |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index ce5a21861074..8a0530921685 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -1894,15 +1894,14 @@ int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) | |||
1894 | attr.ia_mode = S_IFLNK | S_IRWXUGO; | 1894 | attr.ia_mode = S_IFLNK | S_IRWXUGO; |
1895 | attr.ia_valid = ATTR_MODE; | 1895 | attr.ia_valid = ATTR_MODE; |
1896 | 1896 | ||
1897 | page = alloc_page(GFP_HIGHUSER); | 1897 | page = alloc_page(GFP_USER); |
1898 | if (!page) | 1898 | if (!page) |
1899 | return -ENOMEM; | 1899 | return -ENOMEM; |
1900 | 1900 | ||
1901 | kaddr = kmap_atomic(page); | 1901 | kaddr = page_address(page); |
1902 | memcpy(kaddr, symname, pathlen); | 1902 | memcpy(kaddr, symname, pathlen); |
1903 | if (pathlen < PAGE_SIZE) | 1903 | if (pathlen < PAGE_SIZE) |
1904 | memset(kaddr + pathlen, 0, PAGE_SIZE - pathlen); | 1904 | memset(kaddr + pathlen, 0, PAGE_SIZE - pathlen); |
1905 | kunmap_atomic(kaddr); | ||
1906 | 1905 | ||
1907 | trace_nfs_symlink_enter(dir, dentry); | 1906 | trace_nfs_symlink_enter(dir, dentry); |
1908 | error = NFS_PROTO(dir)->symlink(dir, dentry, page, pathlen, &attr); | 1907 | error = NFS_PROTO(dir)->symlink(dir, dentry, page, pathlen, &attr); |
diff --git a/mm/shmem.c b/mm/shmem.c index 5813b7fa85b6..642471b0ddea 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
@@ -2469,6 +2469,7 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s | |||
2469 | inode->i_op = &shmem_short_symlink_operations; | 2469 | inode->i_op = &shmem_short_symlink_operations; |
2470 | inode->i_link = info->symlink; | 2470 | inode->i_link = info->symlink; |
2471 | } else { | 2471 | } else { |
2472 | inode_nohighmem(inode); | ||
2472 | error = shmem_getpage(inode, 0, &page, SGP_WRITE, NULL); | 2473 | error = shmem_getpage(inode, 0, &page, SGP_WRITE, NULL); |
2473 | if (error) { | 2474 | if (error) { |
2474 | iput(inode); | 2475 | iput(inode); |
@@ -2476,7 +2477,6 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s | |||
2476 | } | 2477 | } |
2477 | inode->i_mapping->a_ops = &shmem_aops; | 2478 | inode->i_mapping->a_ops = &shmem_aops; |
2478 | inode->i_op = &shmem_symlink_inode_operations; | 2479 | inode->i_op = &shmem_symlink_inode_operations; |
2479 | inode_nohighmem(inode); | ||
2480 | memcpy(page_address(page), symname, len); | 2480 | memcpy(page_address(page), symname, len); |
2481 | SetPageUptodate(page); | 2481 | SetPageUptodate(page); |
2482 | set_page_dirty(page); | 2482 | set_page_dirty(page); |