linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 12/19] pramfs: symlink operations
@ 2013-09-07  8:29 Marco Stornelli
  2013-09-07 14:41 ` Al Viro
  0 siblings, 1 reply; 3+ messages in thread
From: Marco Stornelli @ 2013-09-07  8:29 UTC (permalink / raw)
  To: Vladimir Davydov; +Cc: linux-kernel, Linux FS Devel

Add symlink operations.

Signed-off-by: Marco Stornelli <marco.stornelli@gmail.com>
---
 fs/pramfs/symlink.c |   76 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 76 insertions(+), 0 deletions(-)
 create mode 100644 fs/pramfs/symlink.c

diff --git a/fs/pramfs/symlink.c b/fs/pramfs/symlink.c
new file mode 100644
index 0000000..0d5213f
--- /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
+};
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH 12/19] pramfs: symlink operations
  2013-09-07  8:29 [PATCH 12/19] pramfs: symlink operations Marco Stornelli
@ 2013-09-07 14:41 ` Al Viro
  2013-09-07 16:09   ` Marco Stornelli
  0 siblings, 1 reply; 3+ messages in thread
From: Al Viro @ 2013-09-07 14:41 UTC (permalink / raw)
  To: Marco Stornelli; +Cc: Vladimir Davydov, linux-kernel, Linux FS Devel

On Sat, Sep 07, 2013 at 10:29:15AM +0200, Marco Stornelli wrote:
> +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);
> +}

Just nd_set_link(nd, blockp) instead of that vfs_follow_link() and be
done with that; that way you can use generic_readlink() instead of
pram_readlink() *and* get lower stack footprint on traversing them.

BTW, where's the error checking?  pram_get_block()/pram_find_data_block()
seem to assume that fs image isn't corrupted and if it is... that code
will happily dereference any address.  At least range checks of some sort
in pram_get_block() (and checking if it has failed) would be a good idea...

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH 12/19] pramfs: symlink operations
  2013-09-07 14:41 ` Al Viro
@ 2013-09-07 16:09   ` Marco Stornelli
  0 siblings, 0 replies; 3+ messages in thread
From: Marco Stornelli @ 2013-09-07 16:09 UTC (permalink / raw)
  To: Al Viro; +Cc: Vladimir Davydov, linux-kernel, Linux FS Devel

Il 07/09/2013 16:41, Al Viro ha scritto:
> On Sat, Sep 07, 2013 at 10:29:15AM +0200, Marco Stornelli wrote:
>> +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);
>> +}
>
> Just nd_set_link(nd, blockp) instead of that vfs_follow_link() and be
> done with that; that way you can use generic_readlink() instead of
> pram_readlink() *and* get lower stack footprint on traversing them.
>
>

Yep, you're right (as usual :))

Marco

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2013-09-07 16:09 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-09-07  8:29 [PATCH 12/19] pramfs: symlink operations Marco Stornelli
2013-09-07 14:41 ` Al Viro
2013-09-07 16:09   ` Marco Stornelli

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).