OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [before_ORP/] [uclinux/] [uClinux-2.0.x/] [fs/] [ufs/] [ufs_symlink.c] - Diff between revs 901 and 1765

Only display areas with differences | Details | Blame | View Log

Rev 901 Rev 1765
/*
/*
 *  linux/fs/ufs/ufs_symlink.c
 *  linux/fs/ufs/ufs_symlink.c
 *
 *
 * Copyright (C) 1996
 * Copyright (C) 1996
 * Adrian Rodriguez (adrian@franklins-tower.rutgers.edu)
 * Adrian Rodriguez (adrian@franklins-tower.rutgers.edu)
 * Laboratory for Computer Science Research Computing Facility
 * Laboratory for Computer Science Research Computing Facility
 * Rutgers, The State University of New Jersey
 * Rutgers, The State University of New Jersey
 *
 *
 * $Id: ufs_symlink.c,v 1.1.1.1 2001-09-10 07:44:40 simons Exp $
 * $Id: ufs_symlink.c,v 1.1.1.1 2001-09-10 07:44:40 simons Exp $
 *
 *
 */
 */
 
 
#include <linux/fs.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/sched.h>
 
 
#include <asm/segment.h>
#include <asm/segment.h>
 
 
extern int ufs_bmap (struct inode *, int);
extern int ufs_bmap (struct inode *, int);
 
 
static int
static int
ufs_readlink(struct inode * inode, char * buffer, int buflen)
ufs_readlink(struct inode * inode, char * buffer, int buflen)
{
{
        unsigned long int block;
        unsigned long int block;
        struct buffer_head * bh = NULL;
        struct buffer_head * bh = NULL;
        char * link;
        char * link;
        int i;
        int i;
        char c;
        char c;
 
 
        if (inode->i_sb->u.ufs_sb.s_flags & (UFS_DEBUG|UFS_DEBUG_LINKS)) {
        if (inode->i_sb->u.ufs_sb.s_flags & (UFS_DEBUG|UFS_DEBUG_LINKS)) {
                printk("ufs_readlink: called on ino %lu dev %u/%u\n",
                printk("ufs_readlink: called on ino %lu dev %u/%u\n",
                       inode->i_ino, MAJOR(inode->i_dev), MINOR(inode->i_dev));
                       inode->i_ino, MAJOR(inode->i_dev), MINOR(inode->i_dev));
        }
        }
 
 
        if (!S_ISLNK(inode->i_mode)) {
        if (!S_ISLNK(inode->i_mode)) {
                iput (inode);
                iput (inode);
                return -EINVAL;
                return -EINVAL;
        }
        }
        if (buflen > inode->i_sb->s_blocksize - 1)
        if (buflen > inode->i_sb->s_blocksize - 1)
                buflen = inode->i_sb->s_blocksize - 1;
                buflen = inode->i_sb->s_blocksize - 1;
        if (inode->i_blocks) {
        if (inode->i_blocks) {
                /* XXX - error checking */
                /* XXX - error checking */
                block = ufs_bmap(inode, 0);
                block = ufs_bmap(inode, 0);
                if (inode->i_sb->u.ufs_sb.s_flags &(UFS_DEBUG|UFS_DEBUG_LINKS)) {
                if (inode->i_sb->u.ufs_sb.s_flags &(UFS_DEBUG|UFS_DEBUG_LINKS)) {
                        printk("ufs_readlink: bmap got %lu for ino %lu\n",
                        printk("ufs_readlink: bmap got %lu for ino %lu\n",
                               block, inode->i_ino);
                               block, inode->i_ino);
                }
                }
                bh = bread(inode->i_dev, block, BLOCK_SIZE);
                bh = bread(inode->i_dev, block, BLOCK_SIZE);
                if (!bh) {
                if (!bh) {
                        iput (inode);
                        iput (inode);
                        printk("ufs_readlink: can't read block 0 for ino %lu on dev %u/%u\n",
                        printk("ufs_readlink: can't read block 0 for ino %lu on dev %u/%u\n",
                               inode->i_ino, MAJOR(inode->i_dev),
                               inode->i_ino, MAJOR(inode->i_dev),
                               MINOR(inode->i_dev));
                               MINOR(inode->i_dev));
                        return 0;
                        return 0;
                }
                }
                link = bh->b_data;
                link = bh->b_data;
        }
        }
        else {
        else {
                link = (char *)&(inode->u.ufs_i.ui_db[0]);
                link = (char *)&(inode->u.ufs_i.ui_db[0]);
        }
        }
        i = 0;
        i = 0;
        while (i < buflen && (c = link[i])) {
        while (i < buflen && (c = link[i])) {
                i++;
                i++;
                put_user (c, buffer++);
                put_user (c, buffer++);
        }
        }
        iput (inode);
        iput (inode);
        if (bh)
        if (bh)
                brelse (bh);
                brelse (bh);
        return i;
        return i;
}
}
 
 
/*
/*
 * XXX - blatantly stolen from ext2fs
 * XXX - blatantly stolen from ext2fs
 */
 */
