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] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*
2
 *  linux/fs/ufs/ufs_symlink.c
3
 *
4
 * Copyright (C) 1996
5
 * Adrian Rodriguez (adrian@franklins-tower.rutgers.edu)
6
 * Laboratory for Computer Science Research Computing Facility
7
 * Rutgers, The State University of New Jersey
8
 *
9
 * $Id: ufs_symlink.c,v 1.1.1.1 2001-09-10 07:44:40 simons Exp $
10
 *
11
 */
12
 
13
#include <linux/fs.h>
14
#include <linux/sched.h>
15
 
16
#include <asm/segment.h>
17
 
18
extern int ufs_bmap (struct inode *, int);
19
 
20
static int
21
ufs_readlink(struct inode * inode, char * buffer, int buflen)
22
{
23
        unsigned long int block;
24
        struct buffer_head * bh = NULL;
25
        char * link;
26
        int i;
27
        char c;
28
 
29
        if (inode->i_sb->u.ufs_sb.s_flags & (UFS_DEBUG|UFS_DEBUG_LINKS)) {
30
                printk("ufs_readlink: called on ino %lu dev %u/%u\n",
31
                       inode->i_ino, MAJOR(inode->i_dev), MINOR(inode->i_dev));
32
        }
33
 
34
        if (!S_ISLNK(inode->i_mode)) {
35
                iput (inode);
36
                return -EINVAL;
37
        }
38
        if (buflen > inode->i_sb->s_blocksize - 1)
39
                buflen = inode->i_sb->s_blocksize - 1;
40
        if (inode->i_blocks) {
41
                /* XXX - error checking */
42
                block = ufs_bmap(inode, 0);
43
                if (inode->i_sb->u.ufs_sb.s_flags &(UFS_DEBUG|UFS_DEBUG_LINKS)) {
44
                        printk("ufs_readlink: bmap got %lu for ino %lu\n",
45
                               block, inode->i_ino);
46
                }
47
                bh = bread(inode->i_dev, block, BLOCK_SIZE);
48
                if (!bh) {
49
                        iput (inode);
50
                        printk("ufs_readlink: can't read block 0 for ino %lu on dev %u/%u\n",
51
                               inode->i_ino, MAJOR(inode->i_dev),
52
                               MINOR(inode->i_dev));
53
                        return 0;
54
                }
55
                link = bh->b_data;
56
        }
57
        else {
58
                link = (char *)&(inode->u.ufs_i.ui_db[0]);
59
        }
60
        i = 0;
61
        while (i < buflen && (c = link[i])) {
62
                i++;
63
                put_user (c, buffer++);
64
        }
65
        iput (inode);
66
        if (bh)
67
                brelse (bh);
68
        return i;
69
}
70
 
71
/*
72
 * XXX - blatantly stolen from ext2fs
73
 */
74
static int
75
ufs_follow_link(struct inode * dir, struct inode * inode,
76
                int flag, int mode, struct inode ** res_inode)
77
{
78
        unsigned long int block;
79
        int error;
80
        struct buffer_head * bh;
81
        char * link;
82
 
83
        bh = NULL;
84
 
85
        if (inode->i_sb->u.ufs_sb.s_flags & (UFS_DEBUG|UFS_DEBUG_LINKS)) {
86
                printk("ufs_follow_link: called on ino %lu dev %u/%u\n",
87
                       dir->i_ino, MAJOR(dir->i_dev), MINOR(dir->i_dev));
88
        }
89
 
90
        *res_inode = NULL;
91
        if (!dir) {
92
                dir = current->fs->root;
93
                dir->i_count++;
94
        }
95
        if (!inode) {
96
                iput (dir);
97
                return -ENOENT;
98
        }
99
        if (!S_ISLNK(inode->i_mode)) {
100
                iput (dir);
101
                *res_inode = inode;
102
                return 0;
103
        }
104
        if (current->link_count > 5) {
105
                iput (dir);
106
                iput (inode);
107
                return -ELOOP;
108
        }
109
        if (inode->i_blocks) {
110
                /* read the link from disk */
111
                /* XXX - error checking */
112
                block = ufs_bmap(inode, 0);
113
                bh = bread(inode->i_dev, block, BLOCK_SIZE);
114
                if (bh == NULL) {
115
                        printk("ufs_follow_link: can't read block 0 for ino %lu on dev %u/%u\n",
116
                               inode->i_ino, MAJOR(inode->i_dev),
117
                               MINOR(inode->i_dev));
118
                        iput(dir);
119
                        iput(inode);
120
                        return(-EIO);
121
                }
122
                link = bh->b_data;
123
        } else {
124
                /* fast symlink */
125
                link = (char *)&(inode->u.ufs_i.ui_db[0]);
126
        }
127
        current->link_count++;
128
        error = open_namei (link, flag, mode, res_inode, dir);
129
        current->link_count--;
130
        iput (inode);
131
        if (bh) {
132
                brelse (bh);
133
        }
134
        return(error);
135
}
136
 
137
 
138
static struct file_operations ufs_symlink_operations = {
139
        NULL,                   /* lseek */
140
        NULL,                   /* read */
141
        NULL,                   /* write */
142
        NULL,                   /* readdir */
143
        NULL,                   /* select */
144
        NULL,                   /* ioctl */
145
        NULL,                   /* mmap */
146
        NULL,                   /* open */
147
        NULL,                   /* release */
148
        NULL,                   /* fsync */  /* XXX - is this ok? */
149
        NULL,                   /* fasync */
150
        NULL,                   /* check_media_change */
151
        NULL,                   /* revalidate */
152
};
153
 
154
struct inode_operations ufs_symlink_inode_operations = {
155
        &ufs_symlink_operations,        /* default directory file operations */
156
        NULL,                   /* create */
157
        NULL,                   /* lookup */
158
        NULL,                   /* link */
159
        NULL,                   /* unlink */
160
        NULL,                   /* symlink */
161
        NULL,                   /* mkdir */
162
        NULL,                   /* rmdir */
163
        NULL,                   /* mknod */
164
        NULL,                   /* rename */
165
        &ufs_readlink,          /* readlink */
166
        &ufs_follow_link,       /* follow_link */
167
        NULL,                   /* readpage */
168
        NULL,                   /* writepage */
169
        NULL,                   /* bmap */
170
        NULL,                   /* truncate */
171
        NULL,                   /* permission */
172
        NULL,                   /* smap */
173
};
174
 
175
/*
176
 * Local Variables: ***
177
 * c-indent-level: 8 ***
178
 * c-continued-statement-offset: 8 ***
179
 * c-brace-offset: -8 ***
180
 * c-argdecl-indent: 0 ***
181
 * c-label-offset: -8 ***
182
 * End: ***
183
 */

powered by: WebSVN 2.1.0

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