From 33263fc5f9ac8e8cb2b22d06af3ce5ac1dd815e4 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Fri, 4 Feb 2000 07:40:19 +0000 Subject: Merge with Linux 2.3.32. --- fs/affs/dir.c | 2 - fs/affs/file.c | 4 -- fs/affs/symlink.c | 143 ++++++++++++------------------------------------------ 3 files changed, 31 insertions(+), 118 deletions(-) (limited to 'fs/affs') diff --git a/fs/affs/dir.c b/fs/affs/dir.c index b88eac770..f126dcbb8 100644 --- a/fs/affs/dir.c +++ b/fs/affs/dir.c @@ -60,10 +60,8 @@ struct inode_operations affs_dir_inode_operations = { NULL, /* get_block */ NULL, /* readpage */ NULL, /* writepage */ - NULL, /* flushpage */ NULL, /* truncate */ NULL, /* permissions */ - NULL, /* smap */ NULL /* revalidate */ }; diff --git a/fs/affs/file.c b/fs/affs/file.c index 358c1c56c..e32b9c344 100644 --- a/fs/affs/file.c +++ b/fs/affs/file.c @@ -77,10 +77,8 @@ struct inode_operations affs_file_inode_operations = { affs_bmap, /* get_block */ block_read_full_page, /* readpage */ NULL, /* writepage */ - NULL, /* flushpage */ affs_truncate, /* truncate */ NULL, /* permission */ - NULL, /* smap */ NULL /* revalidate */ }; @@ -118,10 +116,8 @@ struct inode_operations affs_file_inode_operations_ofs = { NULL, /* get_block */ NULL, /* readpage */ NULL, /* writepage */ - NULL, /* flushpage */ affs_truncate, /* truncate */ NULL, /* permission */ - NULL, /* smap */ NULL /* revalidate */ }; diff --git a/fs/affs/symlink.c b/fs/affs/symlink.c index 18c03730f..6aad1c222 100644 --- a/fs/affs/symlink.c +++ b/fs/affs/symlink.c @@ -9,103 +9,19 @@ */ #include -#include -#include #include #include #include #include -#include +#include -#define MIN(a,b) (((a) < (b)) ? (a) : (b)) - -static int affs_readlink(struct dentry *, char *, int); -static struct dentry *affs_follow_link(struct dentry *dentry, struct dentry *base, unsigned int); - -struct inode_operations affs_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 */ - affs_readlink, /* readlink */ - affs_follow_link, /* follow_link */ - NULL, /* get_block */ - NULL, /* readpage */ - NULL, /* writepage */ - NULL, /* flushpage */ - NULL, /* truncate */ - NULL, /* permission */ - NULL, /* smap */ - NULL /* revalidate */ -}; - -static int -affs_readlink(struct dentry *dentry, char *buffer, int buflen) +static int affs_symlink_readpage(struct dentry *dentry, struct page *page) { + struct buffer_head *bh; struct inode *inode = dentry->d_inode; - struct buffer_head *bh; - struct slink_front *lf; - int i, j; - char c; - char lc; - char *pf; - - pr_debug("AFFS: readlink(ino=%lu,buflen=%d)\n",inode->i_ino,buflen); - - bh = affs_bread(inode->i_dev,inode->i_ino,AFFS_I2BSIZE(inode)); - if (!bh) { - affs_warning(inode->i_sb,"follow_link","Unable to read i-node block %lu\n", - inode->i_ino); - return -EIO; - } - lf = (struct slink_front *)bh->b_data; - lc = 0; - i = 0; - j = 0; - pf = inode->i_sb->u.affs_sb.s_prefix ? inode->i_sb->u.affs_sb.s_prefix : "/"; - - if (strchr(lf->symname,':')) { /* Handle assign or volume name */ - while (i < buflen && (c = pf[i])) { - put_user(c,buffer++); - i++; - } - while (i < buflen && (c = lf->symname[j]) != ':') { - put_user(c,buffer++); - i++, j++; - } - if (i < buflen) { - put_user('/',buffer++); - i++, j++; - } - lc = '/'; - } - while (i < buflen && (c = lf->symname[j])) { - if (c == '/' && lc == '/' && (i + 3 < buflen)) { /* parent dir */ - put_user('.',buffer++); - put_user('.',buffer++); - i += 2; - } - put_user(c,buffer++); - lc = c; - i++, j++; - } - affs_brelse(bh); - return i; -} - -static struct dentry * -affs_follow_link(struct dentry *dentry, struct dentry *base, unsigned int follow) -{ - struct inode *inode = dentry->d_inode; - struct buffer_head *bh; - struct slink_front *lf; - char *buffer; + char *link = (char*)kmap(page); + struct slink_front *lf; + int err; int i, j; char c; char lc; @@ -113,47 +29,50 @@ affs_follow_link(struct dentry *dentry, struct dentry *base, unsigned int follow pr_debug("AFFS: follow_link(ino=%lu)\n",inode->i_ino); - if (!(buffer = kmalloc(1024,GFP_KERNEL))) { - dput(base); - return ERR_PTR(-ENOSPC); - } + err = -EIO; bh = affs_bread(inode->i_dev,inode->i_ino,AFFS_I2BSIZE(inode)); - if (!bh) { - affs_warning(inode->i_sb,"follow_link","Unable to read i-node block %lu\n", - inode->i_ino); - kfree(buffer); - dput(base); - return ERR_PTR(-EIO); - } + if (!bh) + goto fail; i = 0; j = 0; lf = (struct slink_front *)bh->b_data; lc = 0; pf = inode->i_sb->u.affs_sb.s_prefix ? inode->i_sb->u.affs_sb.s_prefix : "/"; - if (strchr(lf->symname,':')) { /* Handle assign or volume name */ + if (strchr(lf->symname,':')) { /* Handle assign or volume name */ while (i < 1023 && (c = pf[i])) - buffer[i++] = c; + link[i++] = c; while (i < 1023 && lf->symname[j] != ':') - buffer[i++] = lf->symname[j++]; + link[i++] = lf->symname[j++]; if (i < 1023) - buffer[i++] = '/'; + link[i++] = '/'; j++; lc = '/'; } while (i < 1023 && (c = lf->symname[j])) { if (c == '/' && lc == '/' && i < 1020) { /* parent dir */ - buffer[i++] = '.'; - buffer[i++] = '.'; + link[i++] = '.'; + link[i++] = '.'; } - buffer[i++] = c; + link[i++] = c; lc = c; j++; } - buffer[i] = '\0'; + link[i] = '\0'; affs_brelse(bh); - base = lookup_dentry(buffer,base,follow); - kfree(buffer); - return base; + SetPageUptodate(page); + kunmap(page); + UnlockPage(page); + return 0; +fail: + SetPageError(page); + kunmap(page); + UnlockPage(page); + return err; } +struct inode_operations affs_symlink_inode_operations = { + readlink: page_readlink, + follow_link: page_follow_link, + readpage: affs_symlink_readpage, +}; -- cgit v1.2.3