static int
static int
ufs_follow_link(struct inode * dir, struct inode * inode,
ufs_follow_link(struct inode * dir, struct inode * inode,
                int flag, int mode, struct inode ** res_inode)
                int flag, int mode, struct inode ** res_inode)
{
{
        unsigned long int block;
        unsigned long int block;
        int error;
        int error;
        struct buffer_head * bh;
        struct buffer_head * bh;
        char * link;
        char * link;
 
 
        bh = NULL;
        bh = NULL;
 
 
        if (inode->i_sb->u.ufs_sb.s_flags & (UFS_DEBUG|UFS_DEBUG_LINKS)) {
        if (inode->i_sb->u.ufs_sb.s_flags & (UFS_DEBUG|UFS_DEBUG_LINKS)) {
                printk("ufs_follow_link: called on ino %lu dev %u/%u\n",
                printk("ufs_follow_link: called on ino %lu dev %u/%u\n",
                       dir->i_ino, MAJOR(dir->i_dev), MINOR(dir->i_dev));
                       dir->i_ino, MAJOR(dir->i_dev), MINOR(dir->i_dev));
        }
        }
 
 
        *res_inode = NULL;
        *res_inode = NULL;
        if (!dir) {
        if (!dir) {
                dir = current->fs->root;
                dir = current->fs->root;
                dir->i_count++;
                dir->i_count++;
        }
        }
        if (!inode) {
        if (!inode) {
                iput (dir);
                iput (dir);
                return -ENOENT;
                return -ENOENT;
        }
        }
        if (!S_ISLNK(inode->i_mode)) {
        if (!S_ISLNK(inode->i_mode)) {
                iput (dir);
                iput (dir);
                *res_inode = inode;
                *res_inode = inode;
                return 0;
                return 0;
        }
        }
        if (current->link_count > 5) {
        if (current->link_count > 5) {
                iput (dir);
                iput (dir);
                iput (inode);
                iput (inode);
                return -ELOOP;
                return -ELOOP;
        }
        }
        if (inode->i_blocks) {
        if (inode->i_blocks) {
                /* read the link from disk */
                /* read the link from disk */
                /* XXX - error checking */
                /* XXX - error checking */
                block = ufs_bmap(inode, 0);
                block = ufs_bmap(inode, 0);
                bh = bread(inode->i_dev, block, BLOCK_SIZE);
                bh = bread(inode->i_dev, block, BLOCK_SIZE);
                if (bh == NULL) {
                if (bh == NULL) {
                        printk("ufs_follow_link: can't read block 0 for ino %lu on dev %u/%u\n",
                        printk("ufs_follow_link: can't read block 0 for ino %lu on dev %u/%u\n",
                               inode->i_ino, MAJOR(inode->i_dev),
                               inode->i_ino, MAJOR(inode->i_dev),
                               MINOR(inode->i_dev));
                               MINOR(inode->i_dev));
                        iput(dir);
                        iput(dir);
                        iput(inode);
                        iput(inode);
                        return(-EIO);
                        return(-EIO);
                }
                }
                link = bh->b_data;
                link = bh->b_data;
        } else {
        } else {
                /* fast symlink */
                /* fast symlink */
                link = (char *)&(inode->u.ufs_i.ui_db[0]);
                link = (char *)&(inode->u.ufs_i.ui_db[0]);
        }
        }
        current->link_count++;
        current->link_count++;
        error = open_namei (link, flag, mode, res_inode, dir);
        error = open_namei (link, flag, mode, res_inode, dir);
        current->link_count--;
        current->link_count--;
        iput (inode);
        iput (inode);
        if (bh) {
        if (bh) {
                brelse (bh);
                brelse (bh);
        }
        }
        return(error);
        return(error);
}
}
 
 
 
 
static struct file_operations ufs_symlink_operations = {
static struct file_operations ufs_symlink_operations = {
        NULL,                   /* lseek */
        NULL,                   /* lseek */
        NULL,                   /* read */
        NULL,                   /* read */
        NULL,                   /* write */
        NULL,                   /* write */
        NULL,                   /* readdir */
        NULL,                   /* readdir */
        NULL,                   /* select */
        NULL,                   /* select */
        NULL,                   /* ioctl */
        NULL,                   /* ioctl */
        NULL,                   /* mmap */
        NULL,                   /* mmap */
        NULL,                   /* open */
        NULL,                   /* open */
        NULL,                   /* release */
        NULL,                   /* release */
        NULL,                   /* fsync */  /* XXX - is this ok? */
        NULL,                   /* fsync */  /* XXX - is this ok? */
        NULL,                   /* fasync */
        NULL,                   /* fasync */
        NULL,                   /* check_media_change */
        NULL,                   /* check_media_change */
        NULL,                   /* revalidate */
        NULL,                   /* revalidate */
};
};
 
 
struct inode_operations ufs_symlink_inode_operations = {
struct inode_operations ufs_symlink_inode_operations = {
        &ufs_symlink_operations,        /* default directory file operations */
        &ufs_symlink_operations,        /* default directory file operations */
        NULL,                   /* create */
        NULL,                   /* create */
        NULL,                   /* lookup */
        NULL,                   /* lookup */
        NULL,                   /* link */
        NULL,                   /* link */
        NULL,                   /* unlink */
        NULL,                   /* unlink */
        NULL,                   /* symlink */
        NULL,                   /* symlink */
        NULL,                   /* mkdir */
        NULL,                   /* mkdir */
        NULL,                   /* rmdir */
        NULL,                   /* rmdir */
        NULL,                   /* mknod */
        NULL,                   /* mknod */
        NULL,                   /* rename */
        NULL,                   /* rename */
        &ufs_readlink,          /* readlink */
        &ufs_readlink,          /* readlink */
        &ufs_follow_link,       /* follow_link */
        &ufs_follow_link,       /* follow_link */
        NULL,                   /* readpage */
        NULL,                   /* readpage */
        NULL,                   /* writepage */
        NULL,                   /* writepage */
        NULL,                   /* bmap */
        NULL,                   /* bmap */
        NULL,                   /* truncate */
        NULL,                   /* truncate */
        NULL,                   /* permission */
        NULL,                   /* permission */
        NULL,                   /* smap */
        NULL,                   /* smap */
};
};
 
 
/*
/*
 * Local Variables: ***
 * Local Variables: ***
 * c-indent-level: 8 ***
 * c-indent-level: 8 ***
 * c-continued-statement-offset: 8 ***
 * c-continued-statement-offset: 8 ***
 * c-brace-offset: -8 ***
 * c-brace-offset: -8 ***
 * c-argdecl-indent: 0 ***
 * c-argdecl-indent: 0 ***
 * c-label-offset: -8 ***
 * c-label-offset: -8 ***
 * End: ***
 * End: ***
 */
 */
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.