Commit 5a302308 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] rename block_symlink() to page_symlink()

block_symlink() is not a "block" function at all.  It is a pure
pagecache/address_space function.  Seeing driverfs calling it was
the last straw.

The patch renames it to `page_symlink()' and moves it into fs/namei.c
parent ddedde1d
...@@ -2327,46 +2327,6 @@ int brw_page(int rw, struct page *page, ...@@ -2327,46 +2327,6 @@ int brw_page(int rw, struct page *page,
return 0; return 0;
} }
int block_symlink(struct inode *inode, const char *symname, int len)
{
struct address_space *mapping = inode->i_mapping;
struct page *page = grab_cache_page(mapping, 0);
int err = -ENOMEM;
char *kaddr;
if (!page)
goto fail;
err = mapping->a_ops->prepare_write(NULL, page, 0, len-1);
if (err)
goto fail_map;
kaddr = page_address(page);
memcpy(kaddr, symname, len-1);
mapping->a_ops->commit_write(NULL, page, 0, len-1);
/*
* Notice that we are _not_ going to block here - end of page is
* unmapped, so this will only try to map the rest of page, see
* that it is unmapped (typically even will not look into inode -
* ->i_size will be enough for everything) and zero it out.
* OTOH it's obviously correct and should make the page up-to-date.
*/
if (!PageUptodate(page)) {
err = mapping->a_ops->readpage(NULL, page);
wait_on_page_locked(page);
} else {
unlock_page(page);
}
page_cache_release(page);
if (err < 0)
goto fail;
mark_inode_dirty(inode);
return 0;
fail_map:
unlock_page(page);
page_cache_release(page);
fail:
return err;
}
/* /*
* Sanity checks for try_to_free_buffers. * Sanity checks for try_to_free_buffers.
*/ */
......
...@@ -171,7 +171,7 @@ static int driverfs_symlink(struct inode * dir, struct dentry *dentry, const cha ...@@ -171,7 +171,7 @@ static int driverfs_symlink(struct inode * dir, struct dentry *dentry, const cha
inode = driverfs_get_inode(dir->i_sb, S_IFLNK|S_IRWXUGO, 0); inode = driverfs_get_inode(dir->i_sb, S_IFLNK|S_IRWXUGO, 0);
if (inode) { if (inode) {
int l = strlen(symname)+1; int l = strlen(symname)+1;
error = block_symlink(inode, symname, l); error = page_symlink(inode, symname, l);
if (!error) { if (!error) {
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
dget(dentry); dget(dentry);
......
...@@ -31,7 +31,6 @@ ...@@ -31,7 +31,6 @@
#include "ext2.h" #include "ext2.h"
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/buffer_head.h> /* for block_symlink() */
/* /*
* Couple of helper functions - make the code slightly cleaner. * Couple of helper functions - make the code slightly cleaner.
...@@ -165,7 +164,7 @@ static int ext2_symlink (struct inode * dir, struct dentry * dentry, ...@@ -165,7 +164,7 @@ static int ext2_symlink (struct inode * dir, struct dentry * dentry,
/* slow symlink */ /* slow symlink */
inode->i_op = &page_symlink_inode_operations; inode->i_op = &page_symlink_inode_operations;
inode->i_mapping->a_ops = &ext2_aops; inode->i_mapping->a_ops = &ext2_aops;
err = block_symlink(inode, symname, l); err = page_symlink(inode, symname, l);
if (err) if (err)
goto out_fail; goto out_fail;
} else { } else {
......
...@@ -1092,7 +1092,7 @@ static int commit_write_fn(handle_t *handle, struct buffer_head *bh) ...@@ -1092,7 +1092,7 @@ static int commit_write_fn(handle_t *handle, struct buffer_head *bh)
/* /*
* We need to pick up the new inode size which generic_commit_write gave us * We need to pick up the new inode size which generic_commit_write gave us
* `file' can be NULL - eg, when called from block_symlink(). * `file' can be NULL - eg, when called from page_symlink().
* *
* ext3 never places buffers on inode->i_mapping->private_list. metadata * ext3 never places buffers on inode->i_mapping->private_list. metadata
* buffers are managed internally. * buffers are managed internally.
......
...@@ -987,11 +987,11 @@ static int ext3_symlink (struct inode * dir, ...@@ -987,11 +987,11 @@ static int ext3_symlink (struct inode * dir,
inode->i_op = &page_symlink_inode_operations; inode->i_op = &page_symlink_inode_operations;
inode->i_mapping->a_ops = &ext3_aops; inode->i_mapping->a_ops = &ext3_aops;
/* /*
* block_symlink() calls back into ext3_prepare/commit_write. * page_symlink() calls into ext3_prepare/commit_write.
* We have a transaction open. All is sweetness. It also sets * We have a transaction open. All is sweetness. It also sets
* i_size in generic_commit_write(). * i_size in generic_commit_write().
*/ */
err = block_symlink(inode, symname, l); err = page_symlink(inode, symname, l);
if (err) if (err)
goto out_no_entry; goto out_no_entry;
} else { } else {
......
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
* Copyright (C) 1991, 1992 Linus Torvalds * Copyright (C) 1991, 1992 Linus Torvalds
*/ */
#include <linux/buffer_head.h> /* for block_symlink() */
#include "minix.h" #include "minix.h"
static inline void inc_count(struct inode *inode) static inline void inc_count(struct inode *inode)
...@@ -111,7 +110,7 @@ static int minix_symlink(struct inode * dir, struct dentry *dentry, ...@@ -111,7 +110,7 @@ static int minix_symlink(struct inode * dir, struct dentry *dentry,
inode->i_mode = S_IFLNK | 0777; inode->i_mode = S_IFLNK | 0777;
minix_set_inode(inode, 0); minix_set_inode(inode, 0);
err = block_symlink(inode, symname, i); err = page_symlink(inode, symname, i);
if (err) if (err)
goto out_fail; goto out_fail;
......
...@@ -2136,6 +2136,46 @@ int page_follow_link(struct dentry *dentry, struct nameidata *nd) ...@@ -2136,6 +2136,46 @@ int page_follow_link(struct dentry *dentry, struct nameidata *nd)
return res; return res;
} }
int page_symlink(struct inode *inode, const char *symname, int len)
{
struct address_space *mapping = inode->i_mapping;
struct page *page = grab_cache_page(mapping, 0);
int err = -ENOMEM;
char *kaddr;
if (!page)
goto fail;
err = mapping->a_ops->prepare_write(NULL, page, 0, len-1);
if (err)
goto fail_map;
kaddr = page_address(page);
memcpy(kaddr, symname, len-1);
mapping->a_ops->commit_write(NULL, page, 0, len-1);
/*
* Notice that we are _not_ going to block here - end of page is
* unmapped, so this will only try to map the rest of page, see
* that it is unmapped (typically even will not look into inode -
* ->i_size will be enough for everything) and zero it out.
* OTOH it's obviously correct and should make the page up-to-date.
*/
if (!PageUptodate(page)) {
err = mapping->a_ops->readpage(NULL, page);
wait_on_page_locked(page);
} else {
unlock_page(page);
}
page_cache_release(page);
if (err < 0)
goto fail;
mark_inode_dirty(inode);
return 0;
fail_map:
unlock_page(page);
page_cache_release(page);
fail:
return err;
}
struct inode_operations page_symlink_inode_operations = { struct inode_operations page_symlink_inode_operations = {
readlink: page_readlink, readlink: page_readlink,
follow_link: page_follow_link, follow_link: page_follow_link,
......
...@@ -29,7 +29,6 @@ ...@@ -29,7 +29,6 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/buffer_head.h> /* for block_symlink() */
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -235,7 +234,7 @@ static int ramfs_symlink(struct inode * dir, struct dentry *dentry, const char * ...@@ -235,7 +234,7 @@ static int ramfs_symlink(struct inode * dir, struct dentry *dentry, const char *
inode = ramfs_get_inode(dir->i_sb, S_IFLNK|S_IRWXUGO, 0); inode = ramfs_get_inode(dir->i_sb, S_IFLNK|S_IRWXUGO, 0);
if (inode) { if (inode) {
int l = strlen(symname)+1; int l = strlen(symname)+1;
error = block_symlink(inode, symname, l); error = page_symlink(inode, symname, l);
if (!error) { if (!error) {
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
dget(dentry); dget(dentry);
......
...@@ -117,7 +117,7 @@ static int sysv_symlink(struct inode * dir, struct dentry * dentry, ...@@ -117,7 +117,7 @@ static int sysv_symlink(struct inode * dir, struct dentry * dentry,
goto out; goto out;
sysv_set_inode(inode, 0); sysv_set_inode(inode, 0);
err = block_symlink(inode, symname, l); err = page_symlink(inode, symname, l);
if (err) if (err)
goto out_fail; goto out_fail;
......
...@@ -143,7 +143,7 @@ static int ufs_symlink (struct inode * dir, struct dentry * dentry, ...@@ -143,7 +143,7 @@ static int ufs_symlink (struct inode * dir, struct dentry * dentry,
/* slow symlink */ /* slow symlink */
inode->i_op = &page_symlink_inode_operations; inode->i_op = &page_symlink_inode_operations;
inode->i_mapping->a_ops = &ufs_aops; inode->i_mapping->a_ops = &ufs_aops;
err = block_symlink(inode, symname, l); err = page_symlink(inode, symname, l);
if (err) if (err)
goto out_fail; goto out_fail;
} else { } else {
......
...@@ -499,7 +499,7 @@ static int umsdos_symlink_x (struct inode *dir, struct dentry *dentry, ...@@ -499,7 +499,7 @@ static int umsdos_symlink_x (struct inode *dir, struct dentry *dentry,
} }
len = strlen (symname) + 1; len = strlen (symname) + 1;
ret = block_symlink(dentry->d_inode, symname, len); ret = page_symlink(dentry->d_inode, symname, len);
if (ret < 0) if (ret < 0)
goto out_unlink; goto out_unlink;
out: out:
......
...@@ -192,7 +192,6 @@ void FASTCALL(unlock_buffer(struct buffer_head *bh)); ...@@ -192,7 +192,6 @@ void FASTCALL(unlock_buffer(struct buffer_head *bh));
*/ */
int try_to_release_page(struct page * page, int gfp_mask); int try_to_release_page(struct page * page, int gfp_mask);
int block_flushpage(struct page *page, unsigned long offset); int block_flushpage(struct page *page, unsigned long offset);
int block_symlink(struct inode *, const char *, int);
int block_write_full_page(struct page*, get_block_t*); int block_write_full_page(struct page*, get_block_t*);
int block_read_full_page(struct page*, get_block_t*); int block_read_full_page(struct page*, get_block_t*);
int block_prepare_write(struct page*, unsigned, unsigned, get_block_t*); int block_prepare_write(struct page*, unsigned, unsigned, get_block_t*);
......
...@@ -1244,6 +1244,7 @@ extern int vfs_readlink(struct dentry *, char *, int, const char *); ...@@ -1244,6 +1244,7 @@ extern int vfs_readlink(struct dentry *, char *, int, const char *);
extern int vfs_follow_link(struct nameidata *, const char *); extern int vfs_follow_link(struct nameidata *, const char *);
extern int page_readlink(struct dentry *, char *, int); extern int page_readlink(struct dentry *, char *, int);
extern int page_follow_link(struct dentry *, struct nameidata *); extern int page_follow_link(struct dentry *, struct nameidata *);
extern int page_symlink(struct inode *inode, const char *symname, int len);
extern struct inode_operations page_symlink_inode_operations; extern struct inode_operations page_symlink_inode_operations;
extern void generic_fillattr(struct inode *, struct kstat *); extern void generic_fillattr(struct inode *, struct kstat *);
......
...@@ -277,7 +277,7 @@ EXPORT_SYMBOL(vfs_follow_link); ...@@ -277,7 +277,7 @@ EXPORT_SYMBOL(vfs_follow_link);
EXPORT_SYMBOL(page_readlink); EXPORT_SYMBOL(page_readlink);
EXPORT_SYMBOL(page_follow_link); EXPORT_SYMBOL(page_follow_link);
EXPORT_SYMBOL(page_symlink_inode_operations); EXPORT_SYMBOL(page_symlink_inode_operations);
EXPORT_SYMBOL(block_symlink); EXPORT_SYMBOL(page_symlink);
EXPORT_SYMBOL(vfs_readdir); EXPORT_SYMBOL(vfs_readdir);
EXPORT_SYMBOL(__get_lease); EXPORT_SYMBOL(__get_lease);
EXPORT_SYMBOL(lease_get_mtime); EXPORT_SYMBOL(lease_get_mtime);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment