diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-02-04 07:40:19 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-02-04 07:40:19 +0000 |
commit | 33263fc5f9ac8e8cb2b22d06af3ce5ac1dd815e4 (patch) | |
tree | 2d1b86a40bef0958a68cf1a2eafbeb0667a70543 /fs/ufs | |
parent | 216f5f51aa02f8b113aa620ebc14a9631a217a00 (diff) |
Merge with Linux 2.3.32.
Diffstat (limited to 'fs/ufs')
-rw-r--r-- | fs/ufs/dir.c | 2 | ||||
-rw-r--r-- | fs/ufs/file.c | 2 | ||||
-rw-r--r-- | fs/ufs/inode.c | 4 | ||||
-rw-r--r-- | fs/ufs/namei.c | 57 | ||||
-rw-r--r-- | fs/ufs/symlink.c | 119 | ||||
-rw-r--r-- | fs/ufs/truncate.c | 2 |
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) { |