]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
switch befs long symlinks to page_symlink_operations
authorAl Viro <viro@zeniv.linux.org.uk>
Fri, 13 Nov 2015 11:57:13 +0000 (06:57 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Mon, 7 Dec 2015 01:43:25 +0000 (20:43 -0500)
just give them the right ->readpage()...

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/befs/linuxvfs.c

index 46aedacfa6a8d4131563a83a8402daf89d590ddb..1c8b0dca8b506e8add384d66a7c70e6699370e78 100644 (file)
@@ -42,7 +42,7 @@ static struct inode *befs_iget(struct super_block *, unsigned long);
 static struct inode *befs_alloc_inode(struct super_block *sb);
 static void befs_destroy_inode(struct inode *inode);
 static void befs_destroy_inodecache(void);
-static const char *befs_follow_link(struct dentry *, void **);
+static int befs_symlink_readpage(struct file *, struct page *);
 static int befs_utf2nls(struct super_block *sb, const char *in, int in_len,
                        char **out, int *out_len);
 static int befs_nls2utf(struct super_block *sb, const char *in, int in_len,
@@ -79,10 +79,8 @@ static const struct address_space_operations befs_aops = {
        .bmap           = befs_bmap,
 };
 
-static const struct inode_operations befs_symlink_inode_operations = {
-       .readlink       = generic_readlink,
-       .follow_link    = befs_follow_link,
-       .put_link       = kfree_put_link,
+static const struct address_space_operations befs_symlink_aops = {
+       .readpage       = befs_symlink_readpage,
 };
 
 /* 
@@ -398,7 +396,8 @@ static struct inode *befs_iget(struct super_block *sb, unsigned long ino)
                inode->i_fop = &befs_dir_operations;
        } else if (S_ISLNK(inode->i_mode)) {
                if (befs_ino->i_flags & BEFS_LONG_SYMLINK) {
-                       inode->i_op = &befs_symlink_inode_operations;
+                       inode->i_op = &page_symlink_inode_operations;
+                       inode->i_mapping->a_ops = &befs_symlink_aops;
                } else {
                        inode->i_link = befs_ino->i_data.symlink;
                        inode->i_op = &simple_symlink_inode_operations;
@@ -463,31 +462,35 @@ befs_destroy_inodecache(void)
  * The data stream become link name. Unless the LONG_SYMLINK
  * flag is set.
  */
-static const char *
-befs_follow_link(struct dentry *dentry, void **cookie)
+static int befs_symlink_readpage(struct file *unused, struct page *page)
 {
-       struct super_block *sb = dentry->d_sb;
-       struct befs_inode_info *befs_ino = BEFS_I(d_inode(dentry));
+       struct inode *inode = page->mapping->host;
+       struct super_block *sb = inode->i_sb;
+       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;
+       char *link = kmap(page);
 
-       if (len == 0) {
+       if (len == 0 || len > PAGE_SIZE) {
                befs_error(sb, "Long symlink with illegal length");
-               return ERR_PTR(-EIO);
+               goto fail;
        }
        befs_debug(sb, "Follow long symlink");
 
-       link = kmalloc(len, GFP_NOFS);
-       if (!link)
-               return ERR_PTR(-ENOMEM);
        if (befs_read_lsymlink(sb, data, link, len) != len) {
-               kfree(link);
                befs_error(sb, "Failed to read entire long symlink");
-               return ERR_PTR(-EIO);
+               goto fail;
        }
        link[len - 1] = '\0';
-       return *cookie = link;
+       SetPageUptodate(page);
+       kunmap(page);
+       unlock_page(page);
+       return 0;
+fail:
+       SetPageError(page);
+       kunmap(page);
+       unlock_page(page);
+       return -EIO;
 }
 
 /*