blob: 9725f9a55c837595ed154951fe5d29641a4a5019 [file] [log] [blame]
From ltsi-dev-bounces@lists.linuxfoundation.org Sat May 12 10:17:09 2012
From: Marco Stornelli <marco.stornelli@gmail.com>
Date: Sat, 12 May 2012 19:10:36 +0200
Subject: pramfs: symlinks
To: LTSI <ltsi-dev@lists.linuxfoundation.org>
Message-ID: <4FAE998C.1040504@gmail.com>
From: Marco Stornelli <marco.stornelli@gmail.com>
Symlink operations.
Signed-off-by: Marco Stornelli <marco.stornelli@gmail.com>
---
fs/pramfs/symlink.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 76 insertions(+)
--- /dev/null
+++ b/fs/pramfs/symlink.c
@@ -0,0 +1,76 @@
+/*
+ * BRIEF DESCRIPTION
+ *
+ * Symlink operations
+ *
+ * Copyright 2009-2011 Marco Stornelli <marco.stornelli@gmail.com>
+ * Copyright 2003 Sony Corporation
+ * Copyright 2003 Matsushita Electric Industrial Co., Ltd.
+ * 2003-2004 (c) MontaVista Software, Inc. , Steve Longerbeam
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/fs.h>
+#include "pram.h"
+#include "xattr.h"
+
+int pram_block_symlink(struct inode *inode, const char *symname, int len)
+{
+ struct super_block *sb = inode->i_sb;
+ u64 block;
+ char *blockp;
+ int err;
+
+ err = pram_alloc_blocks(inode, 0, 1);
+ if (err)
+ return err;
+
+ block = pram_find_data_block(inode, 0);
+ blockp = pram_get_block(sb, block);
+
+ pram_memunlock_block(sb, blockp);
+ memcpy(blockp, symname, len);
+ blockp[len] = '\0';
+ pram_memlock_block(sb, blockp);
+ return 0;
+}
+
+static int pram_readlink(struct dentry *dentry, char __user *buffer, int buflen)
+{
+ struct inode *inode = dentry->d_inode;
+ struct super_block *sb = inode->i_sb;
+ u64 block;
+ char *blockp;
+
+ block = pram_find_data_block(inode, 0);
+ blockp = pram_get_block(sb, block);
+ return vfs_readlink(dentry, buffer, buflen, blockp);
+}
+
+static void *pram_follow_link(struct dentry *dentry, struct nameidata *nd)
+{
+ struct inode *inode = dentry->d_inode;
+ struct super_block *sb = inode->i_sb;
+ off_t block;
+ int status;
+ char *blockp;
+
+ block = pram_find_data_block(inode, 0);
+ blockp = pram_get_block(sb, block);
+ status = vfs_follow_link(nd, blockp);
+ return ERR_PTR(status);
+}
+
+const struct inode_operations pram_symlink_inode_operations = {
+ .readlink = pram_readlink,
+ .follow_link = pram_follow_link,
+ .setattr = pram_notify_change,
+#ifdef CONFIG_PRAMFS_XATTR
+ .setxattr = generic_setxattr,
+ .getxattr = generic_getxattr,
+ .listxattr = pram_listxattr,
+ .removexattr = generic_removexattr,
+#endif
+};