Skip to content

Commit 63f729c

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs fix from Al Viro: "Don't put symlink bodies in pagecache into highmem" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: Make sure that highmem pages are not added to symlink page cache
2 parents 10a0c0f + e8ecde2 commit 63f729c

File tree

3 files changed

+8
-5
lines changed

3 files changed

+8
-5
lines changed

Documentation/filesystems/porting

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,11 @@ in your dentry operations instead.
508508
[mandatory]
509509
any symlink that might use page_follow_link_light/page_put_link() must
510510
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.
512516
--
513517
[mandatory]
514518
->follow_link() is replaced with ->get_link(); same API, except that

fs/nfs/dir.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1894,15 +1894,14 @@ int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
18941894
attr.ia_mode = S_IFLNK | S_IRWXUGO;
18951895
attr.ia_valid = ATTR_MODE;
18961896

1897-
page = alloc_page(GFP_HIGHUSER);
1897+
page = alloc_page(GFP_USER);
18981898
if (!page)
18991899
return -ENOMEM;
19001900

1901-
kaddr = kmap_atomic(page);
1901+
kaddr = page_address(page);
19021902
memcpy(kaddr, symname, pathlen);
19031903
if (pathlen < PAGE_SIZE)
19041904
memset(kaddr + pathlen, 0, PAGE_SIZE - pathlen);
1905-
kunmap_atomic(kaddr);
19061905

19071906
trace_nfs_symlink_enter(dir, dentry);
19081907
error = NFS_PROTO(dir)->symlink(dir, dentry, page, pathlen, &attr);

mm/shmem.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2469,14 +2469,14 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s
24692469
inode->i_op = &shmem_short_symlink_operations;
24702470
inode->i_link = info->symlink;
24712471
} else {
2472+
inode_nohighmem(inode);
24722473
error = shmem_getpage(inode, 0, &page, SGP_WRITE, NULL);
24732474
if (error) {
24742475
iput(inode);
24752476
return error;
24762477
}
24772478
inode->i_mapping->a_ops = &shmem_aops;
24782479
inode->i_op = &shmem_symlink_inode_operations;
2479-
inode_nohighmem(inode);
24802480
memcpy(page_address(page), symname, len);
24812481
SetPageUptodate(page);
24822482
set_page_dirty(page);

0 commit comments

Comments
 (0)