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