Whamcloud - gitweb
Update copyright and license information.
[fs/lustre-release.git] / lustre / obdfs / symlink.c
index f1e0a5d..a42c0ab 100644 (file)
@@ -1,6 +1,9 @@
 /*
  *  linux/fs/ext2/symlink.c
  *
+ * This code is issued under the GNU General Public License.
+ * See the file COPYING in this distribution
+ *
  * Copyright (C) 1992, 1993, 1994, 1995
  * Remy Card (card@masi.ibp.fr)
  * Laboratoire MASI - Institut Blaise Pascal
  *  Copyright (C) 1999 Seagate Technology Inc. (author: braam@stelias.com)
  */
 
-#include <asm/uaccess.h>
-
-#include <linux/errno.h>
 #include <linux/fs.h>
-#include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/stat.h>
 #include <linux/locks.h>
-
 #include <linux/obd_support.h> /* for ENTRY and EXIT only */
 #include <linux/obdfs.h>
 
-static struct dentry * obdfs_follow_link(struct dentry * dentry,
-                                        struct dentry *base,
-                                        unsigned int follow)
+static int obdfs_fast_readlink(struct dentry *dentry, char *buffer, int buflen)
 {
-       struct inode *inode = dentry->d_inode;
-       struct page *page = NULL;
-       char * link;
-
-       ENTRY;
-       link = obdfs_i2info(inode)->oi_inline;
-       if (!obdfs_has_inline(inode)) {
-               OIDEBUG(inode);
-               page = obdfs_getpage(inode, 0, 0, 0);
-               PDEBUG(page, "follow_link");
-               if (!page) {
-                       dput(base);
-                       EXIT;
-                       return ERR_PTR(-EIO);
-               }
-               link = (char *)page_address(page);
-       }
-       UPDATE_ATIME(inode);
-       base = lookup_dentry(link, base, follow);
-       if (page) {
-               page_cache_release(page);
-       }
-       EXIT;
-       return base;
+        char *s = obdfs_i2info(dentry->d_inode)->oi_inline;
+        return vfs_readlink(dentry, buffer, buflen, s);
 }
 
-static int obdfs_readlink (struct dentry * dentry, char * buffer, int buflen)
+static int obdfs_fast_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
-       struct inode *inode = dentry->d_inode;
-       struct page *page = NULL;
-       char * link;
-       int i;
+        char *s = obdfs_i2info(dentry->d_inode)->oi_inline;
+        return vfs_follow_link(nd, s); 
+}
 
-       ENTRY;
-       if (buflen > inode->i_sb->s_blocksize - 1)
-               buflen = inode->i_sb->s_blocksize - 1;
+struct inode_operations obdfs_fast_symlink_inode_operations = {
+        readlink:       obdfs_fast_readlink,
+        follow_link:    obdfs_fast_follow_link,
+};
 
-       link = obdfs_i2info(inode)->oi_inline;
-       if (!obdfs_has_inline(inode)) {
-               OIDEBUG(inode);
-               page = obdfs_getpage(inode, 0, 0, 0);
-               PDEBUG(page, "readlink");
-               if (!page) {
-                       EXIT;
-                       return 0;
-               }
-               link = (char *)page_address(page);
-       }
+static int obdfs_readlink(struct dentry *dentry, char *buffer, int buflen)
+{
+        struct page *page = NULL;
+        int res;
 
-       i = 0;
-       while (i < buflen && link[i])
-               i++;
-       if (copy_to_user(buffer, link, i))
-               i = -EFAULT;
-       if (page) {
-               page_cache_release(page);
-       }
-       EXIT;
-       return i;
+        ENTRY;
+        OIDEBUG(dentry->d_inode);
+        page = obdfs_getpage(dentry->d_inode, 0, 0, 0);
+        /* PDEBUG(page, "readlink"); */
+        if (!page) {
+                EXIT;
+                return 0;
+        }
+        res = vfs_readlink(dentry, buffer, buflen, (char *)page_address(page));
+        page_cache_release(page);
+        EXIT;
+        return res;
 } /* obdfs_readlink */
 
-/*
- * symlinks can't do much...
- */
+static int obdfs_follow_link(struct dentry * dentry,
+                             struct nameidata *nd)
+{
+        struct page *page = NULL;
+        int res;
+
+        ENTRY;
+        OIDEBUG(dentry->d_inode);
+        page = obdfs_getpage(dentry->d_inode, 0, 0, 0);
+        /* PDEBUG(page, "follow_link"); */
+        if (!page) {
+                dput(nd->dentry);
+                EXIT;
+                return -EIO;
+        }
+        res = vfs_follow_link(nd, (char *)page_address(page));
+        page_cache_release(page);
+        EXIT;
+        return res;
+}
+
 struct inode_operations obdfs_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 */
-       obdfs_readlink,         /* readlink */
-       obdfs_follow_link,      /* follow_link */
-       NULL,                   /* get_block */
-       NULL,                   /* readpage */
-       NULL,                   /* writepage */
-       NULL,                   /* truncate */
-       NULL,                   /* permission */
-       NULL                    /* revalidate */
+        readlink:       obdfs_readlink,
+        follow_link:    obdfs_follow_link,
 };
-