summaryrefslogtreecommitdiffstats
path: root/fs/ufs
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-02-04 07:40:19 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-02-04 07:40:19 +0000
commit33263fc5f9ac8e8cb2b22d06af3ce5ac1dd815e4 (patch)
tree2d1b86a40bef0958a68cf1a2eafbeb0667a70543 /fs/ufs
parent216f5f51aa02f8b113aa620ebc14a9631a217a00 (diff)
Merge with Linux 2.3.32.
Diffstat (limited to 'fs/ufs')
-rw-r--r--fs/ufs/dir.c2
-rw-r--r--fs/ufs/file.c2
-rw-r--r--fs/ufs/inode.c4
-rw-r--r--fs/ufs/namei.c57
-rw-r--r--fs/ufs/symlink.c119
-rw-r--r--fs/ufs/truncate.c2
6 files changed, 39 insertions, 147 deletions
diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c
index 0b23ad37f..f2be33cfa 100644
--- a/fs/ufs/dir.c
+++ b/fs/ufs/dir.c
@@ -210,9 +210,7 @@ struct inode_operations ufs_dir_inode_operations = {
NULL, /* get_block */
NULL, /* readpage */
NULL, /* writepage */
- NULL, /* flushpage */
NULL, /* truncate */
ufs_permission, /* permission */
- NULL, /* smap */
NULL /* revalidate */
};
diff --git a/fs/ufs/file.c b/fs/ufs/file.c
index 33d68ba5d..b014e6c14 100644
--- a/fs/ufs/file.c
+++ b/fs/ufs/file.c
@@ -153,9 +153,7 @@ struct inode_operations ufs_file_inode_operations = {
ufs_getfrag_block, /* get_block */
block_read_full_page, /* readpage */
block_write_full_page, /* writepage */
- block_flushpage, /* flushpage */
ufs_truncate, /* truncate */
NULL, /* permission */
- NULL, /* smap */
NULL /* revalidate */
};
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c
index afcdcd600..21171a864 100644
--- a/fs/ufs/inode.c
+++ b/fs/ufs/inode.c
@@ -631,7 +631,9 @@ void ufs_read_inode (struct inode * inode)
else if (S_ISDIR(inode->i_mode))
inode->i_op = &ufs_dir_inode_operations;
else if (S_ISLNK(inode->i_mode))
- inode->i_op = &ufs_symlink_inode_operations;
+ inode->i_op = inode->i_blocks
+ ?&ufs_symlink_inode_operations
+ :&ufs_fast_symlink_inode_operations;
else
init_special_inode(inode, inode->i_mode,
SWAB32(ufs_inode->ui_u2.ui_addr.ui_db[0]));
diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c
index 278f8826a..497f69867 100644
--- a/fs/ufs/namei.c
+++ b/fs/ufs/namei.c
@@ -751,55 +751,42 @@ end_unlink:
int ufs_symlink (struct inode * dir, struct dentry * dentry,
const char * symname)
{
- struct super_block * sb;
+ struct super_block * sb = dir->i_sb;
struct ufs_dir_entry * de;
struct inode * inode;
- struct buffer_head * bh, * name_block;
- char * link;
- unsigned i, l;
+ struct buffer_head * bh = NULL;
+ unsigned l;
int err;
- char c;
- unsigned swab;
+ unsigned swab = sb->u.ufs_sb.s_swab;
UFSD(("ENTER\n"))
- sb = dir->i_sb;
- swab = sb->u.ufs_sb.s_swab;
- bh = name_block = NULL;
+
+ err = -ENAMETOOLONG;
+ l = strlen(symname)+1;
+ if (l > dir->i_sb->s_blocksize)
+ goto out;
+
err = -EIO;
if (!(inode = ufs_new_inode (dir, S_IFLNK, &err))) {
return err;
}
inode->i_mode = S_IFLNK | S_IRWXUGO;
- inode->i_op = &ufs_symlink_inode_operations;
- for (l = 0; l < sb->s_blocksize - 1 && symname [l]; l++);
- /***if (l >= sizeof (inode->u.ufs_i.i_data)) {***/
+ /***if (l > sizeof (inode->u.ufs_i.i_data)) {***/
if (1) {
/* slow symlink */
- name_block = ufs_bread (inode, 0, 1, &err);
- if (!name_block) {
- inode->i_nlink--;
- mark_inode_dirty(inode);
- iput (inode);
- return err;
- }
- link = name_block->b_data;
-
+ inode->i_op = &ufs_symlink_inode_operations;
+ err = block_symlink(inode, symname, l);
+ if (err)
+ goto out_no_entry;
} else {
/* fast symlink */
- link = (char *) inode->u.ufs_i.i_u1.i_data;
- }
- i = 0;
- while (i < sb->s_blocksize - 1 && (c = *(symname++)))
- link[i++] = c;
- link[i] = 0;
- if (name_block) {
- mark_buffer_dirty(name_block, 1);
- brelse (name_block);
+ inode->i_op = &ufs_fast_symlink_inode_operations;
+ memcpy((char*)&inode->u.ufs_i.i_u1.i_data,symname,l);
+ inode->i_size = l-1;
}
- inode->i_size = i;
mark_inode_dirty(inode);
bh = ufs_add_entry (dir, dentry->d_name.name, dentry->d_name.len, &de, &err);
@@ -828,16 +815,12 @@ out_no_entry:
int ufs_link (struct dentry * old_dentry, struct inode * dir,
struct dentry *dentry)
{
- struct super_block * sb;
struct inode *inode = old_dentry->d_inode;
+ struct super_block * sb = inode->i_sb;
struct ufs_dir_entry * de;
struct buffer_head * bh;
int err;
- unsigned swab;
-
- inode = old_dentry->d_inode;
- sb = inode->i_sb;
- swab = sb->u.ufs_sb.s_swab;
+ unsigned swab = sb->u.ufs_sb.s_swab;
if (S_ISDIR(inode->i_mode))
return -EPERM;
diff --git a/fs/ufs/symlink.c b/fs/ufs/symlink.c
index 3df5c40a6..06ee82740 100644
--- a/fs/ufs/symlink.c
+++ b/fs/ufs/symlink.c
@@ -23,118 +23,29 @@
* ext2 symlink handling code
*/
-#include <asm/uaccess.h>
-
-#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/ufs_fs.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/stat.h>
-
-
-#undef UFS_SYMLINK_DEBUG
-#ifdef UFS_SYMLINK_DEBUG
-#define UFSD(x) printk("(%s, %d), %s:", __FILE__, __LINE__, __FUNCTION__); printk x;
-#else
-#define UFSD(x)
-#endif
-
-
-static struct dentry * ufs_follow_link(struct dentry * dentry,
- struct dentry * base, unsigned int follow)
+static int ufs_readlink(struct dentry *dentry, char *buffer, int buflen)
{
- struct inode * inode;
- struct buffer_head * bh;
- int error;
- char * link;
-
- UFSD(("ENTER\n"))
-
- inode = dentry->d_inode;
- bh = NULL;
- /* slow symlink */
- if (inode->i_blocks) {
- if (!(bh = ufs_bread (inode, 0, 0, &error))) {
- dput(base);
- return ERR_PTR(-EIO);
- }
- link = bh->b_data;
- }
- /* fast symlink */
- else {
- link = (char *) inode->u.ufs_i.i_u1.i_symlink;
- }
- UPDATE_ATIME(inode);
- base = lookup_dentry(link, base, follow);
- if (bh)
- brelse(bh);
- UFSD(("EXIT\n"))
- return base;
+ char *s = (char *)dentry->d_inode->u.ufs_i.i_u1.i_symlink;
+ return vfs_readlink(dentry, buffer, buflen, s);
}
-static int ufs_readlink (struct dentry * dentry, char * buffer, int buflen)
+static struct dentry *ufs_follow_link(struct dentry *dentry, struct dentry *base, unsigned flags)
{
- struct super_block * sb;
- struct inode * inode;
- struct buffer_head * bh;
- char * link;
- int i;
-
- UFSD(("ENTER\n"))
-
- inode = dentry->d_inode;
- sb = inode->i_sb;
- bh = NULL;
- if (buflen > sb->s_blocksize - 1)
- buflen = sb->s_blocksize - 1;
- /* slow symlink */
- if (inode->i_blocks) {
- int err;
- bh = ufs_bread (inode, 0, 0, &err);
- if (!bh) {
- if(err < 0) /* indicate type of error */
- return err;
- return 0;
- }
- link = bh->b_data;
- }
- /* fast symlink */
- else {
- link = (char *) inode->u.ufs_i.i_u1.i_symlink;
- }
- i = 0;
- while (i < buflen && link[i])
- i++;
- if (copy_to_user(buffer, link, i))
- i = -EFAULT;
- UPDATE_ATIME(inode);
- if (bh)
- brelse (bh);
- UFSD(("ENTER\n"))
- return i;
+ char *s = (char *)dentry->d_inode->u.ufs_i.i_u1.i_symlink;
+ return vfs_follow_link(dentry, base, flags, s);
}
+struct inode_operations ufs_fast_symlink_inode_operations = {
+ readlink: ufs_readlink,
+ follow_link: ufs_follow_link,
+};
+
struct inode_operations ufs_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 */
- ufs_readlink, /* readlink */
- ufs_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: ufs_getfrag_block,
+ readpage: block_read_full_page
};
diff --git a/fs/ufs/truncate.c b/fs/ufs/truncate.c
index 2d33bd3c9..57de81eb8 100644
--- a/fs/ufs/truncate.c
+++ b/fs/ufs/truncate.c
@@ -63,7 +63,7 @@
#define DIRECT_FRAGMENT ((inode->i_size + uspi->s_fsize - 1) >> uspi->s_fshift)
#define DATA_BUFFER_USED(bh) \
- (atomic_read(&bh->b_count) || buffer_locked(bh))
+ (atomic_read(&bh->b_count)>1 || buffer_locked(bh))
static int ufs_trunc_direct (struct inode * inode)
{