diff --git a/Documentation/filesystems/porting b/Documentation/filesystems/porting index f24d1b8339576e96c46045f5da8f275ee9250056..3eb7c35c9698d01adadc4d2cf337c249341f7ea6 100644 --- a/Documentation/filesystems/porting +++ b/Documentation/filesystems/porting @@ -504,3 +504,8 @@ in your dentry operations instead. [mandatory] __fd_install() & fd_install() can now sleep. Callers should not hold a spinlock or other resources that do not allow a schedule. +-- +[mandatory] + any symlink that might use page_follow_link_light/page_put_link() must + have inode_nohighmem(inode) called before anything might start playing with + its pagecache. diff --git a/fs/affs/inode.c b/fs/affs/inode.c index 17349500592d55b8b0a9a087809301c05995c696..0fdb0f5b2239df24b69363a7449a7a7ff360003c 100644 --- a/fs/affs/inode.c +++ b/fs/affs/inode.c @@ -140,6 +140,7 @@ struct inode *affs_iget(struct super_block *sb, unsigned long ino) break; case ST_SOFTLINK: inode->i_mode |= S_IFLNK; + inode_nohighmem(inode); inode->i_op = &affs_symlink_inode_operations; inode->i_data.a_ops = &affs_symlink_aops; break; diff --git a/fs/affs/namei.c b/fs/affs/namei.c index 181e05b46e7261d32ab9390daf7007b017af1e84..00d3002a6780b339cf456417b742bf5c9f991ec8 100644 --- a/fs/affs/namei.c +++ b/fs/affs/namei.c @@ -344,6 +344,7 @@ affs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) return -ENOSPC; inode->i_op = &affs_symlink_inode_operations; + inode_nohighmem(inode); inode->i_data.a_ops = &affs_symlink_aops; inode->i_mode = S_IFLNK | 0777; mode_to_prot(inode); diff --git a/fs/affs/symlink.c b/fs/affs/symlink.c index ea5b69a18ba9ce9165d8ea083bfffbb40e13a600..e3f9dc3ae8cc91890dcec2e21dbbd77ab4017c89 100644 --- a/fs/affs/symlink.c +++ b/fs/affs/symlink.c @@ -14,7 +14,7 @@ static int affs_symlink_readpage(struct file *file, struct page *page) { struct buffer_head *bh; struct inode *inode = page->mapping->host; - char *link = kmap(page); + char *link = page_address(page); struct slink_front *lf; int i, j; char c; @@ -57,12 +57,10 @@ static int affs_symlink_readpage(struct file *file, struct page *page) link[i] = '\0'; affs_brelse(bh); SetPageUptodate(page); - kunmap(page); unlock_page(page); return 0; fail: SetPageError(page); - kunmap(page); unlock_page(page); return -EIO; } diff --git a/fs/afs/inode.c b/fs/afs/inode.c index e06f5a23352ac65415f8bcb54450af2620588e95..86cc7264c21cda727a3bb71e73af9a7ddc35eec5 100644 --- a/fs/afs/inode.c +++ b/fs/afs/inode.c @@ -56,6 +56,7 @@ static int afs_inode_map_status(struct afs_vnode *vnode, struct key *key) case AFS_FTYPE_SYMLINK: inode->i_mode = S_IFLNK | vnode->status.mode; inode->i_op = &page_symlink_inode_operations; + inode_nohighmem(inode); break; default: printk("kAFS: AFS vnode with undefined type\n"); diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c index 1c8b0dca8b506e8add384d66a7c70e6699370e78..25250fa87086316a95d8877935d810cd8d305196 100644 --- a/fs/befs/linuxvfs.c +++ b/fs/befs/linuxvfs.c @@ -397,6 +397,7 @@ static struct inode *befs_iget(struct super_block *sb, unsigned long ino) } else if (S_ISLNK(inode->i_mode)) { if (befs_ino->i_flags & BEFS_LONG_SYMLINK) { inode->i_op = &page_symlink_inode_operations; + inode_nohighmem(inode); inode->i_mapping->a_ops = &befs_symlink_aops; } else { inode->i_link = befs_ino->i_data.symlink; @@ -469,7 +470,7 @@ static int befs_symlink_readpage(struct file *unused, struct page *page) struct befs_inode_info *befs_ino = BEFS_I(inode); befs_data_stream *data = &befs_ino->i_data.ds; befs_off_t len = data->size; - char *link = kmap(page); + char *link = page_address(page); if (len == 0 || len > PAGE_SIZE) { befs_error(sb, "Long symlink with illegal length"); @@ -483,12 +484,10 @@ static int befs_symlink_readpage(struct file *unused, struct page *page) } link[len - 1] = '\0'; SetPageUptodate(page); - kunmap(page); unlock_page(page); return 0; fail: SetPageError(page); - kunmap(page); unlock_page(page); return -EIO; } diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index a70c5790f8f5908f08f606d097fe33e6966af36b..70f98bfde27757e50b20433a402b12f852a18f6e 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -3774,6 +3774,7 @@ static void btrfs_read_locked_inode(struct inode *inode) break; case S_IFLNK: inode->i_op = &btrfs_symlink_inode_operations; + inode_nohighmem(inode); inode->i_mapping->a_ops = &btrfs_symlink_aops; break; default: @@ -9705,6 +9706,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, btrfs_free_path(path); inode->i_op = &btrfs_symlink_inode_operations; + inode_nohighmem(inode); inode->i_mapping->a_ops = &btrfs_symlink_aops; inode_set_bytes(inode, name_len); btrfs_i_size_write(inode, name_len); diff --git a/fs/coda/cnode.c b/fs/coda/cnode.c index 7740b1c871c183ea55994e84812273effa58a476..dd6a79ef47509c875b1457c70f3d690a112ae707 100644 --- a/fs/coda/cnode.c +++ b/fs/coda/cnode.c @@ -8,6 +8,7 @@ #include #include +#include #include "coda_linux.h" static inline int coda_fideq(struct CodaFid *fid1, struct CodaFid *fid2) @@ -35,6 +36,7 @@ static void coda_fill_inode(struct inode *inode, struct coda_vattr *attr) inode->i_fop = &coda_dir_operations; } else if (S_ISLNK(inode->i_mode)) { inode->i_op = &coda_symlink_inode_operations; + inode_nohighmem(inode); inode->i_data.a_ops = &coda_symlink_aops; inode->i_mapping = &inode->i_data; } else diff --git a/fs/coda/symlink.c b/fs/coda/symlink.c index ab94ef63caefed0767e8f2cccf6364038ca94825..03736e20d72076cec96eb0c57aa0c9bf8f901e59 100644 --- a/fs/coda/symlink.c +++ b/fs/coda/symlink.c @@ -26,7 +26,7 @@ static int coda_symlink_filler(struct file *file, struct page *page) int error; struct coda_inode_info *cii; unsigned int len = PAGE_SIZE; - char *p = kmap(page); + char *p = page_address(page); cii = ITOC(inode); @@ -34,13 +34,11 @@ static int coda_symlink_filler(struct file *file, struct page *page) if (error) goto fail; SetPageUptodate(page); - kunmap(page); unlock_page(page); return 0; fail: SetPageError(page); - kunmap(page); unlock_page(page); return error; } diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c index 355c522f3585a5e3a7667225681383ff85b93a48..b862bc219cd7c7d269a7ba9e786559d1595315d7 100644 --- a/fs/cramfs/inode.c +++ b/fs/cramfs/inode.c @@ -100,6 +100,7 @@ static struct inode *get_cramfs_inode(struct super_block *sb, break; case S_IFLNK: inode->i_op = &page_symlink_inode_operations; + inode_nohighmem(inode); inode->i_data.a_ops = &cramfs_aops; break; default: diff --git a/fs/efs/inode.c b/fs/efs/inode.c index 079d20306ee18990f09943c7eff4f9548cf9d761..cdf0872382afa3e4755d5276fa1588be03d272a1 100644 --- a/fs/efs/inode.c +++ b/fs/efs/inode.c @@ -151,6 +151,7 @@ struct inode *efs_iget(struct super_block *super, unsigned long ino) break; case S_IFLNK: inode->i_op = &page_symlink_inode_operations; + inode_nohighmem(inode); inode->i_data.a_ops = &efs_symlink_aops; break; case S_IFCHR: diff --git a/fs/efs/symlink.c b/fs/efs/symlink.c index 75117d0dac2b174f5b231234b1543cecd95bdbfa..4870cc82deb014be3e28a5f55704ecedfb3b0c91 100644 --- a/fs/efs/symlink.c +++ b/fs/efs/symlink.c @@ -13,7 +13,7 @@ static int efs_symlink_readpage(struct file *file, struct page *page) { - char *link = kmap(page); + char *link = page_address(page); struct buffer_head * bh; struct inode * inode = page->mapping->host; efs_block_t size = inode->i_size; @@ -39,12 +39,10 @@ static int efs_symlink_readpage(struct file *file, struct page *page) } link[size] = '\0'; SetPageUptodate(page); - kunmap(page); unlock_page(page); return 0; fail: SetPageError(page); - kunmap(page); unlock_page(page); return err; } diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c index 73c64daa0f5517b4ff8271bd17e25740bb83d506..d8e9c18171a99496915ecf4ad59c307653d0a0c3 100644 --- a/fs/exofs/inode.c +++ b/fs/exofs/inode.c @@ -1227,6 +1227,7 @@ struct inode *exofs_iget(struct super_block *sb, unsigned long ino) inode->i_link = (char *)oi->i_data; } else { inode->i_op = &page_symlink_inode_operations; + inode_nohighmem(inode); inode->i_mapping->a_ops = &exofs_aops; } } else { diff --git a/fs/exofs/namei.c b/fs/exofs/namei.c index 994e078da4bb746fd8c088f70efbfaa19a4665a3..c20d77df2679abb185e29a79f5ceab8349204d65 100644 --- a/fs/exofs/namei.c +++ b/fs/exofs/namei.c @@ -111,6 +111,7 @@ static int exofs_symlink(struct inode *dir, struct dentry *dentry, if (l > sizeof(oi->i_data)) { /* slow symlink */ inode->i_op = &page_symlink_inode_operations; + inode_nohighmem(inode); inode->i_mapping->a_ops = &exofs_aops; memset(oi->i_data, 0, sizeof(oi->i_data)); diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index 0aa9bf6e6e53e2d1ac14d26917d6afa1b6fae233..338eefda70c6fc4e2055c0165b590febf1295acb 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c @@ -1420,6 +1420,7 @@ struct inode *ext2_iget (struct super_block *sb, unsigned long ino) sizeof(ei->i_data) - 1); } else { inode->i_op = &ext2_symlink_inode_operations; + inode_nohighmem(inode); if (test_opt(inode->i_sb, NOBH)) inode->i_mapping->a_ops = &ext2_nobh_aops; else diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index 3267a80dbbe26f4fbefb14c82fdb832d9169d6a8..7a2be8f7f3c37a69135cab528b1244e51c5fc2a2 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c @@ -183,6 +183,7 @@ static int ext2_symlink (struct inode * dir, struct dentry * dentry, if (l > sizeof (EXT2_I(inode)->i_data)) { /* slow symlink */ inode->i_op = &ext2_symlink_inode_operations; + inode_nohighmem(inode); if (test_opt(inode->i_sb, NOBH)) inode->i_mapping->a_ops = &ext2_nobh_aops; else diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index ea433a7f4bca21511ba84fbfbe52f71883680661..b3bd912df6bfaf475f9304eba7fb1b9ce6368e87 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -4283,6 +4283,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino) inode->i_op = &ext4_symlink_inode_operations; ext4_set_aops(inode); } + inode_nohighmem(inode); } else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { inode->i_op = &ext4_special_inode_operations; diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index a969ab39f3026187242dbea0881d5ebdb991d978..f27e0c2598c59edb5685c27310c2766d0860838d 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -3132,6 +3132,7 @@ static int ext4_symlink(struct inode *dir, if ((disk_link.len > EXT4_N_BLOCKS * 4)) { if (!encryption_required) inode->i_op = &ext4_symlink_inode_operations; + inode_nohighmem(inode); ext4_set_aops(inode); /* * We cannot call page_symlink() with transaction started diff --git a/fs/ext4/symlink.c b/fs/ext4/symlink.c index abe2401ce405669f0d315319f5275a9fc321c697..0e6dc44c5ebf1b4dbad3c9a498b11a1b14c5fc4b 100644 --- a/fs/ext4/symlink.c +++ b/fs/ext4/symlink.c @@ -45,7 +45,7 @@ static const char *ext4_encrypted_follow_link(struct dentry *dentry, void **cook cpage = read_mapping_page(inode->i_mapping, 0, NULL); if (IS_ERR(cpage)) return ERR_CAST(cpage); - caddr = kmap(cpage); + caddr = page_address(cpage); caddr[size] = 0; } @@ -75,16 +75,12 @@ static const char *ext4_encrypted_follow_link(struct dentry *dentry, void **cook /* Null-terminate the name */ if (res <= plen) paddr[res] = '\0'; - if (cpage) { - kunmap(cpage); + if (cpage) page_cache_release(cpage); - } return *cookie = paddr; errout: - if (cpage) { - kunmap(cpage); + if (cpage) page_cache_release(cpage); - } kfree(paddr); return ERR_PTR(res); } diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index 97e20decacb4e17677fc3c43cfb5d45a6ab290bc..5528801a5baf3a13a75ffd16c831c1d7b1a650f4 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -202,6 +202,7 @@ struct inode *f2fs_iget(struct super_block *sb, unsigned long ino) inode->i_op = &f2fs_encrypted_symlink_inode_operations; else inode->i_op = &f2fs_symlink_inode_operations; + inode_nohighmem(inode); inode->i_mapping->a_ops = &f2fs_dblock_aops; } else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index 2c32110f9fc082408b318cac2142602ab7888a9e..484df6850747c82314155652474001060b0f4517 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c @@ -351,6 +351,7 @@ static int f2fs_symlink(struct inode *dir, struct dentry *dentry, inode->i_op = &f2fs_encrypted_symlink_inode_operations; else inode->i_op = &f2fs_symlink_inode_operations; + inode_nohighmem(inode); inode->i_mapping->a_ops = &f2fs_dblock_aops; f2fs_lock_op(sbi); @@ -942,7 +943,7 @@ static const char *f2fs_encrypted_follow_link(struct dentry *dentry, void **cook cpage = read_mapping_page(inode->i_mapping, 0, NULL); if (IS_ERR(cpage)) return ERR_CAST(cpage); - caddr = kmap(cpage); + caddr = page_address(cpage); caddr[size] = 0; /* Symlink is encrypted */ @@ -982,13 +983,11 @@ static const char *f2fs_encrypted_follow_link(struct dentry *dentry, void **cook /* Null-terminate the name */ paddr[res] = '\0'; - kunmap(cpage); page_cache_release(cpage); return *cookie = paddr; errout: kfree(cstr.name); f2fs_fname_crypto_free_buffer(&pstr); - kunmap(cpage); page_cache_release(cpage); return ERR_PTR(res); } diff --git a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c index ef73ed674a27162917845b0507269bdf86b273da..3e2ccade61edb4e4a9a7d27d9229d5ed37175dbc 100644 --- a/fs/freevxfs/vxfs_inode.c +++ b/fs/freevxfs/vxfs_inode.c @@ -326,6 +326,7 @@ vxfs_iget(struct super_block *sbp, ino_t ino) } else if (S_ISLNK(ip->i_mode)) { if (!VXFS_ISIMMED(vip)) { ip->i_op = &page_symlink_inode_operations; + inode_nohighmem(ip); ip->i_mapping->a_ops = &vxfs_aops; } else { ip->i_op = &simple_symlink_inode_operations; diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index 6dd107d7421ec05368845846d6a9cd9f558e9d23..19b33f8151f1ab2cb0957b7e5772ff1206659aad 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c @@ -403,6 +403,7 @@ struct inode *hfsplus_new_inode(struct super_block *sb, umode_t mode) } else if (S_ISLNK(inode->i_mode)) { sbi->file_count++; inode->i_op = &page_symlink_inode_operations; + inode_nohighmem(inode); inode->i_mapping->a_ops = &hfsplus_aops; hip->clump_blocks = 1; } else @@ -526,6 +527,7 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd) inode->i_mapping->a_ops = &hfsplus_aops; } else if (S_ISLNK(inode->i_mode)) { inode->i_op = &page_symlink_inode_operations; + inode_nohighmem(inode); inode->i_mapping->a_ops = &hfsplus_aops; } else { init_special_inode(inode, inode->i_mode, diff --git a/fs/hpfs/inode.c b/fs/hpfs/inode.c index 933c73780813198b8953376eaa1e595d786e36e1..1f3c6d76200bea68aa7d879955f0351b74b9cdc0 100644 --- a/fs/hpfs/inode.c +++ b/fs/hpfs/inode.c @@ -77,6 +77,7 @@ void hpfs_read_inode(struct inode *i) kfree(ea); i->i_mode = S_IFLNK | 0777; i->i_op = &page_symlink_inode_operations; + inode_nohighmem(i); i->i_data.a_ops = &hpfs_symlink_aops; set_nlink(i, 1); i->i_size = ea_size; diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c index ae4d5a1fa4c9b7f75ce188d8ec80e69d0a820892..506765afa1a3135d1ff9bccc48f06634439fa69e 100644 --- a/fs/hpfs/namei.c +++ b/fs/hpfs/namei.c @@ -332,6 +332,7 @@ static int hpfs_symlink(struct inode *dir, struct dentry *dentry, const char *sy result->i_blocks = 1; set_nlink(result, 1); result->i_size = strlen(symlink); + inode_nohighmem(result); result->i_op = &page_symlink_inode_operations; result->i_data.a_ops = &hpfs_symlink_aops; @@ -500,7 +501,7 @@ static int hpfs_rmdir(struct inode *dir, struct dentry *dentry) static int hpfs_symlink_readpage(struct file *file, struct page *page) { - char *link = kmap(page); + char *link = page_address(page); struct inode *i = page->mapping->host; struct fnode *fnode; struct buffer_head *bh; @@ -516,14 +517,12 @@ static int hpfs_symlink_readpage(struct file *file, struct page *page) goto fail; hpfs_unlock(i->i_sb); SetPageUptodate(page); - kunmap(page); unlock_page(page); return 0; fail: hpfs_unlock(i->i_sb); SetPageError(page); - kunmap(page); unlock_page(page); return err; } diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index de4bdfac0cec36f7f3e1d5cee94ec4aecef3e311..d8f51ee8126b3282156721d2d2639e24d3aa536e 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -760,6 +760,7 @@ static struct inode *hugetlbfs_get_inode(struct super_block *sb, break; case S_IFLNK: inode->i_op = &page_symlink_inode_operations; + inode_nohighmem(inode); break; } lockdep_annotate_inode_mutex_key(inode); diff --git a/fs/inode.c b/fs/inode.c index 1be5f9003eb38852f68957fcd287cdd5b820b310..5bb85a064ce7fade86383db89c252fe920032279 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -2028,3 +2028,9 @@ void inode_set_flags(struct inode *inode, unsigned int flags, new_flags) != old_flags)); } EXPORT_SYMBOL(inode_set_flags); + +void inode_nohighmem(struct inode *inode) +{ + mapping_set_gfp_mask(inode->i_mapping, GFP_USER); +} +EXPORT_SYMBOL(inode_nohighmem); diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index d67a16f2a45df8fcce56b9ff3ec56f334d951c9c..61abdc4920dab0056e998682f01038ef0a17f178 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c @@ -1417,6 +1417,7 @@ static int isofs_read_inode(struct inode *inode, int relocated) inode->i_fop = &isofs_dir_operations; } else if (S_ISLNK(inode->i_mode)) { inode->i_op = &page_symlink_inode_operations; + inode_nohighmem(inode); inode->i_data.a_ops = &isofs_symlink_aops; } else /* XXX - parse_rock_ridge_inode() had already set i_rdev. */ diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c index 735d7522a3a911f19af593d6b5f7d366d6cf448d..5384ceb35b1cc829442d6aa440db19c553a6eed8 100644 --- a/fs/isofs/rock.c +++ b/fs/isofs/rock.c @@ -687,7 +687,7 @@ static int rock_ridge_symlink_readpage(struct file *file, struct page *page) struct inode *inode = page->mapping->host; struct iso_inode_info *ei = ISOFS_I(inode); struct isofs_sb_info *sbi = ISOFS_SB(inode->i_sb); - char *link = kmap(page); + char *link = page_address(page); unsigned long bufsize = ISOFS_BUFFER_SIZE(inode); struct buffer_head *bh; char *rpnt = link; @@ -774,7 +774,6 @@ static int rock_ridge_symlink_readpage(struct file *file, struct page *page) brelse(bh); *rpnt = '\0'; SetPageUptodate(page); - kunmap(page); unlock_page(page); return 0; @@ -791,7 +790,6 @@ static int rock_ridge_symlink_readpage(struct file *file, struct page *page) brelse(bh); error: SetPageError(page); - kunmap(page); unlock_page(page); return -EIO; } diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c index 41aa3ca6a6a4995104d12f38cc5945ebb63a0f7d..9d9bae63ae2a2d44b36c4b1bcd53adae2158e896 100644 --- a/fs/jfs/inode.c +++ b/fs/jfs/inode.c @@ -60,6 +60,7 @@ struct inode *jfs_iget(struct super_block *sb, unsigned long ino) } else if (S_ISLNK(inode->i_mode)) { if (inode->i_size >= IDATASIZE) { inode->i_op = &page_symlink_inode_operations; + inode_nohighmem(inode); inode->i_mapping->a_ops = &jfs_aops; } else { inode->i_op = &jfs_fast_symlink_inode_operations; diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 9d7551f5c32a9ffb9a166f588e5f2211d62d0249..701f89370de7afb7d9a7402f1cbe4fe0d42b19fa 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c @@ -983,6 +983,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry, jfs_info("jfs_symlink: allocate extent ip:0x%p", ip); ip->i_op = &jfs_symlink_inode_operations; + inode_nohighmem(ip); ip->i_mapping->a_ops = &jfs_aops; /* diff --git a/fs/logfs/dir.c b/fs/logfs/dir.c index 99944a406a292fa6ab004eafcd064904a5e70595..542468e9bfb492f8333221a80bcfbcc4b01aa39a 100644 --- a/fs/logfs/dir.c +++ b/fs/logfs/dir.c @@ -529,6 +529,7 @@ static int logfs_symlink(struct inode *dir, struct dentry *dentry, return PTR_ERR(inode); inode->i_op = &page_symlink_inode_operations; + inode_nohighmem(inode); inode->i_mapping->a_ops = &logfs_reg_aops; return __logfs_create(dir, dentry, inode, target, destlen); diff --git a/fs/logfs/inode.c b/fs/logfs/inode.c index 06baa926a7a05379faf1aa5c1fa7c3766d24c592..0fce46d62b9c20491a9fb248f55a39b2273def74 100644 --- a/fs/logfs/inode.c +++ b/fs/logfs/inode.c @@ -65,6 +65,7 @@ static void logfs_inode_setops(struct inode *inode) break; case S_IFLNK: inode->i_op = &page_symlink_inode_operations; + inode_nohighmem(inode); inode->i_mapping->a_ops = &logfs_reg_aops; break; case S_IFSOCK: /* fall through */ diff --git a/fs/minix/inode.c b/fs/minix/inode.c index 086cd0a61e8015e60ccebcb99464ab23e58bb266..67a23bfd73035db19d6e7b43a7eaeeb53a4b4928 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c @@ -452,6 +452,7 @@ void minix_set_inode(struct inode *inode, dev_t rdev) inode->i_mapping->a_ops = &minix_aops; } else if (S_ISLNK(inode->i_mode)) { inode->i_op = &minix_symlink_inode_operations; + inode_nohighmem(inode); inode->i_mapping->a_ops = &minix_aops; } else init_special_inode(inode, inode->i_mode, rdev); diff --git a/fs/namei.c b/fs/namei.c index 4bae5cbfaa853c49489174485abdb969a0a2a092..2808958e6c67041ad6cc8eba7cd294fe30c1e5e6 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -4527,7 +4527,8 @@ static const char *page_getlink(struct dentry * dentry, void **cookie) if (IS_ERR(page)) return (char*)page; *cookie = page; - kaddr = kmap(page); + BUG_ON(mapping_gfp_mask(mapping) & __GFP_HIGHMEM); + kaddr = page_address(page); nd_terminate_link(kaddr, dentry->d_inode->i_size, PAGE_SIZE - 1); return kaddr; } @@ -4541,7 +4542,6 @@ EXPORT_SYMBOL(page_follow_link_light); void page_put_link(struct inode *unused, void *cookie) { struct page *page = cookie; - kunmap(page); page_cache_release(page); } EXPORT_SYMBOL(page_put_link); @@ -4565,7 +4565,6 @@ int __page_symlink(struct inode *inode, const char *symname, int len, int nofs) struct page *page; void *fsdata; int err; - char *kaddr; unsigned int flags = AOP_FLAG_UNINTERRUPTIBLE; if (nofs) flags |= AOP_FLAG_NOFS; @@ -4576,9 +4575,7 @@ int __page_symlink(struct inode *inode, const char *symname, int len, int nofs) if (err) goto fail; - kaddr = kmap_atomic(page); - memcpy(kaddr, symname, len-1); - kunmap_atomic(kaddr); + memcpy(page_address(page), symname, len-1); err = pagecache_write_end(NULL, mapping, 0, len-1, len-1, page, fsdata); diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c index 9605a2f635490ddf498c72049d7b40d84e7f977b..bb856f7e05fd86fcc28b8611a6bd58abe53c86d9 100644 --- a/fs/ncpfs/inode.c +++ b/fs/ncpfs/inode.c @@ -283,6 +283,7 @@ ncp_iget(struct super_block *sb, struct ncp_entry_info *info) #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS) } else if (S_ISLNK(inode->i_mode)) { inode->i_op = &ncp_symlink_inode_operations; + inode_nohighmem(inode); inode->i_data.a_ops = &ncp_symlink_aops; #endif } else { diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 31b0a52223a73758c385d18bea4ec22ed63c2884..ae9aa0b8155cfef77454d3f760c25a2fd030e14d 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -408,9 +408,10 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st inode->i_fop = NULL; inode->i_flags |= S_AUTOMOUNT; } - } else if (S_ISLNK(inode->i_mode)) + } else if (S_ISLNK(inode->i_mode)) { inode->i_op = &nfs_symlink_inode_operations; - else + inode_nohighmem(inode); + } else init_special_inode(inode, inode->i_mode, fattr->rdev); memset(&inode->i_atime, 0, sizeof(inode->i_atime)); diff --git a/fs/nfs/symlink.c b/fs/nfs/symlink.c index b6de433da5db14ab788ba358ce94b5952d5c601f..abd93bf015d6465c85cfc0b9a9fc88af7aa73e9d 100644 --- a/fs/nfs/symlink.c +++ b/fs/nfs/symlink.c @@ -56,7 +56,7 @@ static const char *nfs_follow_link(struct dentry *dentry, void **cookie) if (IS_ERR(page)) return ERR_CAST(page); *cookie = page; - return kmap(page); + return page_address(page); } /* diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c index ac2f64943ff4c257f3fe2cd8d32de581de601cc6..10b22527a617dcdefc36d36ce4fc3d3658e20330 100644 --- a/fs/nilfs2/inode.c +++ b/fs/nilfs2/inode.c @@ -510,6 +510,7 @@ static int __nilfs_read_inode(struct super_block *sb, inode->i_mapping->a_ops = &nilfs_aops; } else if (S_ISLNK(inode->i_mode)) { inode->i_op = &nilfs_symlink_inode_operations; + inode_nohighmem(inode); inode->i_mapping->a_ops = &nilfs_aops; } else { inode->i_op = &nilfs_special_inode_operations; diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c index c9a1a491aa9124b4cad5941e477f7ac3ae5de8b1..90b3ba960b9b6746d2b96856d7ff4c3a3e063490 100644 --- a/fs/nilfs2/namei.c +++ b/fs/nilfs2/namei.c @@ -161,6 +161,7 @@ static int nilfs_symlink(struct inode *dir, struct dentry *dentry, /* slow symlink */ inode->i_op = &nilfs_symlink_inode_operations; + inode_nohighmem(inode); inode->i_mapping->a_ops = &nilfs_aops; err = page_symlink(inode, symname, l); if (err) diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index 8f87e05ee25d3824524c7f6e040a5f43d87c723d..97a563bab9a871ee3e371a9796b990c24835f47f 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c @@ -361,6 +361,7 @@ void ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe, break; case S_IFLNK: inode->i_op = &ocfs2_symlink_inode_operations; + inode_nohighmem(inode); i_size_write(inode, le64_to_cpu(fe->i_size)); break; default: diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index a03f6f433075c02d3c87c192b362d2c7f2e96952..2efe8afc82c53820314a54ab0ca8bcf3736637a9 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c @@ -1960,6 +1960,7 @@ static int ocfs2_symlink(struct inode *dir, inode->i_rdev = 0; newsize = l - 1; inode->i_op = &ocfs2_symlink_inode_operations; + inode_nohighmem(inode); if (l > ocfs2_fast_symlink_chars(sb)) { u32 offset = 0; diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c index c4bcb778886e5c79c4dcc9381cf13f0a76358838..f37b3deb01b4d5f2d07ea90774a5bf99c39992bd 100644 --- a/fs/qnx4/inode.c +++ b/fs/qnx4/inode.c @@ -316,6 +316,7 @@ struct inode *qnx4_iget(struct super_block *sb, unsigned long ino) inode->i_fop = &qnx4_dir_operations; } else if (S_ISLNK(inode->i_mode)) { inode->i_op = &page_symlink_inode_operations; + inode_nohighmem(inode); inode->i_mapping->a_ops = &qnx4_aops; qnx4_i(inode)->mmu_private = inode->i_size; } else { diff --git a/fs/qnx6/inode.c b/fs/qnx6/inode.c index 32d2e1a9774ca66005d92786df99a70865efb3fa..9728b5499e1d5a1eae80344ff0e9e76dd1a04153 100644 --- a/fs/qnx6/inode.c +++ b/fs/qnx6/inode.c @@ -582,6 +582,7 @@ struct inode *qnx6_iget(struct super_block *sb, unsigned ino) inode->i_mapping->a_ops = &qnx6_aops; } else if (S_ISLNK(inode->i_mode)) { inode->i_op = &page_symlink_inode_operations; + inode_nohighmem(inode); inode->i_mapping->a_ops = &qnx6_aops; } else init_special_inode(inode, inode->i_mode, 0); diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c index 889d558b4e05518e6b14280d8ffea7ec28d7f85c..38981b03752433de71197c5c724999a33dc2d53d 100644 --- a/fs/ramfs/inode.c +++ b/fs/ramfs/inode.c @@ -79,6 +79,7 @@ struct inode *ramfs_get_inode(struct super_block *sb, break; case S_IFLNK: inode->i_op = &page_symlink_inode_operations; + inode_nohighmem(inode); break; } } diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 3d8e7e671d5ba7d15fe4a14e1b803673c220cdee..ae9e5b308cf9f5775300e7ee109e4e2f72720b12 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -1361,6 +1361,7 @@ static void init_inode(struct inode *inode, struct treepath *path) inode->i_fop = &reiserfs_dir_operations; } else if (S_ISLNK(inode->i_mode)) { inode->i_op = &reiserfs_symlink_inode_operations; + inode_nohighmem(inode); inode->i_mapping->a_ops = &reiserfs_address_space_operations; } else { inode->i_blocks = 0; diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index 47f96988fdd478dbc6ce325232d38754258864cc..4fc2326fac038458821140e6e0cc2c5abcc6c0cd 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c @@ -1170,6 +1170,7 @@ static int reiserfs_symlink(struct inode *parent_dir, reiserfs_update_inode_transaction(parent_dir); inode->i_op = &reiserfs_symlink_inode_operations; + inode_nohighmem(inode); inode->i_mapping->a_ops = &reiserfs_address_space_operations; retval = reiserfs_add_entry(&th, parent_dir, dentry->d_name.name, diff --git a/fs/romfs/super.c b/fs/romfs/super.c index 268733cda397eb7780f45d966cdca822daad16e8..bb894e78a821ef4643e25cbf684832b5baaf054c 100644 --- a/fs/romfs/super.c +++ b/fs/romfs/super.c @@ -360,6 +360,7 @@ static struct inode *romfs_iget(struct super_block *sb, unsigned long pos) break; case ROMFH_SYM: i->i_op = &page_symlink_inode_operations; + inode_nohighmem(i); i->i_data.a_ops = &romfs_aops; mode |= S_IRWXUGO; break; diff --git a/fs/squashfs/inode.c b/fs/squashfs/inode.c index a1ce5ce60632e892fc0f17859e99963eb1a67235..0927b1e80ab6e0b5a039f41840131c3f40988f75 100644 --- a/fs/squashfs/inode.c +++ b/fs/squashfs/inode.c @@ -41,6 +41,7 @@ #include #include #include +#include #include "squashfs_fs.h" #include "squashfs_fs_sb.h" @@ -291,6 +292,7 @@ int squashfs_read_inode(struct inode *inode, long long ino) set_nlink(inode, le32_to_cpu(sqsh_ino->nlink)); inode->i_size = le32_to_cpu(sqsh_ino->symlink_size); inode->i_op = &squashfs_symlink_inode_ops; + inode_nohighmem(inode); inode->i_data.a_ops = &squashfs_symlink_aops; inode->i_mode |= S_IFLNK; squashfs_i(inode)->start = block; diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c index 02fa1dcc5969f6b596a6c527170fcf9193c437e5..ef8bcdb80acabbd58d82fe9af25403474c532a73 100644 --- a/fs/sysv/inode.c +++ b/fs/sysv/inode.c @@ -163,6 +163,7 @@ void sysv_set_inode(struct inode *inode, dev_t rdev) inode->i_mapping->a_ops = &sysv_aops; } else if (S_ISLNK(inode->i_mode)) { inode->i_op = &sysv_symlink_inode_operations; + inode_nohighmem(inode); inode->i_mapping->a_ops = &sysv_aops; } else init_special_inode(inode, inode->i_mode, rdev); diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 8675c2b53a71ba09cbc252b9dd68ea2cbb4c630d..055746350d16f90be47fe892d093c51d4959eedb 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -1541,6 +1541,7 @@ static int udf_read_inode(struct inode *inode, bool hidden_inode) case ICBTAG_FILE_TYPE_SYMLINK: inode->i_data.a_ops = &udf_symlink_aops; inode->i_op = &page_symlink_inode_operations; + inode_nohighmem(inode); inode->i_mode = S_IFLNK | S_IRWXUGO; break; case ICBTAG_FILE_TYPE_MAIN: diff --git a/fs/udf/namei.c b/fs/udf/namei.c index d0e6de1d148cb6c5591239b71d4fc52dfcf17e2e..42eafb91f7ff3c092fd38f6fb6136862ca6508c8 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -922,6 +922,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, inode->i_data.a_ops = &udf_symlink_aops; inode->i_op = &page_symlink_inode_operations; + inode_nohighmem(inode); if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { struct kernel_lb_addr eloc; diff --git a/fs/udf/symlink.c b/fs/udf/symlink.c index 862535b3ba58a8a6f6ca3d23b35b0b66fee36c22..8d619773056b5ef0b0a3f2d7dd27b74a6eb76434 100644 --- a/fs/udf/symlink.c +++ b/fs/udf/symlink.c @@ -107,7 +107,7 @@ static int udf_symlink_filler(struct file *file, struct page *page) struct buffer_head *bh = NULL; unsigned char *symlink; int err; - unsigned char *p = kmap(page); + unsigned char *p = page_address(page); struct udf_inode_info *iinfo; uint32_t pos; @@ -141,7 +141,6 @@ static int udf_symlink_filler(struct file *file, struct page *page) up_read(&iinfo->i_data_sem); SetPageUptodate(page); - kunmap(page); unlock_page(page); return 0; @@ -149,7 +148,6 @@ static int udf_symlink_filler(struct file *file, struct page *page) up_read(&iinfo->i_data_sem); SetPageError(page); out_unmap: - kunmap(page); unlock_page(page); return err; } diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index 737160a7b819ac00ab965521e9c409829d5a401b..d897e169ab9c4f240e1f4023955f37bf0fe8f266 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c @@ -533,6 +533,7 @@ static void ufs_set_inode_ops(struct inode *inode) } else { inode->i_mapping->a_ops = &ufs_aops; inode->i_op = &page_symlink_inode_operations; + inode_nohighmem(inode); } } else init_special_inode(inode, inode->i_mode, diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c index 24b0cbd2d917a338ea1b098ad8245be59180e6d9..acf4a3b61b81fcc58342819eabbc768e6ba33bae 100644 --- a/fs/ufs/namei.c +++ b/fs/ufs/namei.c @@ -124,6 +124,7 @@ static int ufs_symlink (struct inode * dir, struct dentry * dentry, if (l > UFS_SB(sb)->s_uspi->s_maxsymlinklen) { /* slow symlink */ inode->i_op = &page_symlink_inode_operations; + inode_nohighmem(inode); inode->i_mapping->a_ops = &ufs_aops; err = page_symlink(inode, symname, l); if (err) diff --git a/include/linux/fs.h b/include/linux/fs.h index 3aa51425416148f5bec14b6faf4e6f4e81370a22..dfeda44b9ba446ef59e368cafdb1acc61b323d3f 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -3025,5 +3025,6 @@ static inline bool dir_relax(struct inode *inode) } extern bool path_noexec(const struct path *path); +extern void inode_nohighmem(struct inode *inode); #endif /* _LINUX_FS_H */ diff --git a/mm/shmem.c b/mm/shmem.c index 9187eee4128b45769583dae2a73720e3545ee933..64bf5acb49fe111ee3b5665daad5434d87766d01 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -2444,7 +2444,6 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s int len; struct inode *inode; struct page *page; - char *kaddr; struct shmem_inode_info *info; len = strlen(symname) + 1; @@ -2483,9 +2482,8 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s } inode->i_mapping->a_ops = &shmem_aops; inode->i_op = &shmem_symlink_inode_operations; - kaddr = kmap_atomic(page); - memcpy(kaddr, symname, len); - kunmap_atomic(kaddr); + inode_nohighmem(inode); + memcpy(page_address(page), symname, len); SetPageUptodate(page); set_page_dirty(page); unlock_page(page); @@ -2506,13 +2504,12 @@ static const char *shmem_follow_link(struct dentry *dentry, void **cookie) return ERR_PTR(error); unlock_page(page); *cookie = page; - return kmap(page); + return page_address(page); } static void shmem_put_link(struct inode *unused, void *cookie) { struct page *page = cookie; - kunmap(page); mark_page_accessed(page); page_cache_release(page); }