summaryrefslogtreecommitdiffstats
path: root/fs/sysv
diff options
context:
space:
mode:
Diffstat (limited to 'fs/sysv')
-rw-r--r--fs/sysv/dir.c2
-rw-r--r--fs/sysv/file.c2
-rw-r--r--fs/sysv/inode.c1
-rw-r--r--fs/sysv/namei.c64
-rw-r--r--fs/sysv/symlink.c73
-rw-r--r--fs/sysv/truncate.c2
6 files changed, 29 insertions, 115 deletions
diff --git a/fs/sysv/dir.c b/fs/sysv/dir.c
index d76f1d6b3..f17fb8b63 100644
--- a/fs/sysv/dir.c
+++ b/fs/sysv/dir.c
@@ -62,10 +62,8 @@ struct inode_operations sysv_dir_inode_operations = {
NULL, /* get_block */
NULL, /* readpage */
NULL, /* writepage */
- NULL, /* flushpage */
NULL, /* truncate */
NULL, /* permission */
- NULL, /* smap */
NULL /* revalidate */
};
diff --git a/fs/sysv/file.c b/fs/sysv/file.c
index 36650f141..f54b8d6bc 100644
--- a/fs/sysv/file.c
+++ b/fs/sysv/file.c
@@ -77,9 +77,7 @@ struct inode_operations sysv_file_inode_operations = {
sysv_get_block, /* get_block */
block_read_full_page, /* readpage */
block_write_full_page, /* writepage */
- block_flushpage, /* flushpage */
sysv_truncate, /* truncate */
NULL, /* permission */
- NULL, /* smap */
NULL /* revalidate */
};
diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c
index 1db8ca9c8..6cd146dbd 100644
--- a/fs/sysv/inode.c
+++ b/fs/sysv/inode.c
@@ -21,6 +21,7 @@
* the superblock.
*/
+#include <linux/config.h>
#include <linux/module.h>
#include <linux/sched.h>
diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c
index 2a1626bdd..844912898 100644
--- a/fs/sysv/namei.c
+++ b/fs/sysv/namei.c
@@ -440,59 +440,41 @@ end_unlink:
int sysv_symlink(struct inode * dir, struct dentry * dentry,
const char * symname)
{
- struct sysv_dir_entry * de;
struct inode * inode;
- struct buffer_head * name_block;
- char * name_block_data;
- struct super_block * sb;
- int i;
- char c;
+ struct sysv_dir_entry * de;
struct buffer_head * bh;
-
+ int err;
+ int l;
+
+ err = -ENAMETOOLONG;
+ l = strlen(symname)+1;
+ if (l > dir->i_sb->sv_block_size_1)
+ goto out;
+ err = -ENOSPC;
if (!(inode = sysv_new_inode(dir)))
- return -ENOSPC;
+ goto out;
inode->i_mode = S_IFLNK | 0777;
inode->i_op = &sysv_symlink_inode_operations;
- name_block = sysv_file_bread(inode, 0, 1);
- if (!name_block) {
- inode->i_nlink--;
- mark_inode_dirty(inode);
- iput(inode);
- return -ENOSPC;
- }
- sb = inode->i_sb;
- name_block_data = name_block->b_data;
- i = 0;
- while (i < sb->sv_block_size_1 && (c = *(symname++)))
- name_block_data[i++] = c;
- name_block_data[i] = 0;
- mark_buffer_dirty(name_block, 1);
- brelse(name_block);
- inode->i_size = i;
+ err = block_symlink(inode, symname, l);
+ if (err)
+ goto out_no_entry;
mark_inode_dirty(inode);
- bh = sysv_find_entry(dir, dentry->d_name.name,
- dentry->d_name.len, &de);
- if (bh) {
- inode->i_nlink--;
- mark_inode_dirty(inode);
- iput(inode);
- brelse(bh);
- return -EEXIST;
- }
- i = sysv_add_entry(dir, dentry->d_name.name,
+ err = sysv_add_entry(dir, dentry->d_name.name,
dentry->d_name.len, &bh, &de);
- if (i) {
- inode->i_nlink--;
- mark_inode_dirty(inode);
- iput(inode);
- return i;
- }
+ if (err)
+ goto out_no_entry;
de->inode = inode->i_ino;
mark_buffer_dirty(bh, 1);
brelse(bh);
d_instantiate(dentry, inode);
- return 0;
+out:
+ return err;
+out_no_entry:
+ inode->i_nlink--;
+ mark_inode_dirty(inode);
+ iput(inode);
+ goto out;
}
int sysv_link(struct dentry * old_dentry, struct inode * dir,
diff --git a/fs/sysv/symlink.c b/fs/sysv/symlink.c
index df611d589..3f77f831e 100644
--- a/fs/sysv/symlink.c
+++ b/fs/sysv/symlink.c
@@ -13,79 +13,14 @@
* SystemV/Coherent symlink handling code
*/
-#include <linux/errno.h>
-#include <linux/sched.h>
#include <linux/sysv_fs.h>
-#include <linux/stat.h>
-
-#include <asm/uaccess.h>
-
-static int sysv_readlink(struct dentry *, char *, int);
-static struct dentry *sysv_follow_link(struct dentry *, struct dentry *, unsigned int);
/*
* symlinks can't do much...
*/
struct inode_operations sysv_symlink_inode_operations = {
- NULL, /* no file-operations */
- NULL, /* create */
- NULL, /* lookup */
- NULL, /* link */
- NULL, /* unlink */
- NULL, /* symlink */
- NULL, /* mkdir */
- NULL, /* rmdir */
- NULL, /* mknod */
- NULL, /* rename */
- sysv_readlink, /* readlink */
- sysv_follow_link, /* follow_link */
- NULL, /* get_block */
- NULL, /* readpage */
- NULL, /* writepage */
- NULL, /* flushpage */
- NULL, /* truncate */
- NULL, /* permission */
- NULL, /* smap */
- NULL /* revalidate */
+ readlink: page_readlink,
+ follow_link: page_follow_link,
+ get_block: sysv_get_block,
+ readpage: block_read_full_page
};
-
-static struct dentry *sysv_follow_link(struct dentry * dentry,
- struct dentry * base,
- unsigned int follow)
-{
- struct inode *inode = dentry->d_inode;
- struct buffer_head * bh;
-
- bh = sysv_file_bread(inode, 0, 0);
- if (!bh) {
- dput(base);
- return ERR_PTR(-EIO);
- }
- UPDATE_ATIME(inode);
- base = lookup_dentry(bh->b_data, base, follow);
- brelse(bh);
- return base;
-}
-
-static int sysv_readlink(struct dentry * dentry, char * buffer, int buflen)
-{
- struct inode *inode = dentry->d_inode;
- struct buffer_head * bh;
- char * bh_data;
- int i;
- char c;
-
- if (buflen > inode->i_sb->sv_block_size_1)
- buflen = inode->i_sb->sv_block_size_1;
- bh = sysv_file_bread(inode, 0, 0);
- if (!bh)
- return 0;
- bh_data = bh->b_data;
- i = 0;
- while (i<buflen && (c = bh_data[i])) {
- i++;
- put_user(c,buffer++);
- }
- brelse(bh);
- return i;
-}
diff --git a/fs/sysv/truncate.c b/fs/sysv/truncate.c
index db0f72506..32bfccf6d 100644
--- a/fs/sysv/truncate.c
+++ b/fs/sysv/truncate.c
@@ -36,7 +36,7 @@
*/
#define DATA_BUFFER_USED(bh) \
- (atomic_read(&bh->b_count) || buffer_locked(bh))
+ (atomic_read(&bh->b_count)>1 || buffer_locked(bh))
/* We throw away any data beyond inode->i_size. */