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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [rc203soc/] [sw/] [uClinux/] [fs/] [xiafs/] [symlink.c] - Diff between revs 1628 and 1765

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 1628 Rev 1765
/*
/*
 *  linux/fs/xiafs/symlink.c
 *  linux/fs/xiafs/symlink.c
 *
 *
 *  Copyright (C) Q. Frank Xia, 1993.
 *  Copyright (C) Q. Frank Xia, 1993.
 *
 *
 *  Based on Linus' minix/symlink.c
 *  Based on Linus' minix/symlink.c
 *  Copyright (C) Linus Torvalds, 1991, 1992.
 *  Copyright (C) Linus Torvalds, 1991, 1992.
 *
 *
 *  This software may be redistributed per Linux Copyright.
 *  This software may be redistributed per Linux Copyright.
 */
 */
 
 
#include <linux/errno.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/fs.h>
#include <linux/xia_fs.h>
#include <linux/xia_fs.h>
#include <linux/stat.h>
#include <linux/stat.h>
 
 
#include <asm/segment.h>
#include <asm/segment.h>
 
 
static int
static int
xiafs_readlink(struct inode *, char *, int);
xiafs_readlink(struct inode *, char *, int);
 
 
static int
static int
xiafs_follow_link(struct inode *, struct inode *, int, int, struct inode **);
xiafs_follow_link(struct inode *, struct inode *, int, int, struct inode **);
 
 
/*
/*
 * symlinks can't do much...
 * symlinks can't do much...
 */
 */
struct inode_operations xiafs_symlink_inode_operations = {
struct inode_operations xiafs_symlink_inode_operations = {
        NULL,                   /* no file-operations */
        NULL,                   /* no 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 */
        xiafs_readlink,         /* readlink */
        xiafs_readlink,         /* readlink */
        xiafs_follow_link,      /* follow_link */
        xiafs_follow_link,      /* follow_link */
        NULL,                   /* readpage */
        NULL,                   /* readpage */
        NULL,                   /* writepage */
        NULL,                   /* writepage */
        NULL,                   /* bmap */
        NULL,                   /* bmap */
        NULL,                   /* truncate */
        NULL,                   /* truncate */
        NULL                    /* permission */
        NULL                    /* permission */
};
};
 
 
static int xiafs_readlink(struct inode * inode, char * buffer, int buflen)
static int xiafs_readlink(struct inode * inode, char * buffer, int buflen)
{
{
    struct buffer_head * bh;
    struct buffer_head * bh;
    int i;
    int i;
    char c;
    char c;
 
 
    if (!S_ISLNK(inode->i_mode)) {
    if (!S_ISLNK(inode->i_mode)) {
        iput(inode);
        iput(inode);
        return -EINVAL;
        return -EINVAL;
    }
    }
    if (buflen > BLOCK_SIZE)
    if (buflen > BLOCK_SIZE)
        buflen = BLOCK_SIZE;
        buflen = BLOCK_SIZE;
    bh = xiafs_bread(inode, 0, 0);
    bh = xiafs_bread(inode, 0, 0);
    if (!IS_RDONLY (inode)) {
    if (!IS_RDONLY (inode)) {
        inode->i_atime=CURRENT_TIME;
        inode->i_atime=CURRENT_TIME;
        inode->i_dirt=1;
        inode->i_dirt=1;
    }
    }
    iput(inode);
    iput(inode);
    if (!bh)
    if (!bh)
        return 0;
        return 0;
    for (i=0; i < buflen && (c=bh->b_data[i]); i++)
    for (i=0; i < buflen && (c=bh->b_data[i]); i++)
      put_user(c, buffer++);
      put_user(c, buffer++);
    if (i < buflen-1)
    if (i < buflen-1)
      put_user('\0', buffer);
      put_user('\0', buffer);
    brelse(bh);
    brelse(bh);
    return i;
    return i;
}
}
 
 
static int xiafs_follow_link(struct inode * dir, struct inode * inode,
static int xiafs_follow_link(struct inode * dir, struct inode * inode,
        int flag, int mode, struct inode ** res_inode)
        int flag, int mode, struct inode ** res_inode)
{
{
    int error;
    int error;
    struct buffer_head * bh;
    struct buffer_head * bh;
 
 
    *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 (!IS_RDONLY (inode)) {
    if (!IS_RDONLY (inode)) {
        inode->i_atime=CURRENT_TIME;
        inode->i_atime=CURRENT_TIME;
        inode->i_dirt=1;
        inode->i_dirt=1;
    }
    }
    if (current->link_count > 5) {
    if (current->link_count > 5) {
        iput(inode);
        iput(inode);
        iput(dir);
        iput(dir);
        return -ELOOP;
        return -ELOOP;
    }
    }
    if (!(bh = xiafs_bread(inode, 0, 0))) {
    if (!(bh = xiafs_bread(inode, 0, 0))) {
        iput(inode);
        iput(inode);
        iput(dir);
        iput(dir);
        return -EIO;
        return -EIO;
    }
    }
    iput(inode);
    iput(inode);
    current->link_count++;
    current->link_count++;
    error = open_namei(bh->b_data,flag,mode,res_inode,dir);
    error = open_namei(bh->b_data,flag,mode,res_inode,dir);
    current->link_count--;
    current->link_count--;
    brelse(bh);
    brelse(bh);
    return error;
    return error;
}
}
 
 
 
 
 
 
 
 

powered by: WebSVN 2.1.0

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