Linux Audio

Check our new training course

Loading...
v3.5.6
  1/* -*- mode: c; c-basic-offset: 8; -*-
  2 * vim: noexpandtab sw=8 ts=8 sts=0:
  3 *
  4 *  linux/cluster/ssi/cfs/symlink.c
  5 *
  6 *	This program is free software; you can redistribute it and/or
  7 *	modify it under the terms of the GNU General Public License as
  8 *	published by the Free Software Foundation; either version 2 of
  9 *	the License, or (at your option) any later version.
 10 *
 11 *	This program is distributed in the hope that it will be useful,
 12 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 13 *	MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE
 14 *	or NON INFRINGEMENT.  See the GNU General Public License for more
 15 *	details.
 16 *
 17 * 	You should have received a copy of the GNU General Public License
 18 * 	along with this program; if not, write to the Free Software
 19 * 	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 20 *
 21 *	Questions/Comments/Bugfixes to ssic-linux-devel@lists.sourceforge.net
 22 *
 23 *  Copyright (C) 1992  Rick Sladkey
 24 *
 25 *  Optimization changes Copyright (C) 1994 Florian La Roche
 26 *
 27 *  Jun 7 1999, cache symlink lookups in the page cache.  -DaveM
 28 *
 29 *  Portions Copyright (C) 2001 Compaq Computer Corporation
 30 *
 31 *  ocfs2 symlink handling code.
 32 *
 33 *  Copyright (C) 2004, 2005 Oracle.
 34 *
 35 */
 36
 37#include <linux/fs.h>
 38#include <linux/types.h>
 39#include <linux/slab.h>
 40#include <linux/pagemap.h>
 41#include <linux/namei.h>
 42
 43#include <cluster/masklog.h>
 44
 45#include "ocfs2.h"
 46
 47#include "alloc.h"
 48#include "file.h"
 49#include "inode.h"
 50#include "journal.h"
 51#include "symlink.h"
 52#include "xattr.h"
 53
 54#include "buffer_head_io.h"
 55
 56
 57static int ocfs2_fast_symlink_readpage(struct file *unused, struct page *page)
 
 58{
 59	struct inode *inode = page->mapping->host;
 60	struct buffer_head *bh;
 61	int status = ocfs2_read_inode_block(inode, &bh);
 62	struct ocfs2_dinode *fe;
 63	const char *link;
 64	void *kaddr;
 65	size_t len;
 66
 
 67	if (status < 0) {
 68		mlog_errno(status);
 69		return status;
 
 70	}
 71
 72	fe = (struct ocfs2_dinode *) bh->b_data;
 73	link = (char *) fe->id2.i_symlink;
 74	/* will be less than a page size */
 75	len = strnlen(link, ocfs2_fast_symlink_chars(inode->i_sb));
 76	kaddr = kmap_atomic(page);
 77	memcpy(kaddr, link, len + 1);
 78	kunmap_atomic(kaddr);
 79	SetPageUptodate(page);
 80	unlock_page(page);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 81	brelse(bh);
 82	return 0;
 
 
 
 83}
 84
 85const struct address_space_operations ocfs2_fast_symlink_aops = {
 86	.readpage		= ocfs2_fast_symlink_readpage,
 87};
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 88
 89const struct inode_operations ocfs2_symlink_inode_operations = {
 90	.readlink	= generic_readlink,
 91	.follow_link	= page_follow_link_light,
 92	.put_link	= page_put_link,
 
 
 
 
 
 
 
 
 
 
 
 
 93	.getattr	= ocfs2_getattr,
 94	.setattr	= ocfs2_setattr,
 95	.setxattr	= generic_setxattr,
 96	.getxattr	= generic_getxattr,
 97	.listxattr	= ocfs2_listxattr,
 98	.removexattr	= generic_removexattr,
 99	.fiemap		= ocfs2_fiemap,
100};
v3.1
  1/* -*- mode: c; c-basic-offset: 8; -*-
  2 * vim: noexpandtab sw=8 ts=8 sts=0:
  3 *
  4 *  linux/cluster/ssi/cfs/symlink.c
  5 *
  6 *	This program is free software; you can redistribute it and/or
  7 *	modify it under the terms of the GNU General Public License as
  8 *	published by the Free Software Foundation; either version 2 of
  9 *	the License, or (at your option) any later version.
 10 *
 11 *	This program is distributed in the hope that it will be useful,
 12 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 13 *	MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE
 14 *	or NON INFRINGEMENT.  See the GNU General Public License for more
 15 *	details.
 16 *
 17 * 	You should have received a copy of the GNU General Public License
 18 * 	along with this program; if not, write to the Free Software
 19 * 	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 20 *
 21 *	Questions/Comments/Bugfixes to ssic-linux-devel@lists.sourceforge.net
 22 *
 23 *  Copyright (C) 1992  Rick Sladkey
 24 *
 25 *  Optimization changes Copyright (C) 1994 Florian La Roche
 26 *
 27 *  Jun 7 1999, cache symlink lookups in the page cache.  -DaveM
 28 *
 29 *  Portions Copyright (C) 2001 Compaq Computer Corporation
 30 *
 31 *  ocfs2 symlink handling code.
 32 *
 33 *  Copyright (C) 2004, 2005 Oracle.
 34 *
 35 */
 36
 37#include <linux/fs.h>
 38#include <linux/types.h>
 39#include <linux/slab.h>
 40#include <linux/pagemap.h>
 41#include <linux/namei.h>
 42
 43#include <cluster/masklog.h>
 44
 45#include "ocfs2.h"
 46
 47#include "alloc.h"
 48#include "file.h"
 49#include "inode.h"
 50#include "journal.h"
 51#include "symlink.h"
 52#include "xattr.h"
 53
 54#include "buffer_head_io.h"
 55
 56
 57static char *ocfs2_fast_symlink_getlink(struct inode *inode,
 58					struct buffer_head **bh)
 59{
 60	int status;
 61	char *link = NULL;
 
 62	struct ocfs2_dinode *fe;
 
 
 
 63
 64	status = ocfs2_read_inode_block(inode, bh);
 65	if (status < 0) {
 66		mlog_errno(status);
 67		link = ERR_PTR(status);
 68		goto bail;
 69	}
 70
 71	fe = (struct ocfs2_dinode *) (*bh)->b_data;
 72	link = (char *) fe->id2.i_symlink;
 73bail:
 74
 75	return link;
 76}
 77
 78static int ocfs2_readlink(struct dentry *dentry,
 79			  char __user *buffer,
 80			  int buflen)
 81{
 82	int ret;
 83	char *link;
 84	struct buffer_head *bh = NULL;
 85	struct inode *inode = dentry->d_inode;
 86
 87	link = ocfs2_fast_symlink_getlink(inode, &bh);
 88	if (IS_ERR(link)) {
 89		ret = PTR_ERR(link);
 90		goto out;
 91	}
 92
 93	/*
 94	 * Without vfsmount we can't update atime now,
 95	 * but we will update atime here ultimately.
 96	 */
 97	ret = vfs_readlink(dentry, buffer, buflen, link);
 98
 99	brelse(bh);
100out:
101	if (ret < 0)
102		mlog_errno(ret);
103	return ret;
104}
105
106static void *ocfs2_fast_follow_link(struct dentry *dentry,
107				    struct nameidata *nd)
108{
109	int status = 0;
110	int len;
111	char *target, *link = ERR_PTR(-ENOMEM);
112	struct inode *inode = dentry->d_inode;
113	struct buffer_head *bh = NULL;
114
115	BUG_ON(!ocfs2_inode_is_fast_symlink(inode));
116	target = ocfs2_fast_symlink_getlink(inode, &bh);
117	if (IS_ERR(target)) {
118		status = PTR_ERR(target);
119		mlog_errno(status);
120		goto bail;
121	}
122
123	/* Fast symlinks can't be large */
124	len = strnlen(target, ocfs2_fast_symlink_chars(inode->i_sb));
125	link = kzalloc(len + 1, GFP_NOFS);
126	if (!link) {
127		status = -ENOMEM;
128		mlog_errno(status);
129		goto bail;
130	}
131
132	memcpy(link, target, len);
133
134bail:
135	nd_set_link(nd, status ? ERR_PTR(status) : link);
136	brelse(bh);
137
138	if (status)
139		mlog_errno(status);
140	return NULL;
141}
142
143static void ocfs2_fast_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
144{
145	char *link = nd_get_link(nd);
146	if (!IS_ERR(link))
147		kfree(link);
148}
149
150const struct inode_operations ocfs2_symlink_inode_operations = {
151	.readlink	= page_readlink,
152	.follow_link	= page_follow_link_light,
153	.put_link	= page_put_link,
154	.getattr	= ocfs2_getattr,
155	.setattr	= ocfs2_setattr,
156	.setxattr	= generic_setxattr,
157	.getxattr	= generic_getxattr,
158	.listxattr	= ocfs2_listxattr,
159	.removexattr	= generic_removexattr,
160	.fiemap		= ocfs2_fiemap,
161};
162const struct inode_operations ocfs2_fast_symlink_inode_operations = {
163	.readlink	= ocfs2_readlink,
164	.follow_link	= ocfs2_fast_follow_link,
165	.put_link	= ocfs2_fast_put_link,
166	.getattr	= ocfs2_getattr,
167	.setattr	= ocfs2_setattr,
168	.setxattr	= generic_setxattr,
169	.getxattr	= generic_getxattr,
170	.listxattr	= ocfs2_listxattr,
171	.removexattr	= generic_removexattr,
172	.fiemap		= ocfs2_fiemap,
173};