diff options
Diffstat (limited to 'fs/sysv')
-rw-r--r-- | fs/sysv/dir.c | 2 | ||||
-rw-r--r-- | fs/sysv/file.c | 2 | ||||
-rw-r--r-- | fs/sysv/inode.c | 1 | ||||
-rw-r--r-- | fs/sysv/namei.c | 64 | ||||
-rw-r--r-- | fs/sysv/symlink.c | 73 | ||||
-rw-r--r-- | fs/sysv/truncate.c | 2 |
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. */ |