Whamcloud - gitweb
New direcotory layout:
[fs/lustre-release.git] / lustre / obdfs / symlink.c
1 /*
2  *  linux/fs/ext2/symlink.c
3  *
4  * Copyright (C) 1992, 1993, 1994, 1995
5  * Remy Card (card@masi.ibp.fr)
6  * Laboratoire MASI - Institut Blaise Pascal
7  * Universite Pierre et Marie Curie (Paris VI)
8  *
9  *  from
10  *
11  *  linux/fs/minix/symlink.c
12  *
13  *  Copyright (C) 1991, 1992  Linus Torvalds
14  *
15  *  ext2 symlink handling code
16  *
17  * Modified for OBDFS: 
18  *  Copyright (C) 1999 Seagate Technology Inc. (author: braam@stelias.com)
19  */
20
21 #include <asm/uaccess.h>
22
23 #include <linux/errno.h>
24 #include <linux/fs.h>
25 #include <linux/ext2_fs.h>
26 #include <linux/sched.h>
27 #include <linux/mm.h>
28 #include <linux/stat.h>
29
30 static int obdfs_readlink (struct dentry *, char *, int);
31 static struct dentry *obdfs_follow_link(struct dentry *, struct dentry *, unsigned int);
32
33 static struct dentry * ext2_follow_link(struct dentry * dentry,
34                                         struct dentry *base,
35                                         unsigned int follow)
36 {
37         struct inode *inode = dentry->d_inode;
38         struct page *page = NULL;
39         int error;
40         char * link;
41
42         link = (char *) inode->u.ext2_i.i_data;
43         if (inode->i_blocks) {
44                 if (!(page = obdfs_getpage(inode, 0, 0, &error))) {
45                         dput(base);
46                         return ERR_PTR(-EIO);
47                 }
48                 link = bh->b_data;
49         }
50         UPDATE_ATIME(inode);
51         base = lookup_dentry(link, base, follow);
52         if (bh)
53                 brelse(bh);
54         return base;
55 }
56
57 static int ext2_readlink (struct dentry * dentry, char * buffer, int buflen)
58 {
59         struct inode *inode = dentry->d_inode;
60         struct buffer_head * bh = NULL;
61         char * link;
62         int i;
63
64         if (buflen > inode->i_sb->s_blocksize - 1)
65                 buflen = inode->i_sb->s_blocksize - 1;
66
67         link = (char *) inode->u.ext2_i.i_data;
68         if (inode->i_blocks) {
69                 int err;
70                 bh = ext2_bread (inode, 0, 0, &err);
71                 if (!bh) {
72                         if(err < 0) /* indicate type of error */
73                                 return err;
74                         return 0;
75                 }
76                 link = bh->b_data;
77         }
78
79         i = 0;
80         while (i < buflen && link[i])
81                 i++;
82         if (copy_to_user(buffer, link, i))
83                 i = -EFAULT;
84         if (bh)
85                 brelse (bh);
86         return i;
87 }