Commit 87ec21741138bb42e7f943bb142b1d8567c10925
1 parent
536baf02f6
Exists in
master
and in
39 other branches
GFS2: Move gfs2_unlink_ok into ops_inode.c
Another function which is only called from one ops_inode.c so we move it and make it static. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Showing 3 changed files with 38 additions and 41 deletions Inline Diff
fs/gfs2/inode.c
1 | /* | 1 | /* |
2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | 2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
3 | * Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved. | 3 | * Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This copyrighted material is made available to anyone wishing to use, | 5 | * This copyrighted material is made available to anyone wishing to use, |
6 | * modify, copy, or redistribute it subject to the terms and conditions | 6 | * modify, copy, or redistribute it subject to the terms and conditions |
7 | * of the GNU General Public License version 2. | 7 | * of the GNU General Public License version 2. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/sched.h> | 10 | #include <linux/sched.h> |
11 | #include <linux/slab.h> | 11 | #include <linux/slab.h> |
12 | #include <linux/spinlock.h> | 12 | #include <linux/spinlock.h> |
13 | #include <linux/completion.h> | 13 | #include <linux/completion.h> |
14 | #include <linux/buffer_head.h> | 14 | #include <linux/buffer_head.h> |
15 | #include <linux/posix_acl.h> | 15 | #include <linux/posix_acl.h> |
16 | #include <linux/sort.h> | 16 | #include <linux/sort.h> |
17 | #include <linux/gfs2_ondisk.h> | 17 | #include <linux/gfs2_ondisk.h> |
18 | #include <linux/crc32.h> | 18 | #include <linux/crc32.h> |
19 | #include <linux/security.h> | 19 | #include <linux/security.h> |
20 | #include <linux/time.h> | 20 | #include <linux/time.h> |
21 | 21 | ||
22 | #include "gfs2.h" | 22 | #include "gfs2.h" |
23 | #include "incore.h" | 23 | #include "incore.h" |
24 | #include "acl.h" | 24 | #include "acl.h" |
25 | #include "bmap.h" | 25 | #include "bmap.h" |
26 | #include "dir.h" | 26 | #include "dir.h" |
27 | #include "eattr.h" | 27 | #include "eattr.h" |
28 | #include "glock.h" | 28 | #include "glock.h" |
29 | #include "glops.h" | 29 | #include "glops.h" |
30 | #include "inode.h" | 30 | #include "inode.h" |
31 | #include "log.h" | 31 | #include "log.h" |
32 | #include "meta_io.h" | 32 | #include "meta_io.h" |
33 | #include "quota.h" | 33 | #include "quota.h" |
34 | #include "rgrp.h" | 34 | #include "rgrp.h" |
35 | #include "trans.h" | 35 | #include "trans.h" |
36 | #include "util.h" | 36 | #include "util.h" |
37 | 37 | ||
38 | struct gfs2_inum_range_host { | 38 | struct gfs2_inum_range_host { |
39 | u64 ir_start; | 39 | u64 ir_start; |
40 | u64 ir_length; | 40 | u64 ir_length; |
41 | }; | 41 | }; |
42 | 42 | ||
43 | static int iget_test(struct inode *inode, void *opaque) | 43 | static int iget_test(struct inode *inode, void *opaque) |
44 | { | 44 | { |
45 | struct gfs2_inode *ip = GFS2_I(inode); | 45 | struct gfs2_inode *ip = GFS2_I(inode); |
46 | u64 *no_addr = opaque; | 46 | u64 *no_addr = opaque; |
47 | 47 | ||
48 | if (ip->i_no_addr == *no_addr && test_bit(GIF_USER, &ip->i_flags)) | 48 | if (ip->i_no_addr == *no_addr && test_bit(GIF_USER, &ip->i_flags)) |
49 | return 1; | 49 | return 1; |
50 | 50 | ||
51 | return 0; | 51 | return 0; |
52 | } | 52 | } |
53 | 53 | ||
54 | static int iget_set(struct inode *inode, void *opaque) | 54 | static int iget_set(struct inode *inode, void *opaque) |
55 | { | 55 | { |
56 | struct gfs2_inode *ip = GFS2_I(inode); | 56 | struct gfs2_inode *ip = GFS2_I(inode); |
57 | u64 *no_addr = opaque; | 57 | u64 *no_addr = opaque; |
58 | 58 | ||
59 | inode->i_ino = (unsigned long)*no_addr; | 59 | inode->i_ino = (unsigned long)*no_addr; |
60 | ip->i_no_addr = *no_addr; | 60 | ip->i_no_addr = *no_addr; |
61 | set_bit(GIF_USER, &ip->i_flags); | 61 | set_bit(GIF_USER, &ip->i_flags); |
62 | return 0; | 62 | return 0; |
63 | } | 63 | } |
64 | 64 | ||
65 | struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr) | 65 | struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr) |
66 | { | 66 | { |
67 | unsigned long hash = (unsigned long)no_addr; | 67 | unsigned long hash = (unsigned long)no_addr; |
68 | return ilookup5(sb, hash, iget_test, &no_addr); | 68 | return ilookup5(sb, hash, iget_test, &no_addr); |
69 | } | 69 | } |
70 | 70 | ||
71 | static struct inode *gfs2_iget(struct super_block *sb, u64 no_addr) | 71 | static struct inode *gfs2_iget(struct super_block *sb, u64 no_addr) |
72 | { | 72 | { |
73 | unsigned long hash = (unsigned long)no_addr; | 73 | unsigned long hash = (unsigned long)no_addr; |
74 | return iget5_locked(sb, hash, iget_test, iget_set, &no_addr); | 74 | return iget5_locked(sb, hash, iget_test, iget_set, &no_addr); |
75 | } | 75 | } |
76 | 76 | ||
77 | struct gfs2_skip_data { | 77 | struct gfs2_skip_data { |
78 | u64 no_addr; | 78 | u64 no_addr; |
79 | int skipped; | 79 | int skipped; |
80 | }; | 80 | }; |
81 | 81 | ||
82 | static int iget_skip_test(struct inode *inode, void *opaque) | 82 | static int iget_skip_test(struct inode *inode, void *opaque) |
83 | { | 83 | { |
84 | struct gfs2_inode *ip = GFS2_I(inode); | 84 | struct gfs2_inode *ip = GFS2_I(inode); |
85 | struct gfs2_skip_data *data = opaque; | 85 | struct gfs2_skip_data *data = opaque; |
86 | 86 | ||
87 | if (ip->i_no_addr == data->no_addr && test_bit(GIF_USER, &ip->i_flags)){ | 87 | if (ip->i_no_addr == data->no_addr && test_bit(GIF_USER, &ip->i_flags)){ |
88 | if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)){ | 88 | if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)){ |
89 | data->skipped = 1; | 89 | data->skipped = 1; |
90 | return 0; | 90 | return 0; |
91 | } | 91 | } |
92 | return 1; | 92 | return 1; |
93 | } | 93 | } |
94 | return 0; | 94 | return 0; |
95 | } | 95 | } |
96 | 96 | ||
97 | static int iget_skip_set(struct inode *inode, void *opaque) | 97 | static int iget_skip_set(struct inode *inode, void *opaque) |
98 | { | 98 | { |
99 | struct gfs2_inode *ip = GFS2_I(inode); | 99 | struct gfs2_inode *ip = GFS2_I(inode); |
100 | struct gfs2_skip_data *data = opaque; | 100 | struct gfs2_skip_data *data = opaque; |
101 | 101 | ||
102 | if (data->skipped) | 102 | if (data->skipped) |
103 | return 1; | 103 | return 1; |
104 | inode->i_ino = (unsigned long)(data->no_addr); | 104 | inode->i_ino = (unsigned long)(data->no_addr); |
105 | ip->i_no_addr = data->no_addr; | 105 | ip->i_no_addr = data->no_addr; |
106 | set_bit(GIF_USER, &ip->i_flags); | 106 | set_bit(GIF_USER, &ip->i_flags); |
107 | return 0; | 107 | return 0; |
108 | } | 108 | } |
109 | 109 | ||
110 | static struct inode *gfs2_iget_skip(struct super_block *sb, | 110 | static struct inode *gfs2_iget_skip(struct super_block *sb, |
111 | u64 no_addr) | 111 | u64 no_addr) |
112 | { | 112 | { |
113 | struct gfs2_skip_data data; | 113 | struct gfs2_skip_data data; |
114 | unsigned long hash = (unsigned long)no_addr; | 114 | unsigned long hash = (unsigned long)no_addr; |
115 | 115 | ||
116 | data.no_addr = no_addr; | 116 | data.no_addr = no_addr; |
117 | data.skipped = 0; | 117 | data.skipped = 0; |
118 | return iget5_locked(sb, hash, iget_skip_test, iget_skip_set, &data); | 118 | return iget5_locked(sb, hash, iget_skip_test, iget_skip_set, &data); |
119 | } | 119 | } |
120 | 120 | ||
121 | /** | 121 | /** |
122 | * GFS2 lookup code fills in vfs inode contents based on info obtained | 122 | * GFS2 lookup code fills in vfs inode contents based on info obtained |
123 | * from directory entry inside gfs2_inode_lookup(). This has caused issues | 123 | * from directory entry inside gfs2_inode_lookup(). This has caused issues |
124 | * with NFS code path since its get_dentry routine doesn't have the relevant | 124 | * with NFS code path since its get_dentry routine doesn't have the relevant |
125 | * directory entry when gfs2_inode_lookup() is invoked. Part of the code | 125 | * directory entry when gfs2_inode_lookup() is invoked. Part of the code |
126 | * segment inside gfs2_inode_lookup code needs to get moved around. | 126 | * segment inside gfs2_inode_lookup code needs to get moved around. |
127 | * | 127 | * |
128 | * Clean up I_LOCK and I_NEW as well. | 128 | * Clean up I_LOCK and I_NEW as well. |
129 | **/ | 129 | **/ |
130 | 130 | ||
131 | void gfs2_set_iop(struct inode *inode) | 131 | void gfs2_set_iop(struct inode *inode) |
132 | { | 132 | { |
133 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 133 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
134 | umode_t mode = inode->i_mode; | 134 | umode_t mode = inode->i_mode; |
135 | 135 | ||
136 | if (S_ISREG(mode)) { | 136 | if (S_ISREG(mode)) { |
137 | inode->i_op = &gfs2_file_iops; | 137 | inode->i_op = &gfs2_file_iops; |
138 | if (gfs2_localflocks(sdp)) | 138 | if (gfs2_localflocks(sdp)) |
139 | inode->i_fop = &gfs2_file_fops_nolock; | 139 | inode->i_fop = &gfs2_file_fops_nolock; |
140 | else | 140 | else |
141 | inode->i_fop = &gfs2_file_fops; | 141 | inode->i_fop = &gfs2_file_fops; |
142 | } else if (S_ISDIR(mode)) { | 142 | } else if (S_ISDIR(mode)) { |
143 | inode->i_op = &gfs2_dir_iops; | 143 | inode->i_op = &gfs2_dir_iops; |
144 | if (gfs2_localflocks(sdp)) | 144 | if (gfs2_localflocks(sdp)) |
145 | inode->i_fop = &gfs2_dir_fops_nolock; | 145 | inode->i_fop = &gfs2_dir_fops_nolock; |
146 | else | 146 | else |
147 | inode->i_fop = &gfs2_dir_fops; | 147 | inode->i_fop = &gfs2_dir_fops; |
148 | } else if (S_ISLNK(mode)) { | 148 | } else if (S_ISLNK(mode)) { |
149 | inode->i_op = &gfs2_symlink_iops; | 149 | inode->i_op = &gfs2_symlink_iops; |
150 | } else { | 150 | } else { |
151 | inode->i_op = &gfs2_file_iops; | 151 | inode->i_op = &gfs2_file_iops; |
152 | init_special_inode(inode, inode->i_mode, inode->i_rdev); | 152 | init_special_inode(inode, inode->i_mode, inode->i_rdev); |
153 | } | 153 | } |
154 | 154 | ||
155 | unlock_new_inode(inode); | 155 | unlock_new_inode(inode); |
156 | } | 156 | } |
157 | 157 | ||
158 | /** | 158 | /** |
159 | * gfs2_inode_lookup - Lookup an inode | 159 | * gfs2_inode_lookup - Lookup an inode |
160 | * @sb: The super block | 160 | * @sb: The super block |
161 | * @no_addr: The inode number | 161 | * @no_addr: The inode number |
162 | * @type: The type of the inode | 162 | * @type: The type of the inode |
163 | * @skip_freeing: set this not return an inode if it is currently being freed. | 163 | * @skip_freeing: set this not return an inode if it is currently being freed. |
164 | * | 164 | * |
165 | * Returns: A VFS inode, or an error | 165 | * Returns: A VFS inode, or an error |
166 | */ | 166 | */ |
167 | 167 | ||
168 | struct inode *gfs2_inode_lookup(struct super_block *sb, | 168 | struct inode *gfs2_inode_lookup(struct super_block *sb, |
169 | unsigned int type, | 169 | unsigned int type, |
170 | u64 no_addr, | 170 | u64 no_addr, |
171 | u64 no_formal_ino, int skip_freeing) | 171 | u64 no_formal_ino, int skip_freeing) |
172 | { | 172 | { |
173 | struct inode *inode; | 173 | struct inode *inode; |
174 | struct gfs2_inode *ip; | 174 | struct gfs2_inode *ip; |
175 | struct gfs2_glock *io_gl; | 175 | struct gfs2_glock *io_gl; |
176 | int error; | 176 | int error; |
177 | 177 | ||
178 | if (skip_freeing) | 178 | if (skip_freeing) |
179 | inode = gfs2_iget_skip(sb, no_addr); | 179 | inode = gfs2_iget_skip(sb, no_addr); |
180 | else | 180 | else |
181 | inode = gfs2_iget(sb, no_addr); | 181 | inode = gfs2_iget(sb, no_addr); |
182 | ip = GFS2_I(inode); | 182 | ip = GFS2_I(inode); |
183 | 183 | ||
184 | if (!inode) | 184 | if (!inode) |
185 | return ERR_PTR(-ENOBUFS); | 185 | return ERR_PTR(-ENOBUFS); |
186 | 186 | ||
187 | if (inode->i_state & I_NEW) { | 187 | if (inode->i_state & I_NEW) { |
188 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 188 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
189 | ip->i_no_formal_ino = no_formal_ino; | 189 | ip->i_no_formal_ino = no_formal_ino; |
190 | 190 | ||
191 | error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl); | 191 | error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl); |
192 | if (unlikely(error)) | 192 | if (unlikely(error)) |
193 | goto fail; | 193 | goto fail; |
194 | ip->i_gl->gl_object = ip; | 194 | ip->i_gl->gl_object = ip; |
195 | 195 | ||
196 | error = gfs2_glock_get(sdp, no_addr, &gfs2_iopen_glops, CREATE, &io_gl); | 196 | error = gfs2_glock_get(sdp, no_addr, &gfs2_iopen_glops, CREATE, &io_gl); |
197 | if (unlikely(error)) | 197 | if (unlikely(error)) |
198 | goto fail_put; | 198 | goto fail_put; |
199 | 199 | ||
200 | set_bit(GIF_INVALID, &ip->i_flags); | 200 | set_bit(GIF_INVALID, &ip->i_flags); |
201 | error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh); | 201 | error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh); |
202 | if (unlikely(error)) | 202 | if (unlikely(error)) |
203 | goto fail_iopen; | 203 | goto fail_iopen; |
204 | ip->i_iopen_gh.gh_gl->gl_object = ip; | 204 | ip->i_iopen_gh.gh_gl->gl_object = ip; |
205 | 205 | ||
206 | gfs2_glock_put(io_gl); | 206 | gfs2_glock_put(io_gl); |
207 | 207 | ||
208 | if ((type == DT_UNKNOWN) && (no_formal_ino == 0)) | 208 | if ((type == DT_UNKNOWN) && (no_formal_ino == 0)) |
209 | goto gfs2_nfsbypass; | 209 | goto gfs2_nfsbypass; |
210 | 210 | ||
211 | inode->i_mode = DT2IF(type); | 211 | inode->i_mode = DT2IF(type); |
212 | 212 | ||
213 | /* | 213 | /* |
214 | * We must read the inode in order to work out its type in | 214 | * We must read the inode in order to work out its type in |
215 | * this case. Note that this doesn't happen often as we normally | 215 | * this case. Note that this doesn't happen often as we normally |
216 | * know the type beforehand. This code path only occurs during | 216 | * know the type beforehand. This code path only occurs during |
217 | * unlinked inode recovery (where it is safe to do this glock, | 217 | * unlinked inode recovery (where it is safe to do this glock, |
218 | * which is not true in the general case). | 218 | * which is not true in the general case). |
219 | */ | 219 | */ |
220 | if (type == DT_UNKNOWN) { | 220 | if (type == DT_UNKNOWN) { |
221 | struct gfs2_holder gh; | 221 | struct gfs2_holder gh; |
222 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | 222 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); |
223 | if (unlikely(error)) | 223 | if (unlikely(error)) |
224 | goto fail_glock; | 224 | goto fail_glock; |
225 | /* Inode is now uptodate */ | 225 | /* Inode is now uptodate */ |
226 | gfs2_glock_dq_uninit(&gh); | 226 | gfs2_glock_dq_uninit(&gh); |
227 | } | 227 | } |
228 | 228 | ||
229 | gfs2_set_iop(inode); | 229 | gfs2_set_iop(inode); |
230 | } | 230 | } |
231 | 231 | ||
232 | gfs2_nfsbypass: | 232 | gfs2_nfsbypass: |
233 | return inode; | 233 | return inode; |
234 | fail_glock: | 234 | fail_glock: |
235 | gfs2_glock_dq(&ip->i_iopen_gh); | 235 | gfs2_glock_dq(&ip->i_iopen_gh); |
236 | fail_iopen: | 236 | fail_iopen: |
237 | gfs2_glock_put(io_gl); | 237 | gfs2_glock_put(io_gl); |
238 | fail_put: | 238 | fail_put: |
239 | ip->i_gl->gl_object = NULL; | 239 | ip->i_gl->gl_object = NULL; |
240 | gfs2_glock_put(ip->i_gl); | 240 | gfs2_glock_put(ip->i_gl); |
241 | fail: | 241 | fail: |
242 | iget_failed(inode); | 242 | iget_failed(inode); |
243 | return ERR_PTR(error); | 243 | return ERR_PTR(error); |
244 | } | 244 | } |
245 | 245 | ||
246 | static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) | 246 | static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) |
247 | { | 247 | { |
248 | const struct gfs2_dinode *str = buf; | 248 | const struct gfs2_dinode *str = buf; |
249 | struct timespec atime; | 249 | struct timespec atime; |
250 | u16 height, depth; | 250 | u16 height, depth; |
251 | 251 | ||
252 | if (unlikely(ip->i_no_addr != be64_to_cpu(str->di_num.no_addr))) | 252 | if (unlikely(ip->i_no_addr != be64_to_cpu(str->di_num.no_addr))) |
253 | goto corrupt; | 253 | goto corrupt; |
254 | ip->i_no_formal_ino = be64_to_cpu(str->di_num.no_formal_ino); | 254 | ip->i_no_formal_ino = be64_to_cpu(str->di_num.no_formal_ino); |
255 | ip->i_inode.i_mode = be32_to_cpu(str->di_mode); | 255 | ip->i_inode.i_mode = be32_to_cpu(str->di_mode); |
256 | ip->i_inode.i_rdev = 0; | 256 | ip->i_inode.i_rdev = 0; |
257 | switch (ip->i_inode.i_mode & S_IFMT) { | 257 | switch (ip->i_inode.i_mode & S_IFMT) { |
258 | case S_IFBLK: | 258 | case S_IFBLK: |
259 | case S_IFCHR: | 259 | case S_IFCHR: |
260 | ip->i_inode.i_rdev = MKDEV(be32_to_cpu(str->di_major), | 260 | ip->i_inode.i_rdev = MKDEV(be32_to_cpu(str->di_major), |
261 | be32_to_cpu(str->di_minor)); | 261 | be32_to_cpu(str->di_minor)); |
262 | break; | 262 | break; |
263 | }; | 263 | }; |
264 | 264 | ||
265 | ip->i_inode.i_uid = be32_to_cpu(str->di_uid); | 265 | ip->i_inode.i_uid = be32_to_cpu(str->di_uid); |
266 | ip->i_inode.i_gid = be32_to_cpu(str->di_gid); | 266 | ip->i_inode.i_gid = be32_to_cpu(str->di_gid); |
267 | /* | 267 | /* |
268 | * We will need to review setting the nlink count here in the | 268 | * We will need to review setting the nlink count here in the |
269 | * light of the forthcoming ro bind mount work. This is a reminder | 269 | * light of the forthcoming ro bind mount work. This is a reminder |
270 | * to do that. | 270 | * to do that. |
271 | */ | 271 | */ |
272 | ip->i_inode.i_nlink = be32_to_cpu(str->di_nlink); | 272 | ip->i_inode.i_nlink = be32_to_cpu(str->di_nlink); |
273 | ip->i_disksize = be64_to_cpu(str->di_size); | 273 | ip->i_disksize = be64_to_cpu(str->di_size); |
274 | i_size_write(&ip->i_inode, ip->i_disksize); | 274 | i_size_write(&ip->i_inode, ip->i_disksize); |
275 | gfs2_set_inode_blocks(&ip->i_inode, be64_to_cpu(str->di_blocks)); | 275 | gfs2_set_inode_blocks(&ip->i_inode, be64_to_cpu(str->di_blocks)); |
276 | atime.tv_sec = be64_to_cpu(str->di_atime); | 276 | atime.tv_sec = be64_to_cpu(str->di_atime); |
277 | atime.tv_nsec = be32_to_cpu(str->di_atime_nsec); | 277 | atime.tv_nsec = be32_to_cpu(str->di_atime_nsec); |
278 | if (timespec_compare(&ip->i_inode.i_atime, &atime) < 0) | 278 | if (timespec_compare(&ip->i_inode.i_atime, &atime) < 0) |
279 | ip->i_inode.i_atime = atime; | 279 | ip->i_inode.i_atime = atime; |
280 | ip->i_inode.i_mtime.tv_sec = be64_to_cpu(str->di_mtime); | 280 | ip->i_inode.i_mtime.tv_sec = be64_to_cpu(str->di_mtime); |
281 | ip->i_inode.i_mtime.tv_nsec = be32_to_cpu(str->di_mtime_nsec); | 281 | ip->i_inode.i_mtime.tv_nsec = be32_to_cpu(str->di_mtime_nsec); |
282 | ip->i_inode.i_ctime.tv_sec = be64_to_cpu(str->di_ctime); | 282 | ip->i_inode.i_ctime.tv_sec = be64_to_cpu(str->di_ctime); |
283 | ip->i_inode.i_ctime.tv_nsec = be32_to_cpu(str->di_ctime_nsec); | 283 | ip->i_inode.i_ctime.tv_nsec = be32_to_cpu(str->di_ctime_nsec); |
284 | 284 | ||
285 | ip->i_goal = be64_to_cpu(str->di_goal_meta); | 285 | ip->i_goal = be64_to_cpu(str->di_goal_meta); |
286 | ip->i_generation = be64_to_cpu(str->di_generation); | 286 | ip->i_generation = be64_to_cpu(str->di_generation); |
287 | 287 | ||
288 | ip->i_diskflags = be32_to_cpu(str->di_flags); | 288 | ip->i_diskflags = be32_to_cpu(str->di_flags); |
289 | gfs2_set_inode_flags(&ip->i_inode); | 289 | gfs2_set_inode_flags(&ip->i_inode); |
290 | height = be16_to_cpu(str->di_height); | 290 | height = be16_to_cpu(str->di_height); |
291 | if (unlikely(height > GFS2_MAX_META_HEIGHT)) | 291 | if (unlikely(height > GFS2_MAX_META_HEIGHT)) |
292 | goto corrupt; | 292 | goto corrupt; |
293 | ip->i_height = (u8)height; | 293 | ip->i_height = (u8)height; |
294 | 294 | ||
295 | depth = be16_to_cpu(str->di_depth); | 295 | depth = be16_to_cpu(str->di_depth); |
296 | if (unlikely(depth > GFS2_DIR_MAX_DEPTH)) | 296 | if (unlikely(depth > GFS2_DIR_MAX_DEPTH)) |
297 | goto corrupt; | 297 | goto corrupt; |
298 | ip->i_depth = (u8)depth; | 298 | ip->i_depth = (u8)depth; |
299 | ip->i_entries = be32_to_cpu(str->di_entries); | 299 | ip->i_entries = be32_to_cpu(str->di_entries); |
300 | 300 | ||
301 | ip->i_eattr = be64_to_cpu(str->di_eattr); | 301 | ip->i_eattr = be64_to_cpu(str->di_eattr); |
302 | if (S_ISREG(ip->i_inode.i_mode)) | 302 | if (S_ISREG(ip->i_inode.i_mode)) |
303 | gfs2_set_aops(&ip->i_inode); | 303 | gfs2_set_aops(&ip->i_inode); |
304 | 304 | ||
305 | return 0; | 305 | return 0; |
306 | corrupt: | 306 | corrupt: |
307 | if (gfs2_consist_inode(ip)) | 307 | if (gfs2_consist_inode(ip)) |
308 | gfs2_dinode_print(ip); | 308 | gfs2_dinode_print(ip); |
309 | return -EIO; | 309 | return -EIO; |
310 | } | 310 | } |
311 | 311 | ||
312 | /** | 312 | /** |
313 | * gfs2_inode_refresh - Refresh the incore copy of the dinode | 313 | * gfs2_inode_refresh - Refresh the incore copy of the dinode |
314 | * @ip: The GFS2 inode | 314 | * @ip: The GFS2 inode |
315 | * | 315 | * |
316 | * Returns: errno | 316 | * Returns: errno |
317 | */ | 317 | */ |
318 | 318 | ||
319 | int gfs2_inode_refresh(struct gfs2_inode *ip) | 319 | int gfs2_inode_refresh(struct gfs2_inode *ip) |
320 | { | 320 | { |
321 | struct buffer_head *dibh; | 321 | struct buffer_head *dibh; |
322 | int error; | 322 | int error; |
323 | 323 | ||
324 | error = gfs2_meta_inode_buffer(ip, &dibh); | 324 | error = gfs2_meta_inode_buffer(ip, &dibh); |
325 | if (error) | 325 | if (error) |
326 | return error; | 326 | return error; |
327 | 327 | ||
328 | if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), dibh, GFS2_METATYPE_DI)) { | 328 | if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), dibh, GFS2_METATYPE_DI)) { |
329 | brelse(dibh); | 329 | brelse(dibh); |
330 | return -EIO; | 330 | return -EIO; |
331 | } | 331 | } |
332 | 332 | ||
333 | error = gfs2_dinode_in(ip, dibh->b_data); | 333 | error = gfs2_dinode_in(ip, dibh->b_data); |
334 | brelse(dibh); | 334 | brelse(dibh); |
335 | clear_bit(GIF_INVALID, &ip->i_flags); | 335 | clear_bit(GIF_INVALID, &ip->i_flags); |
336 | 336 | ||
337 | return error; | 337 | return error; |
338 | } | 338 | } |
339 | 339 | ||
340 | int gfs2_dinode_dealloc(struct gfs2_inode *ip) | 340 | int gfs2_dinode_dealloc(struct gfs2_inode *ip) |
341 | { | 341 | { |
342 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 342 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
343 | struct gfs2_alloc *al; | 343 | struct gfs2_alloc *al; |
344 | struct gfs2_rgrpd *rgd; | 344 | struct gfs2_rgrpd *rgd; |
345 | int error; | 345 | int error; |
346 | 346 | ||
347 | if (gfs2_get_inode_blocks(&ip->i_inode) != 1) { | 347 | if (gfs2_get_inode_blocks(&ip->i_inode) != 1) { |
348 | if (gfs2_consist_inode(ip)) | 348 | if (gfs2_consist_inode(ip)) |
349 | gfs2_dinode_print(ip); | 349 | gfs2_dinode_print(ip); |
350 | return -EIO; | 350 | return -EIO; |
351 | } | 351 | } |
352 | 352 | ||
353 | al = gfs2_alloc_get(ip); | 353 | al = gfs2_alloc_get(ip); |
354 | if (!al) | 354 | if (!al) |
355 | return -ENOMEM; | 355 | return -ENOMEM; |
356 | 356 | ||
357 | error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); | 357 | error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); |
358 | if (error) | 358 | if (error) |
359 | goto out; | 359 | goto out; |
360 | 360 | ||
361 | error = gfs2_rindex_hold(sdp, &al->al_ri_gh); | 361 | error = gfs2_rindex_hold(sdp, &al->al_ri_gh); |
362 | if (error) | 362 | if (error) |
363 | goto out_qs; | 363 | goto out_qs; |
364 | 364 | ||
365 | rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr); | 365 | rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr); |
366 | if (!rgd) { | 366 | if (!rgd) { |
367 | gfs2_consist_inode(ip); | 367 | gfs2_consist_inode(ip); |
368 | error = -EIO; | 368 | error = -EIO; |
369 | goto out_rindex_relse; | 369 | goto out_rindex_relse; |
370 | } | 370 | } |
371 | 371 | ||
372 | error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, | 372 | error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, |
373 | &al->al_rgd_gh); | 373 | &al->al_rgd_gh); |
374 | if (error) | 374 | if (error) |
375 | goto out_rindex_relse; | 375 | goto out_rindex_relse; |
376 | 376 | ||
377 | error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_STATFS + RES_QUOTA, 1); | 377 | error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_STATFS + RES_QUOTA, 1); |
378 | if (error) | 378 | if (error) |
379 | goto out_rg_gunlock; | 379 | goto out_rg_gunlock; |
380 | 380 | ||
381 | set_bit(GLF_DIRTY, &ip->i_gl->gl_flags); | 381 | set_bit(GLF_DIRTY, &ip->i_gl->gl_flags); |
382 | set_bit(GLF_LFLUSH, &ip->i_gl->gl_flags); | 382 | set_bit(GLF_LFLUSH, &ip->i_gl->gl_flags); |
383 | 383 | ||
384 | gfs2_free_di(rgd, ip); | 384 | gfs2_free_di(rgd, ip); |
385 | 385 | ||
386 | gfs2_trans_end(sdp); | 386 | gfs2_trans_end(sdp); |
387 | 387 | ||
388 | out_rg_gunlock: | 388 | out_rg_gunlock: |
389 | gfs2_glock_dq_uninit(&al->al_rgd_gh); | 389 | gfs2_glock_dq_uninit(&al->al_rgd_gh); |
390 | out_rindex_relse: | 390 | out_rindex_relse: |
391 | gfs2_glock_dq_uninit(&al->al_ri_gh); | 391 | gfs2_glock_dq_uninit(&al->al_ri_gh); |
392 | out_qs: | 392 | out_qs: |
393 | gfs2_quota_unhold(ip); | 393 | gfs2_quota_unhold(ip); |
394 | out: | 394 | out: |
395 | gfs2_alloc_put(ip); | 395 | gfs2_alloc_put(ip); |
396 | return error; | 396 | return error; |
397 | } | 397 | } |
398 | 398 | ||
399 | /** | 399 | /** |
400 | * gfs2_change_nlink - Change nlink count on inode | 400 | * gfs2_change_nlink - Change nlink count on inode |
401 | * @ip: The GFS2 inode | 401 | * @ip: The GFS2 inode |
402 | * @diff: The change in the nlink count required | 402 | * @diff: The change in the nlink count required |
403 | * | 403 | * |
404 | * Returns: errno | 404 | * Returns: errno |
405 | */ | 405 | */ |
406 | int gfs2_change_nlink(struct gfs2_inode *ip, int diff) | 406 | int gfs2_change_nlink(struct gfs2_inode *ip, int diff) |
407 | { | 407 | { |
408 | struct buffer_head *dibh; | 408 | struct buffer_head *dibh; |
409 | u32 nlink; | 409 | u32 nlink; |
410 | int error; | 410 | int error; |
411 | 411 | ||
412 | BUG_ON(diff != 1 && diff != -1); | 412 | BUG_ON(diff != 1 && diff != -1); |
413 | nlink = ip->i_inode.i_nlink + diff; | 413 | nlink = ip->i_inode.i_nlink + diff; |
414 | 414 | ||
415 | /* If we are reducing the nlink count, but the new value ends up being | 415 | /* If we are reducing the nlink count, but the new value ends up being |
416 | bigger than the old one, we must have underflowed. */ | 416 | bigger than the old one, we must have underflowed. */ |
417 | if (diff < 0 && nlink > ip->i_inode.i_nlink) { | 417 | if (diff < 0 && nlink > ip->i_inode.i_nlink) { |
418 | if (gfs2_consist_inode(ip)) | 418 | if (gfs2_consist_inode(ip)) |
419 | gfs2_dinode_print(ip); | 419 | gfs2_dinode_print(ip); |
420 | return -EIO; | 420 | return -EIO; |
421 | } | 421 | } |
422 | 422 | ||
423 | error = gfs2_meta_inode_buffer(ip, &dibh); | 423 | error = gfs2_meta_inode_buffer(ip, &dibh); |
424 | if (error) | 424 | if (error) |
425 | return error; | 425 | return error; |
426 | 426 | ||
427 | if (diff > 0) | 427 | if (diff > 0) |
428 | inc_nlink(&ip->i_inode); | 428 | inc_nlink(&ip->i_inode); |
429 | else | 429 | else |
430 | drop_nlink(&ip->i_inode); | 430 | drop_nlink(&ip->i_inode); |
431 | 431 | ||
432 | ip->i_inode.i_ctime = CURRENT_TIME; | 432 | ip->i_inode.i_ctime = CURRENT_TIME; |
433 | 433 | ||
434 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 434 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
435 | gfs2_dinode_out(ip, dibh->b_data); | 435 | gfs2_dinode_out(ip, dibh->b_data); |
436 | brelse(dibh); | 436 | brelse(dibh); |
437 | mark_inode_dirty(&ip->i_inode); | 437 | mark_inode_dirty(&ip->i_inode); |
438 | 438 | ||
439 | if (ip->i_inode.i_nlink == 0) | 439 | if (ip->i_inode.i_nlink == 0) |
440 | gfs2_unlink_di(&ip->i_inode); /* mark inode unlinked */ | 440 | gfs2_unlink_di(&ip->i_inode); /* mark inode unlinked */ |
441 | 441 | ||
442 | return error; | 442 | return error; |
443 | } | 443 | } |
444 | 444 | ||
445 | struct inode *gfs2_lookup_simple(struct inode *dip, const char *name) | 445 | struct inode *gfs2_lookup_simple(struct inode *dip, const char *name) |
446 | { | 446 | { |
447 | struct qstr qstr; | 447 | struct qstr qstr; |
448 | struct inode *inode; | 448 | struct inode *inode; |
449 | gfs2_str2qstr(&qstr, name); | 449 | gfs2_str2qstr(&qstr, name); |
450 | inode = gfs2_lookupi(dip, &qstr, 1); | 450 | inode = gfs2_lookupi(dip, &qstr, 1); |
451 | /* gfs2_lookupi has inconsistent callers: vfs | 451 | /* gfs2_lookupi has inconsistent callers: vfs |
452 | * related routines expect NULL for no entry found, | 452 | * related routines expect NULL for no entry found, |
453 | * gfs2_lookup_simple callers expect ENOENT | 453 | * gfs2_lookup_simple callers expect ENOENT |
454 | * and do not check for NULL. | 454 | * and do not check for NULL. |
455 | */ | 455 | */ |
456 | if (inode == NULL) | 456 | if (inode == NULL) |
457 | return ERR_PTR(-ENOENT); | 457 | return ERR_PTR(-ENOENT); |
458 | else | 458 | else |
459 | return inode; | 459 | return inode; |
460 | } | 460 | } |
461 | 461 | ||
462 | 462 | ||
463 | /** | 463 | /** |
464 | * gfs2_lookupi - Look up a filename in a directory and return its inode | 464 | * gfs2_lookupi - Look up a filename in a directory and return its inode |
465 | * @d_gh: An initialized holder for the directory glock | 465 | * @d_gh: An initialized holder for the directory glock |
466 | * @name: The name of the inode to look for | 466 | * @name: The name of the inode to look for |
467 | * @is_root: If 1, ignore the caller's permissions | 467 | * @is_root: If 1, ignore the caller's permissions |
468 | * @i_gh: An uninitialized holder for the new inode glock | 468 | * @i_gh: An uninitialized holder for the new inode glock |
469 | * | 469 | * |
470 | * This can be called via the VFS filldir function when NFS is doing | 470 | * This can be called via the VFS filldir function when NFS is doing |
471 | * a readdirplus and the inode which its intending to stat isn't | 471 | * a readdirplus and the inode which its intending to stat isn't |
472 | * already in cache. In this case we must not take the directory glock | 472 | * already in cache. In this case we must not take the directory glock |
473 | * again, since the readdir call will have already taken that lock. | 473 | * again, since the readdir call will have already taken that lock. |
474 | * | 474 | * |
475 | * Returns: errno | 475 | * Returns: errno |
476 | */ | 476 | */ |
477 | 477 | ||
478 | struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, | 478 | struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, |
479 | int is_root) | 479 | int is_root) |
480 | { | 480 | { |
481 | struct super_block *sb = dir->i_sb; | 481 | struct super_block *sb = dir->i_sb; |
482 | struct gfs2_inode *dip = GFS2_I(dir); | 482 | struct gfs2_inode *dip = GFS2_I(dir); |
483 | struct gfs2_holder d_gh; | 483 | struct gfs2_holder d_gh; |
484 | int error = 0; | 484 | int error = 0; |
485 | struct inode *inode = NULL; | 485 | struct inode *inode = NULL; |
486 | int unlock = 0; | 486 | int unlock = 0; |
487 | 487 | ||
488 | if (!name->len || name->len > GFS2_FNAMESIZE) | 488 | if (!name->len || name->len > GFS2_FNAMESIZE) |
489 | return ERR_PTR(-ENAMETOOLONG); | 489 | return ERR_PTR(-ENAMETOOLONG); |
490 | 490 | ||
491 | if ((name->len == 1 && memcmp(name->name, ".", 1) == 0) || | 491 | if ((name->len == 1 && memcmp(name->name, ".", 1) == 0) || |
492 | (name->len == 2 && memcmp(name->name, "..", 2) == 0 && | 492 | (name->len == 2 && memcmp(name->name, "..", 2) == 0 && |
493 | dir == sb->s_root->d_inode)) { | 493 | dir == sb->s_root->d_inode)) { |
494 | igrab(dir); | 494 | igrab(dir); |
495 | return dir; | 495 | return dir; |
496 | } | 496 | } |
497 | 497 | ||
498 | if (gfs2_glock_is_locked_by_me(dip->i_gl) == NULL) { | 498 | if (gfs2_glock_is_locked_by_me(dip->i_gl) == NULL) { |
499 | error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &d_gh); | 499 | error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &d_gh); |
500 | if (error) | 500 | if (error) |
501 | return ERR_PTR(error); | 501 | return ERR_PTR(error); |
502 | unlock = 1; | 502 | unlock = 1; |
503 | } | 503 | } |
504 | 504 | ||
505 | if (!is_root) { | 505 | if (!is_root) { |
506 | error = gfs2_permission(dir, MAY_EXEC); | 506 | error = gfs2_permission(dir, MAY_EXEC); |
507 | if (error) | 507 | if (error) |
508 | goto out; | 508 | goto out; |
509 | } | 509 | } |
510 | 510 | ||
511 | inode = gfs2_dir_search(dir, name); | 511 | inode = gfs2_dir_search(dir, name); |
512 | if (IS_ERR(inode)) | 512 | if (IS_ERR(inode)) |
513 | error = PTR_ERR(inode); | 513 | error = PTR_ERR(inode); |
514 | out: | 514 | out: |
515 | if (unlock) | 515 | if (unlock) |
516 | gfs2_glock_dq_uninit(&d_gh); | 516 | gfs2_glock_dq_uninit(&d_gh); |
517 | if (error == -ENOENT) | 517 | if (error == -ENOENT) |
518 | return NULL; | 518 | return NULL; |
519 | return inode ? inode : ERR_PTR(error); | 519 | return inode ? inode : ERR_PTR(error); |
520 | } | 520 | } |
521 | 521 | ||
522 | static void gfs2_inum_range_in(struct gfs2_inum_range_host *ir, const void *buf) | 522 | static void gfs2_inum_range_in(struct gfs2_inum_range_host *ir, const void *buf) |
523 | { | 523 | { |
524 | const struct gfs2_inum_range *str = buf; | 524 | const struct gfs2_inum_range *str = buf; |
525 | 525 | ||
526 | ir->ir_start = be64_to_cpu(str->ir_start); | 526 | ir->ir_start = be64_to_cpu(str->ir_start); |
527 | ir->ir_length = be64_to_cpu(str->ir_length); | 527 | ir->ir_length = be64_to_cpu(str->ir_length); |
528 | } | 528 | } |
529 | 529 | ||
530 | static void gfs2_inum_range_out(const struct gfs2_inum_range_host *ir, void *buf) | 530 | static void gfs2_inum_range_out(const struct gfs2_inum_range_host *ir, void *buf) |
531 | { | 531 | { |
532 | struct gfs2_inum_range *str = buf; | 532 | struct gfs2_inum_range *str = buf; |
533 | 533 | ||
534 | str->ir_start = cpu_to_be64(ir->ir_start); | 534 | str->ir_start = cpu_to_be64(ir->ir_start); |
535 | str->ir_length = cpu_to_be64(ir->ir_length); | 535 | str->ir_length = cpu_to_be64(ir->ir_length); |
536 | } | 536 | } |
537 | 537 | ||
538 | static int pick_formal_ino_1(struct gfs2_sbd *sdp, u64 *formal_ino) | 538 | static int pick_formal_ino_1(struct gfs2_sbd *sdp, u64 *formal_ino) |
539 | { | 539 | { |
540 | struct gfs2_inode *ip = GFS2_I(sdp->sd_ir_inode); | 540 | struct gfs2_inode *ip = GFS2_I(sdp->sd_ir_inode); |
541 | struct buffer_head *bh; | 541 | struct buffer_head *bh; |
542 | struct gfs2_inum_range_host ir; | 542 | struct gfs2_inum_range_host ir; |
543 | int error; | 543 | int error; |
544 | 544 | ||
545 | error = gfs2_trans_begin(sdp, RES_DINODE, 0); | 545 | error = gfs2_trans_begin(sdp, RES_DINODE, 0); |
546 | if (error) | 546 | if (error) |
547 | return error; | 547 | return error; |
548 | mutex_lock(&sdp->sd_inum_mutex); | 548 | mutex_lock(&sdp->sd_inum_mutex); |
549 | 549 | ||
550 | error = gfs2_meta_inode_buffer(ip, &bh); | 550 | error = gfs2_meta_inode_buffer(ip, &bh); |
551 | if (error) { | 551 | if (error) { |
552 | mutex_unlock(&sdp->sd_inum_mutex); | 552 | mutex_unlock(&sdp->sd_inum_mutex); |
553 | gfs2_trans_end(sdp); | 553 | gfs2_trans_end(sdp); |
554 | return error; | 554 | return error; |
555 | } | 555 | } |
556 | 556 | ||
557 | gfs2_inum_range_in(&ir, bh->b_data + sizeof(struct gfs2_dinode)); | 557 | gfs2_inum_range_in(&ir, bh->b_data + sizeof(struct gfs2_dinode)); |
558 | 558 | ||
559 | if (ir.ir_length) { | 559 | if (ir.ir_length) { |
560 | *formal_ino = ir.ir_start++; | 560 | *formal_ino = ir.ir_start++; |
561 | ir.ir_length--; | 561 | ir.ir_length--; |
562 | gfs2_trans_add_bh(ip->i_gl, bh, 1); | 562 | gfs2_trans_add_bh(ip->i_gl, bh, 1); |
563 | gfs2_inum_range_out(&ir, | 563 | gfs2_inum_range_out(&ir, |
564 | bh->b_data + sizeof(struct gfs2_dinode)); | 564 | bh->b_data + sizeof(struct gfs2_dinode)); |
565 | brelse(bh); | 565 | brelse(bh); |
566 | mutex_unlock(&sdp->sd_inum_mutex); | 566 | mutex_unlock(&sdp->sd_inum_mutex); |
567 | gfs2_trans_end(sdp); | 567 | gfs2_trans_end(sdp); |
568 | return 0; | 568 | return 0; |
569 | } | 569 | } |
570 | 570 | ||
571 | brelse(bh); | 571 | brelse(bh); |
572 | 572 | ||
573 | mutex_unlock(&sdp->sd_inum_mutex); | 573 | mutex_unlock(&sdp->sd_inum_mutex); |
574 | gfs2_trans_end(sdp); | 574 | gfs2_trans_end(sdp); |
575 | 575 | ||
576 | return 1; | 576 | return 1; |
577 | } | 577 | } |
578 | 578 | ||
579 | static int pick_formal_ino_2(struct gfs2_sbd *sdp, u64 *formal_ino) | 579 | static int pick_formal_ino_2(struct gfs2_sbd *sdp, u64 *formal_ino) |
580 | { | 580 | { |
581 | struct gfs2_inode *ip = GFS2_I(sdp->sd_ir_inode); | 581 | struct gfs2_inode *ip = GFS2_I(sdp->sd_ir_inode); |
582 | struct gfs2_inode *m_ip = GFS2_I(sdp->sd_inum_inode); | 582 | struct gfs2_inode *m_ip = GFS2_I(sdp->sd_inum_inode); |
583 | struct gfs2_holder gh; | 583 | struct gfs2_holder gh; |
584 | struct buffer_head *bh; | 584 | struct buffer_head *bh; |
585 | struct gfs2_inum_range_host ir; | 585 | struct gfs2_inum_range_host ir; |
586 | int error; | 586 | int error; |
587 | 587 | ||
588 | error = gfs2_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | 588 | error = gfs2_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); |
589 | if (error) | 589 | if (error) |
590 | return error; | 590 | return error; |
591 | 591 | ||
592 | error = gfs2_trans_begin(sdp, 2 * RES_DINODE, 0); | 592 | error = gfs2_trans_begin(sdp, 2 * RES_DINODE, 0); |
593 | if (error) | 593 | if (error) |
594 | goto out; | 594 | goto out; |
595 | mutex_lock(&sdp->sd_inum_mutex); | 595 | mutex_lock(&sdp->sd_inum_mutex); |
596 | 596 | ||
597 | error = gfs2_meta_inode_buffer(ip, &bh); | 597 | error = gfs2_meta_inode_buffer(ip, &bh); |
598 | if (error) | 598 | if (error) |
599 | goto out_end_trans; | 599 | goto out_end_trans; |
600 | 600 | ||
601 | gfs2_inum_range_in(&ir, bh->b_data + sizeof(struct gfs2_dinode)); | 601 | gfs2_inum_range_in(&ir, bh->b_data + sizeof(struct gfs2_dinode)); |
602 | 602 | ||
603 | if (!ir.ir_length) { | 603 | if (!ir.ir_length) { |
604 | struct buffer_head *m_bh; | 604 | struct buffer_head *m_bh; |
605 | u64 x, y; | 605 | u64 x, y; |
606 | __be64 z; | 606 | __be64 z; |
607 | 607 | ||
608 | error = gfs2_meta_inode_buffer(m_ip, &m_bh); | 608 | error = gfs2_meta_inode_buffer(m_ip, &m_bh); |
609 | if (error) | 609 | if (error) |
610 | goto out_brelse; | 610 | goto out_brelse; |
611 | 611 | ||
612 | z = *(__be64 *)(m_bh->b_data + sizeof(struct gfs2_dinode)); | 612 | z = *(__be64 *)(m_bh->b_data + sizeof(struct gfs2_dinode)); |
613 | x = y = be64_to_cpu(z); | 613 | x = y = be64_to_cpu(z); |
614 | ir.ir_start = x; | 614 | ir.ir_start = x; |
615 | ir.ir_length = GFS2_INUM_QUANTUM; | 615 | ir.ir_length = GFS2_INUM_QUANTUM; |
616 | x += GFS2_INUM_QUANTUM; | 616 | x += GFS2_INUM_QUANTUM; |
617 | if (x < y) | 617 | if (x < y) |
618 | gfs2_consist_inode(m_ip); | 618 | gfs2_consist_inode(m_ip); |
619 | z = cpu_to_be64(x); | 619 | z = cpu_to_be64(x); |
620 | gfs2_trans_add_bh(m_ip->i_gl, m_bh, 1); | 620 | gfs2_trans_add_bh(m_ip->i_gl, m_bh, 1); |
621 | *(__be64 *)(m_bh->b_data + sizeof(struct gfs2_dinode)) = z; | 621 | *(__be64 *)(m_bh->b_data + sizeof(struct gfs2_dinode)) = z; |
622 | 622 | ||
623 | brelse(m_bh); | 623 | brelse(m_bh); |
624 | } | 624 | } |
625 | 625 | ||
626 | *formal_ino = ir.ir_start++; | 626 | *formal_ino = ir.ir_start++; |
627 | ir.ir_length--; | 627 | ir.ir_length--; |
628 | 628 | ||
629 | gfs2_trans_add_bh(ip->i_gl, bh, 1); | 629 | gfs2_trans_add_bh(ip->i_gl, bh, 1); |
630 | gfs2_inum_range_out(&ir, bh->b_data + sizeof(struct gfs2_dinode)); | 630 | gfs2_inum_range_out(&ir, bh->b_data + sizeof(struct gfs2_dinode)); |
631 | 631 | ||
632 | out_brelse: | 632 | out_brelse: |
633 | brelse(bh); | 633 | brelse(bh); |
634 | out_end_trans: | 634 | out_end_trans: |
635 | mutex_unlock(&sdp->sd_inum_mutex); | 635 | mutex_unlock(&sdp->sd_inum_mutex); |
636 | gfs2_trans_end(sdp); | 636 | gfs2_trans_end(sdp); |
637 | out: | 637 | out: |
638 | gfs2_glock_dq_uninit(&gh); | 638 | gfs2_glock_dq_uninit(&gh); |
639 | return error; | 639 | return error; |
640 | } | 640 | } |
641 | 641 | ||
642 | static int pick_formal_ino(struct gfs2_sbd *sdp, u64 *inum) | 642 | static int pick_formal_ino(struct gfs2_sbd *sdp, u64 *inum) |
643 | { | 643 | { |
644 | int error; | 644 | int error; |
645 | 645 | ||
646 | error = pick_formal_ino_1(sdp, inum); | 646 | error = pick_formal_ino_1(sdp, inum); |
647 | if (error <= 0) | 647 | if (error <= 0) |
648 | return error; | 648 | return error; |
649 | 649 | ||
650 | error = pick_formal_ino_2(sdp, inum); | 650 | error = pick_formal_ino_2(sdp, inum); |
651 | 651 | ||
652 | return error; | 652 | return error; |
653 | } | 653 | } |
654 | 654 | ||
655 | /** | 655 | /** |
656 | * create_ok - OK to create a new on-disk inode here? | 656 | * create_ok - OK to create a new on-disk inode here? |
657 | * @dip: Directory in which dinode is to be created | 657 | * @dip: Directory in which dinode is to be created |
658 | * @name: Name of new dinode | 658 | * @name: Name of new dinode |
659 | * @mode: | 659 | * @mode: |
660 | * | 660 | * |
661 | * Returns: errno | 661 | * Returns: errno |
662 | */ | 662 | */ |
663 | 663 | ||
664 | static int create_ok(struct gfs2_inode *dip, const struct qstr *name, | 664 | static int create_ok(struct gfs2_inode *dip, const struct qstr *name, |
665 | unsigned int mode) | 665 | unsigned int mode) |
666 | { | 666 | { |
667 | int error; | 667 | int error; |
668 | 668 | ||
669 | error = gfs2_permission(&dip->i_inode, MAY_WRITE | MAY_EXEC); | 669 | error = gfs2_permission(&dip->i_inode, MAY_WRITE | MAY_EXEC); |
670 | if (error) | 670 | if (error) |
671 | return error; | 671 | return error; |
672 | 672 | ||
673 | /* Don't create entries in an unlinked directory */ | 673 | /* Don't create entries in an unlinked directory */ |
674 | if (!dip->i_inode.i_nlink) | 674 | if (!dip->i_inode.i_nlink) |
675 | return -EPERM; | 675 | return -EPERM; |
676 | 676 | ||
677 | error = gfs2_dir_check(&dip->i_inode, name, NULL); | 677 | error = gfs2_dir_check(&dip->i_inode, name, NULL); |
678 | switch (error) { | 678 | switch (error) { |
679 | case -ENOENT: | 679 | case -ENOENT: |
680 | error = 0; | 680 | error = 0; |
681 | break; | 681 | break; |
682 | case 0: | 682 | case 0: |
683 | return -EEXIST; | 683 | return -EEXIST; |
684 | default: | 684 | default: |
685 | return error; | 685 | return error; |
686 | } | 686 | } |
687 | 687 | ||
688 | if (dip->i_entries == (u32)-1) | 688 | if (dip->i_entries == (u32)-1) |
689 | return -EFBIG; | 689 | return -EFBIG; |
690 | if (S_ISDIR(mode) && dip->i_inode.i_nlink == (u32)-1) | 690 | if (S_ISDIR(mode) && dip->i_inode.i_nlink == (u32)-1) |
691 | return -EMLINK; | 691 | return -EMLINK; |
692 | 692 | ||
693 | return 0; | 693 | return 0; |
694 | } | 694 | } |
695 | 695 | ||
696 | static void munge_mode_uid_gid(struct gfs2_inode *dip, unsigned int *mode, | 696 | static void munge_mode_uid_gid(struct gfs2_inode *dip, unsigned int *mode, |
697 | unsigned int *uid, unsigned int *gid) | 697 | unsigned int *uid, unsigned int *gid) |
698 | { | 698 | { |
699 | if (GFS2_SB(&dip->i_inode)->sd_args.ar_suiddir && | 699 | if (GFS2_SB(&dip->i_inode)->sd_args.ar_suiddir && |
700 | (dip->i_inode.i_mode & S_ISUID) && dip->i_inode.i_uid) { | 700 | (dip->i_inode.i_mode & S_ISUID) && dip->i_inode.i_uid) { |
701 | if (S_ISDIR(*mode)) | 701 | if (S_ISDIR(*mode)) |
702 | *mode |= S_ISUID; | 702 | *mode |= S_ISUID; |
703 | else if (dip->i_inode.i_uid != current_fsuid()) | 703 | else if (dip->i_inode.i_uid != current_fsuid()) |
704 | *mode &= ~07111; | 704 | *mode &= ~07111; |
705 | *uid = dip->i_inode.i_uid; | 705 | *uid = dip->i_inode.i_uid; |
706 | } else | 706 | } else |
707 | *uid = current_fsuid(); | 707 | *uid = current_fsuid(); |
708 | 708 | ||
709 | if (dip->i_inode.i_mode & S_ISGID) { | 709 | if (dip->i_inode.i_mode & S_ISGID) { |
710 | if (S_ISDIR(*mode)) | 710 | if (S_ISDIR(*mode)) |
711 | *mode |= S_ISGID; | 711 | *mode |= S_ISGID; |
712 | *gid = dip->i_inode.i_gid; | 712 | *gid = dip->i_inode.i_gid; |
713 | } else | 713 | } else |
714 | *gid = current_fsgid(); | 714 | *gid = current_fsgid(); |
715 | } | 715 | } |
716 | 716 | ||
717 | static int alloc_dinode(struct gfs2_inode *dip, u64 *no_addr, u64 *generation) | 717 | static int alloc_dinode(struct gfs2_inode *dip, u64 *no_addr, u64 *generation) |
718 | { | 718 | { |
719 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 719 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
720 | int error; | 720 | int error; |
721 | 721 | ||
722 | if (gfs2_alloc_get(dip) == NULL) | 722 | if (gfs2_alloc_get(dip) == NULL) |
723 | return -ENOMEM; | 723 | return -ENOMEM; |
724 | 724 | ||
725 | dip->i_alloc->al_requested = RES_DINODE; | 725 | dip->i_alloc->al_requested = RES_DINODE; |
726 | error = gfs2_inplace_reserve(dip); | 726 | error = gfs2_inplace_reserve(dip); |
727 | if (error) | 727 | if (error) |
728 | goto out; | 728 | goto out; |
729 | 729 | ||
730 | error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_STATFS, 0); | 730 | error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_STATFS, 0); |
731 | if (error) | 731 | if (error) |
732 | goto out_ipreserv; | 732 | goto out_ipreserv; |
733 | 733 | ||
734 | *no_addr = gfs2_alloc_di(dip, generation); | 734 | *no_addr = gfs2_alloc_di(dip, generation); |
735 | 735 | ||
736 | gfs2_trans_end(sdp); | 736 | gfs2_trans_end(sdp); |
737 | 737 | ||
738 | out_ipreserv: | 738 | out_ipreserv: |
739 | gfs2_inplace_release(dip); | 739 | gfs2_inplace_release(dip); |
740 | out: | 740 | out: |
741 | gfs2_alloc_put(dip); | 741 | gfs2_alloc_put(dip); |
742 | return error; | 742 | return error; |
743 | } | 743 | } |
744 | 744 | ||
745 | /** | 745 | /** |
746 | * init_dinode - Fill in a new dinode structure | 746 | * init_dinode - Fill in a new dinode structure |
747 | * @dip: the directory this inode is being created in | 747 | * @dip: the directory this inode is being created in |
748 | * @gl: The glock covering the new inode | 748 | * @gl: The glock covering the new inode |
749 | * @inum: the inode number | 749 | * @inum: the inode number |
750 | * @mode: the file permissions | 750 | * @mode: the file permissions |
751 | * @uid: | 751 | * @uid: |
752 | * @gid: | 752 | * @gid: |
753 | * | 753 | * |
754 | */ | 754 | */ |
755 | 755 | ||
756 | static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | 756 | static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, |
757 | const struct gfs2_inum_host *inum, unsigned int mode, | 757 | const struct gfs2_inum_host *inum, unsigned int mode, |
758 | unsigned int uid, unsigned int gid, | 758 | unsigned int uid, unsigned int gid, |
759 | const u64 *generation, dev_t dev, struct buffer_head **bhp) | 759 | const u64 *generation, dev_t dev, struct buffer_head **bhp) |
760 | { | 760 | { |
761 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 761 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
762 | struct gfs2_dinode *di; | 762 | struct gfs2_dinode *di; |
763 | struct buffer_head *dibh; | 763 | struct buffer_head *dibh; |
764 | struct timespec tv = CURRENT_TIME; | 764 | struct timespec tv = CURRENT_TIME; |
765 | 765 | ||
766 | dibh = gfs2_meta_new(gl, inum->no_addr); | 766 | dibh = gfs2_meta_new(gl, inum->no_addr); |
767 | gfs2_trans_add_bh(gl, dibh, 1); | 767 | gfs2_trans_add_bh(gl, dibh, 1); |
768 | gfs2_metatype_set(dibh, GFS2_METATYPE_DI, GFS2_FORMAT_DI); | 768 | gfs2_metatype_set(dibh, GFS2_METATYPE_DI, GFS2_FORMAT_DI); |
769 | gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode)); | 769 | gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode)); |
770 | di = (struct gfs2_dinode *)dibh->b_data; | 770 | di = (struct gfs2_dinode *)dibh->b_data; |
771 | 771 | ||
772 | di->di_num.no_formal_ino = cpu_to_be64(inum->no_formal_ino); | 772 | di->di_num.no_formal_ino = cpu_to_be64(inum->no_formal_ino); |
773 | di->di_num.no_addr = cpu_to_be64(inum->no_addr); | 773 | di->di_num.no_addr = cpu_to_be64(inum->no_addr); |
774 | di->di_mode = cpu_to_be32(mode); | 774 | di->di_mode = cpu_to_be32(mode); |
775 | di->di_uid = cpu_to_be32(uid); | 775 | di->di_uid = cpu_to_be32(uid); |
776 | di->di_gid = cpu_to_be32(gid); | 776 | di->di_gid = cpu_to_be32(gid); |
777 | di->di_nlink = 0; | 777 | di->di_nlink = 0; |
778 | di->di_size = 0; | 778 | di->di_size = 0; |
779 | di->di_blocks = cpu_to_be64(1); | 779 | di->di_blocks = cpu_to_be64(1); |
780 | di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(tv.tv_sec); | 780 | di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(tv.tv_sec); |
781 | di->di_major = cpu_to_be32(MAJOR(dev)); | 781 | di->di_major = cpu_to_be32(MAJOR(dev)); |
782 | di->di_minor = cpu_to_be32(MINOR(dev)); | 782 | di->di_minor = cpu_to_be32(MINOR(dev)); |
783 | di->di_goal_meta = di->di_goal_data = cpu_to_be64(inum->no_addr); | 783 | di->di_goal_meta = di->di_goal_data = cpu_to_be64(inum->no_addr); |
784 | di->di_generation = cpu_to_be64(*generation); | 784 | di->di_generation = cpu_to_be64(*generation); |
785 | di->di_flags = 0; | 785 | di->di_flags = 0; |
786 | 786 | ||
787 | if (S_ISREG(mode)) { | 787 | if (S_ISREG(mode)) { |
788 | if ((dip->i_diskflags & GFS2_DIF_INHERIT_JDATA) || | 788 | if ((dip->i_diskflags & GFS2_DIF_INHERIT_JDATA) || |
789 | gfs2_tune_get(sdp, gt_new_files_jdata)) | 789 | gfs2_tune_get(sdp, gt_new_files_jdata)) |
790 | di->di_flags |= cpu_to_be32(GFS2_DIF_JDATA); | 790 | di->di_flags |= cpu_to_be32(GFS2_DIF_JDATA); |
791 | } else if (S_ISDIR(mode)) { | 791 | } else if (S_ISDIR(mode)) { |
792 | di->di_flags |= cpu_to_be32(dip->i_diskflags & | 792 | di->di_flags |= cpu_to_be32(dip->i_diskflags & |
793 | GFS2_DIF_INHERIT_JDATA); | 793 | GFS2_DIF_INHERIT_JDATA); |
794 | } | 794 | } |
795 | 795 | ||
796 | di->__pad1 = 0; | 796 | di->__pad1 = 0; |
797 | di->di_payload_format = cpu_to_be32(S_ISDIR(mode) ? GFS2_FORMAT_DE : 0); | 797 | di->di_payload_format = cpu_to_be32(S_ISDIR(mode) ? GFS2_FORMAT_DE : 0); |
798 | di->di_height = 0; | 798 | di->di_height = 0; |
799 | di->__pad2 = 0; | 799 | di->__pad2 = 0; |
800 | di->__pad3 = 0; | 800 | di->__pad3 = 0; |
801 | di->di_depth = 0; | 801 | di->di_depth = 0; |
802 | di->di_entries = 0; | 802 | di->di_entries = 0; |
803 | memset(&di->__pad4, 0, sizeof(di->__pad4)); | 803 | memset(&di->__pad4, 0, sizeof(di->__pad4)); |
804 | di->di_eattr = 0; | 804 | di->di_eattr = 0; |
805 | di->di_atime_nsec = cpu_to_be32(tv.tv_nsec); | 805 | di->di_atime_nsec = cpu_to_be32(tv.tv_nsec); |
806 | di->di_mtime_nsec = cpu_to_be32(tv.tv_nsec); | 806 | di->di_mtime_nsec = cpu_to_be32(tv.tv_nsec); |
807 | di->di_ctime_nsec = cpu_to_be32(tv.tv_nsec); | 807 | di->di_ctime_nsec = cpu_to_be32(tv.tv_nsec); |
808 | memset(&di->di_reserved, 0, sizeof(di->di_reserved)); | 808 | memset(&di->di_reserved, 0, sizeof(di->di_reserved)); |
809 | 809 | ||
810 | set_buffer_uptodate(dibh); | 810 | set_buffer_uptodate(dibh); |
811 | 811 | ||
812 | *bhp = dibh; | 812 | *bhp = dibh; |
813 | } | 813 | } |
814 | 814 | ||
815 | static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | 815 | static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, |
816 | unsigned int mode, const struct gfs2_inum_host *inum, | 816 | unsigned int mode, const struct gfs2_inum_host *inum, |
817 | const u64 *generation, dev_t dev, struct buffer_head **bhp) | 817 | const u64 *generation, dev_t dev, struct buffer_head **bhp) |
818 | { | 818 | { |
819 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 819 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
820 | unsigned int uid, gid; | 820 | unsigned int uid, gid; |
821 | int error; | 821 | int error; |
822 | 822 | ||
823 | munge_mode_uid_gid(dip, &mode, &uid, &gid); | 823 | munge_mode_uid_gid(dip, &mode, &uid, &gid); |
824 | if (!gfs2_alloc_get(dip)) | 824 | if (!gfs2_alloc_get(dip)) |
825 | return -ENOMEM; | 825 | return -ENOMEM; |
826 | 826 | ||
827 | error = gfs2_quota_lock(dip, uid, gid); | 827 | error = gfs2_quota_lock(dip, uid, gid); |
828 | if (error) | 828 | if (error) |
829 | goto out; | 829 | goto out; |
830 | 830 | ||
831 | error = gfs2_quota_check(dip, uid, gid); | 831 | error = gfs2_quota_check(dip, uid, gid); |
832 | if (error) | 832 | if (error) |
833 | goto out_quota; | 833 | goto out_quota; |
834 | 834 | ||
835 | error = gfs2_trans_begin(sdp, RES_DINODE + RES_QUOTA, 0); | 835 | error = gfs2_trans_begin(sdp, RES_DINODE + RES_QUOTA, 0); |
836 | if (error) | 836 | if (error) |
837 | goto out_quota; | 837 | goto out_quota; |
838 | 838 | ||
839 | init_dinode(dip, gl, inum, mode, uid, gid, generation, dev, bhp); | 839 | init_dinode(dip, gl, inum, mode, uid, gid, generation, dev, bhp); |
840 | gfs2_quota_change(dip, +1, uid, gid); | 840 | gfs2_quota_change(dip, +1, uid, gid); |
841 | gfs2_trans_end(sdp); | 841 | gfs2_trans_end(sdp); |
842 | 842 | ||
843 | out_quota: | 843 | out_quota: |
844 | gfs2_quota_unlock(dip); | 844 | gfs2_quota_unlock(dip); |
845 | out: | 845 | out: |
846 | gfs2_alloc_put(dip); | 846 | gfs2_alloc_put(dip); |
847 | return error; | 847 | return error; |
848 | } | 848 | } |
849 | 849 | ||
850 | static int link_dinode(struct gfs2_inode *dip, const struct qstr *name, | 850 | static int link_dinode(struct gfs2_inode *dip, const struct qstr *name, |
851 | struct gfs2_inode *ip) | 851 | struct gfs2_inode *ip) |
852 | { | 852 | { |
853 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 853 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
854 | struct gfs2_alloc *al; | 854 | struct gfs2_alloc *al; |
855 | int alloc_required; | 855 | int alloc_required; |
856 | struct buffer_head *dibh; | 856 | struct buffer_head *dibh; |
857 | int error; | 857 | int error; |
858 | 858 | ||
859 | al = gfs2_alloc_get(dip); | 859 | al = gfs2_alloc_get(dip); |
860 | if (!al) | 860 | if (!al) |
861 | return -ENOMEM; | 861 | return -ENOMEM; |
862 | 862 | ||
863 | error = gfs2_quota_lock(dip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); | 863 | error = gfs2_quota_lock(dip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); |
864 | if (error) | 864 | if (error) |
865 | goto fail; | 865 | goto fail; |
866 | 866 | ||
867 | error = alloc_required = gfs2_diradd_alloc_required(&dip->i_inode, name); | 867 | error = alloc_required = gfs2_diradd_alloc_required(&dip->i_inode, name); |
868 | if (alloc_required < 0) | 868 | if (alloc_required < 0) |
869 | goto fail_quota_locks; | 869 | goto fail_quota_locks; |
870 | if (alloc_required) { | 870 | if (alloc_required) { |
871 | error = gfs2_quota_check(dip, dip->i_inode.i_uid, dip->i_inode.i_gid); | 871 | error = gfs2_quota_check(dip, dip->i_inode.i_uid, dip->i_inode.i_gid); |
872 | if (error) | 872 | if (error) |
873 | goto fail_quota_locks; | 873 | goto fail_quota_locks; |
874 | 874 | ||
875 | al->al_requested = sdp->sd_max_dirres; | 875 | al->al_requested = sdp->sd_max_dirres; |
876 | 876 | ||
877 | error = gfs2_inplace_reserve(dip); | 877 | error = gfs2_inplace_reserve(dip); |
878 | if (error) | 878 | if (error) |
879 | goto fail_quota_locks; | 879 | goto fail_quota_locks; |
880 | 880 | ||
881 | error = gfs2_trans_begin(sdp, sdp->sd_max_dirres + | 881 | error = gfs2_trans_begin(sdp, sdp->sd_max_dirres + |
882 | al->al_rgd->rd_length + | 882 | al->al_rgd->rd_length + |
883 | 2 * RES_DINODE + | 883 | 2 * RES_DINODE + |
884 | RES_STATFS + RES_QUOTA, 0); | 884 | RES_STATFS + RES_QUOTA, 0); |
885 | if (error) | 885 | if (error) |
886 | goto fail_ipreserv; | 886 | goto fail_ipreserv; |
887 | } else { | 887 | } else { |
888 | error = gfs2_trans_begin(sdp, RES_LEAF + 2 * RES_DINODE, 0); | 888 | error = gfs2_trans_begin(sdp, RES_LEAF + 2 * RES_DINODE, 0); |
889 | if (error) | 889 | if (error) |
890 | goto fail_quota_locks; | 890 | goto fail_quota_locks; |
891 | } | 891 | } |
892 | 892 | ||
893 | error = gfs2_dir_add(&dip->i_inode, name, ip, IF2DT(ip->i_inode.i_mode)); | 893 | error = gfs2_dir_add(&dip->i_inode, name, ip, IF2DT(ip->i_inode.i_mode)); |
894 | if (error) | 894 | if (error) |
895 | goto fail_end_trans; | 895 | goto fail_end_trans; |
896 | 896 | ||
897 | error = gfs2_meta_inode_buffer(ip, &dibh); | 897 | error = gfs2_meta_inode_buffer(ip, &dibh); |
898 | if (error) | 898 | if (error) |
899 | goto fail_end_trans; | 899 | goto fail_end_trans; |
900 | ip->i_inode.i_nlink = 1; | 900 | ip->i_inode.i_nlink = 1; |
901 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 901 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
902 | gfs2_dinode_out(ip, dibh->b_data); | 902 | gfs2_dinode_out(ip, dibh->b_data); |
903 | brelse(dibh); | 903 | brelse(dibh); |
904 | return 0; | 904 | return 0; |
905 | 905 | ||
906 | fail_end_trans: | 906 | fail_end_trans: |
907 | gfs2_trans_end(sdp); | 907 | gfs2_trans_end(sdp); |
908 | 908 | ||
909 | fail_ipreserv: | 909 | fail_ipreserv: |
910 | if (dip->i_alloc->al_rgd) | 910 | if (dip->i_alloc->al_rgd) |
911 | gfs2_inplace_release(dip); | 911 | gfs2_inplace_release(dip); |
912 | 912 | ||
913 | fail_quota_locks: | 913 | fail_quota_locks: |
914 | gfs2_quota_unlock(dip); | 914 | gfs2_quota_unlock(dip); |
915 | 915 | ||
916 | fail: | 916 | fail: |
917 | gfs2_alloc_put(dip); | 917 | gfs2_alloc_put(dip); |
918 | return error; | 918 | return error; |
919 | } | 919 | } |
920 | 920 | ||
921 | static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip) | 921 | static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip) |
922 | { | 922 | { |
923 | int err; | 923 | int err; |
924 | size_t len; | 924 | size_t len; |
925 | void *value; | 925 | void *value; |
926 | char *name; | 926 | char *name; |
927 | struct gfs2_ea_request er; | 927 | struct gfs2_ea_request er; |
928 | 928 | ||
929 | err = security_inode_init_security(&ip->i_inode, &dip->i_inode, | 929 | err = security_inode_init_security(&ip->i_inode, &dip->i_inode, |
930 | &name, &value, &len); | 930 | &name, &value, &len); |
931 | 931 | ||
932 | if (err) { | 932 | if (err) { |
933 | if (err == -EOPNOTSUPP) | 933 | if (err == -EOPNOTSUPP) |
934 | return 0; | 934 | return 0; |
935 | return err; | 935 | return err; |
936 | } | 936 | } |
937 | 937 | ||
938 | memset(&er, 0, sizeof(struct gfs2_ea_request)); | 938 | memset(&er, 0, sizeof(struct gfs2_ea_request)); |
939 | 939 | ||
940 | er.er_type = GFS2_EATYPE_SECURITY; | 940 | er.er_type = GFS2_EATYPE_SECURITY; |
941 | er.er_name = name; | 941 | er.er_name = name; |
942 | er.er_data = value; | 942 | er.er_data = value; |
943 | er.er_name_len = strlen(name); | 943 | er.er_name_len = strlen(name); |
944 | er.er_data_len = len; | 944 | er.er_data_len = len; |
945 | 945 | ||
946 | err = gfs2_ea_set_i(ip, &er); | 946 | err = gfs2_ea_set_i(ip, &er); |
947 | 947 | ||
948 | kfree(value); | 948 | kfree(value); |
949 | kfree(name); | 949 | kfree(name); |
950 | 950 | ||
951 | return err; | 951 | return err; |
952 | } | 952 | } |
953 | 953 | ||
954 | /** | 954 | /** |
955 | * gfs2_createi - Create a new inode | 955 | * gfs2_createi - Create a new inode |
956 | * @ghs: An array of two holders | 956 | * @ghs: An array of two holders |
957 | * @name: The name of the new file | 957 | * @name: The name of the new file |
958 | * @mode: the permissions on the new inode | 958 | * @mode: the permissions on the new inode |
959 | * | 959 | * |
960 | * @ghs[0] is an initialized holder for the directory | 960 | * @ghs[0] is an initialized holder for the directory |
961 | * @ghs[1] is the holder for the inode lock | 961 | * @ghs[1] is the holder for the inode lock |
962 | * | 962 | * |
963 | * If the return value is not NULL, the glocks on both the directory and the new | 963 | * If the return value is not NULL, the glocks on both the directory and the new |
964 | * file are held. A transaction has been started and an inplace reservation | 964 | * file are held. A transaction has been started and an inplace reservation |
965 | * is held, as well. | 965 | * is held, as well. |
966 | * | 966 | * |
967 | * Returns: An inode | 967 | * Returns: An inode |
968 | */ | 968 | */ |
969 | 969 | ||
970 | struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, | 970 | struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, |
971 | unsigned int mode, dev_t dev) | 971 | unsigned int mode, dev_t dev) |
972 | { | 972 | { |
973 | struct inode *inode = NULL; | 973 | struct inode *inode = NULL; |
974 | struct gfs2_inode *dip = ghs->gh_gl->gl_object; | 974 | struct gfs2_inode *dip = ghs->gh_gl->gl_object; |
975 | struct inode *dir = &dip->i_inode; | 975 | struct inode *dir = &dip->i_inode; |
976 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 976 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
977 | struct gfs2_inum_host inum = { .no_addr = 0, .no_formal_ino = 0 }; | 977 | struct gfs2_inum_host inum = { .no_addr = 0, .no_formal_ino = 0 }; |
978 | int error; | 978 | int error; |
979 | u64 generation; | 979 | u64 generation; |
980 | struct buffer_head *bh = NULL; | 980 | struct buffer_head *bh = NULL; |
981 | 981 | ||
982 | if (!name->len || name->len > GFS2_FNAMESIZE) | 982 | if (!name->len || name->len > GFS2_FNAMESIZE) |
983 | return ERR_PTR(-ENAMETOOLONG); | 983 | return ERR_PTR(-ENAMETOOLONG); |
984 | 984 | ||
985 | gfs2_holder_reinit(LM_ST_EXCLUSIVE, 0, ghs); | 985 | gfs2_holder_reinit(LM_ST_EXCLUSIVE, 0, ghs); |
986 | error = gfs2_glock_nq(ghs); | 986 | error = gfs2_glock_nq(ghs); |
987 | if (error) | 987 | if (error) |
988 | goto fail; | 988 | goto fail; |
989 | 989 | ||
990 | error = create_ok(dip, name, mode); | 990 | error = create_ok(dip, name, mode); |
991 | if (error) | 991 | if (error) |
992 | goto fail_gunlock; | 992 | goto fail_gunlock; |
993 | 993 | ||
994 | error = pick_formal_ino(sdp, &inum.no_formal_ino); | 994 | error = pick_formal_ino(sdp, &inum.no_formal_ino); |
995 | if (error) | 995 | if (error) |
996 | goto fail_gunlock; | 996 | goto fail_gunlock; |
997 | 997 | ||
998 | error = alloc_dinode(dip, &inum.no_addr, &generation); | 998 | error = alloc_dinode(dip, &inum.no_addr, &generation); |
999 | if (error) | 999 | if (error) |
1000 | goto fail_gunlock; | 1000 | goto fail_gunlock; |
1001 | 1001 | ||
1002 | error = gfs2_glock_nq_num(sdp, inum.no_addr, &gfs2_inode_glops, | 1002 | error = gfs2_glock_nq_num(sdp, inum.no_addr, &gfs2_inode_glops, |
1003 | LM_ST_EXCLUSIVE, GL_SKIP, ghs + 1); | 1003 | LM_ST_EXCLUSIVE, GL_SKIP, ghs + 1); |
1004 | if (error) | 1004 | if (error) |
1005 | goto fail_gunlock; | 1005 | goto fail_gunlock; |
1006 | 1006 | ||
1007 | error = make_dinode(dip, ghs[1].gh_gl, mode, &inum, &generation, dev, &bh); | 1007 | error = make_dinode(dip, ghs[1].gh_gl, mode, &inum, &generation, dev, &bh); |
1008 | if (error) | 1008 | if (error) |
1009 | goto fail_gunlock2; | 1009 | goto fail_gunlock2; |
1010 | 1010 | ||
1011 | inode = gfs2_inode_lookup(dir->i_sb, IF2DT(mode), | 1011 | inode = gfs2_inode_lookup(dir->i_sb, IF2DT(mode), |
1012 | inum.no_addr, | 1012 | inum.no_addr, |
1013 | inum.no_formal_ino, 0); | 1013 | inum.no_formal_ino, 0); |
1014 | if (IS_ERR(inode)) | 1014 | if (IS_ERR(inode)) |
1015 | goto fail_gunlock2; | 1015 | goto fail_gunlock2; |
1016 | 1016 | ||
1017 | error = gfs2_inode_refresh(GFS2_I(inode)); | 1017 | error = gfs2_inode_refresh(GFS2_I(inode)); |
1018 | if (error) | 1018 | if (error) |
1019 | goto fail_gunlock2; | 1019 | goto fail_gunlock2; |
1020 | 1020 | ||
1021 | error = gfs2_acl_create(dip, GFS2_I(inode)); | 1021 | error = gfs2_acl_create(dip, GFS2_I(inode)); |
1022 | if (error) | 1022 | if (error) |
1023 | goto fail_gunlock2; | 1023 | goto fail_gunlock2; |
1024 | 1024 | ||
1025 | error = gfs2_security_init(dip, GFS2_I(inode)); | 1025 | error = gfs2_security_init(dip, GFS2_I(inode)); |
1026 | if (error) | 1026 | if (error) |
1027 | goto fail_gunlock2; | 1027 | goto fail_gunlock2; |
1028 | 1028 | ||
1029 | error = link_dinode(dip, name, GFS2_I(inode)); | 1029 | error = link_dinode(dip, name, GFS2_I(inode)); |
1030 | if (error) | 1030 | if (error) |
1031 | goto fail_gunlock2; | 1031 | goto fail_gunlock2; |
1032 | 1032 | ||
1033 | if (bh) | 1033 | if (bh) |
1034 | brelse(bh); | 1034 | brelse(bh); |
1035 | return inode; | 1035 | return inode; |
1036 | 1036 | ||
1037 | fail_gunlock2: | 1037 | fail_gunlock2: |
1038 | gfs2_glock_dq_uninit(ghs + 1); | 1038 | gfs2_glock_dq_uninit(ghs + 1); |
1039 | if (inode && !IS_ERR(inode)) | 1039 | if (inode && !IS_ERR(inode)) |
1040 | iput(inode); | 1040 | iput(inode); |
1041 | fail_gunlock: | 1041 | fail_gunlock: |
1042 | gfs2_glock_dq(ghs); | 1042 | gfs2_glock_dq(ghs); |
1043 | fail: | 1043 | fail: |
1044 | if (bh) | 1044 | if (bh) |
1045 | brelse(bh); | 1045 | brelse(bh); |
1046 | return ERR_PTR(error); | 1046 | return ERR_PTR(error); |
1047 | } | 1047 | } |
1048 | 1048 | ||
1049 | |||
1050 | /* | ||
1051 | * gfs2_unlink_ok - check to see that a inode is still in a directory | ||
1052 | * @dip: the directory | ||
1053 | * @name: the name of the file | ||
1054 | * @ip: the inode | ||
1055 | * | ||
1056 | * Assumes that the lock on (at least) @dip is held. | ||
1057 | * | ||
1058 | * Returns: 0 if the parent/child relationship is correct, errno if it isn't | ||
1059 | */ | ||
1060 | |||
1061 | int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, | ||
1062 | const struct gfs2_inode *ip) | ||
1063 | { | ||
1064 | int error; | ||
1065 | |||
1066 | if (IS_IMMUTABLE(&ip->i_inode) || IS_APPEND(&ip->i_inode)) | ||
1067 | return -EPERM; | ||
1068 | |||
1069 | if ((dip->i_inode.i_mode & S_ISVTX) && | ||
1070 | dip->i_inode.i_uid != current_fsuid() && | ||
1071 | ip->i_inode.i_uid != current_fsuid() && !capable(CAP_FOWNER)) | ||
1072 | return -EPERM; | ||
1073 | |||
1074 | if (IS_APPEND(&dip->i_inode)) | ||
1075 | return -EPERM; | ||
1076 | |||
1077 | error = gfs2_permission(&dip->i_inode, MAY_WRITE | MAY_EXEC); | ||
1078 | if (error) | ||
1079 | return error; | ||
1080 | |||
1081 | error = gfs2_dir_check(&dip->i_inode, name, ip); | ||
1082 | if (error) | ||
1083 | return error; | ||
1084 | |||
1085 | return 0; | ||
1086 | } | ||
1087 | |||
1088 | static int __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) | 1049 | static int __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) |
1089 | { | 1050 | { |
1090 | struct buffer_head *dibh; | 1051 | struct buffer_head *dibh; |
1091 | int error; | 1052 | int error; |
1092 | 1053 | ||
1093 | error = gfs2_meta_inode_buffer(ip, &dibh); | 1054 | error = gfs2_meta_inode_buffer(ip, &dibh); |
1094 | if (!error) { | 1055 | if (!error) { |
1095 | error = inode_setattr(&ip->i_inode, attr); | 1056 | error = inode_setattr(&ip->i_inode, attr); |
1096 | gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error); | 1057 | gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error); |
1097 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 1058 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
1098 | gfs2_dinode_out(ip, dibh->b_data); | 1059 | gfs2_dinode_out(ip, dibh->b_data); |
1099 | brelse(dibh); | 1060 | brelse(dibh); |
1100 | } | 1061 | } |
1101 | return error; | 1062 | return error; |
1102 | } | 1063 | } |
1103 | 1064 | ||
1104 | /** | 1065 | /** |
1105 | * gfs2_setattr_simple - | 1066 | * gfs2_setattr_simple - |
1106 | * @ip: | 1067 | * @ip: |
1107 | * @attr: | 1068 | * @attr: |
1108 | * | 1069 | * |
1109 | * Called with a reference on the vnode. | 1070 | * Called with a reference on the vnode. |
1110 | * | 1071 | * |
1111 | * Returns: errno | 1072 | * Returns: errno |
1112 | */ | 1073 | */ |
1113 | 1074 | ||
1114 | int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) | 1075 | int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) |
1115 | { | 1076 | { |
1116 | int error; | 1077 | int error; |
1117 | 1078 | ||
1118 | if (current->journal_info) | 1079 | if (current->journal_info) |
1119 | return __gfs2_setattr_simple(ip, attr); | 1080 | return __gfs2_setattr_simple(ip, attr); |
1120 | 1081 | ||
1121 | error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), RES_DINODE, 0); | 1082 | error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), RES_DINODE, 0); |
1122 | if (error) | 1083 | if (error) |
1123 | return error; | 1084 | return error; |
1124 | 1085 | ||
1125 | error = __gfs2_setattr_simple(ip, attr); | 1086 | error = __gfs2_setattr_simple(ip, attr); |
1126 | gfs2_trans_end(GFS2_SB(&ip->i_inode)); | 1087 | gfs2_trans_end(GFS2_SB(&ip->i_inode)); |
1127 | return error; | 1088 | return error; |
1128 | } | 1089 | } |
1129 | 1090 | ||
1130 | void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf) | 1091 | void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf) |
1131 | { | 1092 | { |
1132 | struct gfs2_dinode *str = buf; | 1093 | struct gfs2_dinode *str = buf; |
1133 | 1094 | ||
1134 | str->di_header.mh_magic = cpu_to_be32(GFS2_MAGIC); | 1095 | str->di_header.mh_magic = cpu_to_be32(GFS2_MAGIC); |
1135 | str->di_header.mh_type = cpu_to_be32(GFS2_METATYPE_DI); | 1096 | str->di_header.mh_type = cpu_to_be32(GFS2_METATYPE_DI); |
1136 | str->di_header.__pad0 = 0; | 1097 | str->di_header.__pad0 = 0; |
1137 | str->di_header.mh_format = cpu_to_be32(GFS2_FORMAT_DI); | 1098 | str->di_header.mh_format = cpu_to_be32(GFS2_FORMAT_DI); |
1138 | str->di_header.__pad1 = 0; | 1099 | str->di_header.__pad1 = 0; |
1139 | str->di_num.no_addr = cpu_to_be64(ip->i_no_addr); | 1100 | str->di_num.no_addr = cpu_to_be64(ip->i_no_addr); |
1140 | str->di_num.no_formal_ino = cpu_to_be64(ip->i_no_formal_ino); | 1101 | str->di_num.no_formal_ino = cpu_to_be64(ip->i_no_formal_ino); |
1141 | str->di_mode = cpu_to_be32(ip->i_inode.i_mode); | 1102 | str->di_mode = cpu_to_be32(ip->i_inode.i_mode); |
1142 | str->di_uid = cpu_to_be32(ip->i_inode.i_uid); | 1103 | str->di_uid = cpu_to_be32(ip->i_inode.i_uid); |
1143 | str->di_gid = cpu_to_be32(ip->i_inode.i_gid); | 1104 | str->di_gid = cpu_to_be32(ip->i_inode.i_gid); |
1144 | str->di_nlink = cpu_to_be32(ip->i_inode.i_nlink); | 1105 | str->di_nlink = cpu_to_be32(ip->i_inode.i_nlink); |
1145 | str->di_size = cpu_to_be64(ip->i_disksize); | 1106 | str->di_size = cpu_to_be64(ip->i_disksize); |
1146 | str->di_blocks = cpu_to_be64(gfs2_get_inode_blocks(&ip->i_inode)); | 1107 | str->di_blocks = cpu_to_be64(gfs2_get_inode_blocks(&ip->i_inode)); |
1147 | str->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec); | 1108 | str->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec); |
1148 | str->di_mtime = cpu_to_be64(ip->i_inode.i_mtime.tv_sec); | 1109 | str->di_mtime = cpu_to_be64(ip->i_inode.i_mtime.tv_sec); |
1149 | str->di_ctime = cpu_to_be64(ip->i_inode.i_ctime.tv_sec); | 1110 | str->di_ctime = cpu_to_be64(ip->i_inode.i_ctime.tv_sec); |
1150 | 1111 | ||
1151 | str->di_goal_meta = cpu_to_be64(ip->i_goal); | 1112 | str->di_goal_meta = cpu_to_be64(ip->i_goal); |
1152 | str->di_goal_data = cpu_to_be64(ip->i_goal); | 1113 | str->di_goal_data = cpu_to_be64(ip->i_goal); |
1153 | str->di_generation = cpu_to_be64(ip->i_generation); | 1114 | str->di_generation = cpu_to_be64(ip->i_generation); |
1154 | 1115 | ||
1155 | str->di_flags = cpu_to_be32(ip->i_diskflags); | 1116 | str->di_flags = cpu_to_be32(ip->i_diskflags); |
1156 | str->di_height = cpu_to_be16(ip->i_height); | 1117 | str->di_height = cpu_to_be16(ip->i_height); |
1157 | str->di_payload_format = cpu_to_be32(S_ISDIR(ip->i_inode.i_mode) && | 1118 | str->di_payload_format = cpu_to_be32(S_ISDIR(ip->i_inode.i_mode) && |
1158 | !(ip->i_diskflags & GFS2_DIF_EXHASH) ? | 1119 | !(ip->i_diskflags & GFS2_DIF_EXHASH) ? |
1159 | GFS2_FORMAT_DE : 0); | 1120 | GFS2_FORMAT_DE : 0); |
1160 | str->di_depth = cpu_to_be16(ip->i_depth); | 1121 | str->di_depth = cpu_to_be16(ip->i_depth); |
1161 | str->di_entries = cpu_to_be32(ip->i_entries); | 1122 | str->di_entries = cpu_to_be32(ip->i_entries); |
1162 | 1123 | ||
1163 | str->di_eattr = cpu_to_be64(ip->i_eattr); | 1124 | str->di_eattr = cpu_to_be64(ip->i_eattr); |
1164 | str->di_atime_nsec = cpu_to_be32(ip->i_inode.i_atime.tv_nsec); | 1125 | str->di_atime_nsec = cpu_to_be32(ip->i_inode.i_atime.tv_nsec); |
1165 | str->di_mtime_nsec = cpu_to_be32(ip->i_inode.i_mtime.tv_nsec); | 1126 | str->di_mtime_nsec = cpu_to_be32(ip->i_inode.i_mtime.tv_nsec); |
1166 | str->di_ctime_nsec = cpu_to_be32(ip->i_inode.i_ctime.tv_nsec); | 1127 | str->di_ctime_nsec = cpu_to_be32(ip->i_inode.i_ctime.tv_nsec); |
1167 | } | 1128 | } |
1168 | 1129 | ||
1169 | void gfs2_dinode_print(const struct gfs2_inode *ip) | 1130 | void gfs2_dinode_print(const struct gfs2_inode *ip) |
1170 | { | 1131 | { |
1171 | printk(KERN_INFO " no_formal_ino = %llu\n", | 1132 | printk(KERN_INFO " no_formal_ino = %llu\n", |
1172 | (unsigned long long)ip->i_no_formal_ino); | 1133 | (unsigned long long)ip->i_no_formal_ino); |
1173 | printk(KERN_INFO " no_addr = %llu\n", | 1134 | printk(KERN_INFO " no_addr = %llu\n", |
1174 | (unsigned long long)ip->i_no_addr); | 1135 | (unsigned long long)ip->i_no_addr); |
1175 | printk(KERN_INFO " i_disksize = %llu\n", | 1136 | printk(KERN_INFO " i_disksize = %llu\n", |
1176 | (unsigned long long)ip->i_disksize); | 1137 | (unsigned long long)ip->i_disksize); |
1177 | printk(KERN_INFO " blocks = %llu\n", | 1138 | printk(KERN_INFO " blocks = %llu\n", |
1178 | (unsigned long long)gfs2_get_inode_blocks(&ip->i_inode)); | 1139 | (unsigned long long)gfs2_get_inode_blocks(&ip->i_inode)); |
1179 | printk(KERN_INFO " i_goal = %llu\n", | 1140 | printk(KERN_INFO " i_goal = %llu\n", |
1180 | (unsigned long long)ip->i_goal); | 1141 | (unsigned long long)ip->i_goal); |
1181 | printk(KERN_INFO " i_diskflags = 0x%.8X\n", ip->i_diskflags); | 1142 | printk(KERN_INFO " i_diskflags = 0x%.8X\n", ip->i_diskflags); |
1182 | printk(KERN_INFO " i_height = %u\n", ip->i_height); | 1143 | printk(KERN_INFO " i_height = %u\n", ip->i_height); |
1183 | printk(KERN_INFO " i_depth = %u\n", ip->i_depth); | 1144 | printk(KERN_INFO " i_depth = %u\n", ip->i_depth); |
1184 | printk(KERN_INFO " i_entries = %u\n", ip->i_entries); | 1145 | printk(KERN_INFO " i_entries = %u\n", ip->i_entries); |
1185 | printk(KERN_INFO " i_eattr = %llu\n", | 1146 | printk(KERN_INFO " i_eattr = %llu\n", |
1186 | (unsigned long long)ip->i_eattr); | 1147 | (unsigned long long)ip->i_eattr); |
1187 | } | 1148 | } |
1188 | 1149 | ||
1189 | 1150 |
fs/gfs2/inode.h
1 | /* | 1 | /* |
2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | 2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
3 | * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. | 3 | * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This copyrighted material is made available to anyone wishing to use, | 5 | * This copyrighted material is made available to anyone wishing to use, |
6 | * modify, copy, or redistribute it subject to the terms and conditions | 6 | * modify, copy, or redistribute it subject to the terms and conditions |
7 | * of the GNU General Public License version 2. | 7 | * of the GNU General Public License version 2. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #ifndef __INODE_DOT_H__ | 10 | #ifndef __INODE_DOT_H__ |
11 | #define __INODE_DOT_H__ | 11 | #define __INODE_DOT_H__ |
12 | 12 | ||
13 | #include <linux/fs.h> | 13 | #include <linux/fs.h> |
14 | #include <linux/buffer_head.h> | 14 | #include <linux/buffer_head.h> |
15 | #include <linux/mm.h> | 15 | #include <linux/mm.h> |
16 | #include "util.h" | 16 | #include "util.h" |
17 | 17 | ||
18 | extern int gfs2_releasepage(struct page *page, gfp_t gfp_mask); | 18 | extern int gfs2_releasepage(struct page *page, gfp_t gfp_mask); |
19 | extern int gfs2_internal_read(struct gfs2_inode *ip, | 19 | extern int gfs2_internal_read(struct gfs2_inode *ip, |
20 | struct file_ra_state *ra_state, | 20 | struct file_ra_state *ra_state, |
21 | char *buf, loff_t *pos, unsigned size); | 21 | char *buf, loff_t *pos, unsigned size); |
22 | extern void gfs2_set_aops(struct inode *inode); | 22 | extern void gfs2_set_aops(struct inode *inode); |
23 | 23 | ||
24 | static inline int gfs2_is_stuffed(const struct gfs2_inode *ip) | 24 | static inline int gfs2_is_stuffed(const struct gfs2_inode *ip) |
25 | { | 25 | { |
26 | return !ip->i_height; | 26 | return !ip->i_height; |
27 | } | 27 | } |
28 | 28 | ||
29 | static inline int gfs2_is_jdata(const struct gfs2_inode *ip) | 29 | static inline int gfs2_is_jdata(const struct gfs2_inode *ip) |
30 | { | 30 | { |
31 | return ip->i_diskflags & GFS2_DIF_JDATA; | 31 | return ip->i_diskflags & GFS2_DIF_JDATA; |
32 | } | 32 | } |
33 | 33 | ||
34 | static inline int gfs2_is_writeback(const struct gfs2_inode *ip) | 34 | static inline int gfs2_is_writeback(const struct gfs2_inode *ip) |
35 | { | 35 | { |
36 | const struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 36 | const struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
37 | return (sdp->sd_args.ar_data == GFS2_DATA_WRITEBACK) && !gfs2_is_jdata(ip); | 37 | return (sdp->sd_args.ar_data == GFS2_DATA_WRITEBACK) && !gfs2_is_jdata(ip); |
38 | } | 38 | } |
39 | 39 | ||
40 | static inline int gfs2_is_ordered(const struct gfs2_inode *ip) | 40 | static inline int gfs2_is_ordered(const struct gfs2_inode *ip) |
41 | { | 41 | { |
42 | const struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 42 | const struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
43 | return (sdp->sd_args.ar_data == GFS2_DATA_ORDERED) && !gfs2_is_jdata(ip); | 43 | return (sdp->sd_args.ar_data == GFS2_DATA_ORDERED) && !gfs2_is_jdata(ip); |
44 | } | 44 | } |
45 | 45 | ||
46 | static inline int gfs2_is_dir(const struct gfs2_inode *ip) | 46 | static inline int gfs2_is_dir(const struct gfs2_inode *ip) |
47 | { | 47 | { |
48 | return S_ISDIR(ip->i_inode.i_mode); | 48 | return S_ISDIR(ip->i_inode.i_mode); |
49 | } | 49 | } |
50 | 50 | ||
51 | static inline void gfs2_set_inode_blocks(struct inode *inode, u64 blocks) | 51 | static inline void gfs2_set_inode_blocks(struct inode *inode, u64 blocks) |
52 | { | 52 | { |
53 | inode->i_blocks = blocks << | 53 | inode->i_blocks = blocks << |
54 | (GFS2_SB(inode)->sd_sb.sb_bsize_shift - GFS2_BASIC_BLOCK_SHIFT); | 54 | (GFS2_SB(inode)->sd_sb.sb_bsize_shift - GFS2_BASIC_BLOCK_SHIFT); |
55 | } | 55 | } |
56 | 56 | ||
57 | static inline u64 gfs2_get_inode_blocks(const struct inode *inode) | 57 | static inline u64 gfs2_get_inode_blocks(const struct inode *inode) |
58 | { | 58 | { |
59 | return inode->i_blocks >> | 59 | return inode->i_blocks >> |
60 | (GFS2_SB(inode)->sd_sb.sb_bsize_shift - GFS2_BASIC_BLOCK_SHIFT); | 60 | (GFS2_SB(inode)->sd_sb.sb_bsize_shift - GFS2_BASIC_BLOCK_SHIFT); |
61 | } | 61 | } |
62 | 62 | ||
63 | static inline void gfs2_add_inode_blocks(struct inode *inode, s64 change) | 63 | static inline void gfs2_add_inode_blocks(struct inode *inode, s64 change) |
64 | { | 64 | { |
65 | gfs2_assert(GFS2_SB(inode), (change >= 0 || inode->i_blocks > -change)); | 65 | gfs2_assert(GFS2_SB(inode), (change >= 0 || inode->i_blocks > -change)); |
66 | change *= (GFS2_SB(inode)->sd_sb.sb_bsize/GFS2_BASIC_BLOCK); | 66 | change *= (GFS2_SB(inode)->sd_sb.sb_bsize/GFS2_BASIC_BLOCK); |
67 | inode->i_blocks += change; | 67 | inode->i_blocks += change; |
68 | } | 68 | } |
69 | 69 | ||
70 | static inline int gfs2_check_inum(const struct gfs2_inode *ip, u64 no_addr, | 70 | static inline int gfs2_check_inum(const struct gfs2_inode *ip, u64 no_addr, |
71 | u64 no_formal_ino) | 71 | u64 no_formal_ino) |
72 | { | 72 | { |
73 | return ip->i_no_addr == no_addr && ip->i_no_formal_ino == no_formal_ino; | 73 | return ip->i_no_addr == no_addr && ip->i_no_formal_ino == no_formal_ino; |
74 | } | 74 | } |
75 | 75 | ||
76 | static inline void gfs2_inum_out(const struct gfs2_inode *ip, | 76 | static inline void gfs2_inum_out(const struct gfs2_inode *ip, |
77 | struct gfs2_dirent *dent) | 77 | struct gfs2_dirent *dent) |
78 | { | 78 | { |
79 | dent->de_inum.no_formal_ino = cpu_to_be64(ip->i_no_formal_ino); | 79 | dent->de_inum.no_formal_ino = cpu_to_be64(ip->i_no_formal_ino); |
80 | dent->de_inum.no_addr = cpu_to_be64(ip->i_no_addr); | 80 | dent->de_inum.no_addr = cpu_to_be64(ip->i_no_addr); |
81 | } | 81 | } |
82 | 82 | ||
83 | 83 | ||
84 | extern void gfs2_set_iop(struct inode *inode); | 84 | extern void gfs2_set_iop(struct inode *inode); |
85 | extern struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned type, | 85 | extern struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned type, |
86 | u64 no_addr, u64 no_formal_ino, | 86 | u64 no_addr, u64 no_formal_ino, |
87 | int skip_freeing); | 87 | int skip_freeing); |
88 | extern struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr); | 88 | extern struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr); |
89 | 89 | ||
90 | extern int gfs2_inode_refresh(struct gfs2_inode *ip); | 90 | extern int gfs2_inode_refresh(struct gfs2_inode *ip); |
91 | 91 | ||
92 | extern int gfs2_dinode_dealloc(struct gfs2_inode *inode); | 92 | extern int gfs2_dinode_dealloc(struct gfs2_inode *inode); |
93 | extern int gfs2_change_nlink(struct gfs2_inode *ip, int diff); | 93 | extern int gfs2_change_nlink(struct gfs2_inode *ip, int diff); |
94 | extern struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, | 94 | extern struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, |
95 | int is_root); | 95 | int is_root); |
96 | extern struct inode *gfs2_createi(struct gfs2_holder *ghs, | 96 | extern struct inode *gfs2_createi(struct gfs2_holder *ghs, |
97 | const struct qstr *name, | 97 | const struct qstr *name, |
98 | unsigned int mode, dev_t dev); | 98 | unsigned int mode, dev_t dev); |
99 | extern int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, | ||
100 | const struct gfs2_inode *ip); | ||
101 | extern int gfs2_permission(struct inode *inode, int mask); | 99 | extern int gfs2_permission(struct inode *inode, int mask); |
102 | extern int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr); | 100 | extern int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr); |
103 | extern struct inode *gfs2_lookup_simple(struct inode *dip, const char *name); | 101 | extern struct inode *gfs2_lookup_simple(struct inode *dip, const char *name); |
104 | extern void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf); | 102 | extern void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf); |
105 | extern void gfs2_dinode_print(const struct gfs2_inode *ip); | 103 | extern void gfs2_dinode_print(const struct gfs2_inode *ip); |
106 | 104 | ||
107 | extern const struct inode_operations gfs2_file_iops; | 105 | extern const struct inode_operations gfs2_file_iops; |
108 | extern const struct inode_operations gfs2_dir_iops; | 106 | extern const struct inode_operations gfs2_dir_iops; |
109 | extern const struct inode_operations gfs2_symlink_iops; | 107 | extern const struct inode_operations gfs2_symlink_iops; |
110 | extern const struct file_operations gfs2_file_fops_nolock; | 108 | extern const struct file_operations gfs2_file_fops_nolock; |
111 | extern const struct file_operations gfs2_dir_fops_nolock; | 109 | extern const struct file_operations gfs2_dir_fops_nolock; |
112 | 110 | ||
113 | extern void gfs2_set_inode_flags(struct inode *inode); | 111 | extern void gfs2_set_inode_flags(struct inode *inode); |
114 | 112 | ||
115 | #ifdef CONFIG_GFS2_FS_LOCKING_DLM | 113 | #ifdef CONFIG_GFS2_FS_LOCKING_DLM |
116 | extern const struct file_operations gfs2_file_fops; | 114 | extern const struct file_operations gfs2_file_fops; |
117 | extern const struct file_operations gfs2_dir_fops; | 115 | extern const struct file_operations gfs2_dir_fops; |
118 | 116 | ||
119 | static inline int gfs2_localflocks(const struct gfs2_sbd *sdp) | 117 | static inline int gfs2_localflocks(const struct gfs2_sbd *sdp) |
120 | { | 118 | { |
121 | return sdp->sd_args.ar_localflocks; | 119 | return sdp->sd_args.ar_localflocks; |
122 | } | 120 | } |
123 | #else /* Single node only */ | 121 | #else /* Single node only */ |
124 | #define gfs2_file_fops gfs2_file_fops_nolock | 122 | #define gfs2_file_fops gfs2_file_fops_nolock |
125 | #define gfs2_dir_fops gfs2_dir_fops_nolock | 123 | #define gfs2_dir_fops gfs2_dir_fops_nolock |
126 | 124 | ||
127 | static inline int gfs2_localflocks(const struct gfs2_sbd *sdp) | 125 | static inline int gfs2_localflocks(const struct gfs2_sbd *sdp) |
128 | { | 126 | { |
129 | return 1; | 127 | return 1; |
130 | } | 128 | } |
131 | #endif /* CONFIG_GFS2_FS_LOCKING_DLM */ | 129 | #endif /* CONFIG_GFS2_FS_LOCKING_DLM */ |
132 | 130 | ||
133 | #endif /* __INODE_DOT_H__ */ | 131 | #endif /* __INODE_DOT_H__ */ |
134 | 132 | ||
135 | 133 |
fs/gfs2/ops_inode.c
1 | /* | 1 | /* |
2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | 2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
3 | * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. | 3 | * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This copyrighted material is made available to anyone wishing to use, | 5 | * This copyrighted material is made available to anyone wishing to use, |
6 | * modify, copy, or redistribute it subject to the terms and conditions | 6 | * modify, copy, or redistribute it subject to the terms and conditions |
7 | * of the GNU General Public License version 2. | 7 | * of the GNU General Public License version 2. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/slab.h> | 10 | #include <linux/slab.h> |
11 | #include <linux/spinlock.h> | 11 | #include <linux/spinlock.h> |
12 | #include <linux/completion.h> | 12 | #include <linux/completion.h> |
13 | #include <linux/buffer_head.h> | 13 | #include <linux/buffer_head.h> |
14 | #include <linux/namei.h> | 14 | #include <linux/namei.h> |
15 | #include <linux/utsname.h> | 15 | #include <linux/utsname.h> |
16 | #include <linux/mm.h> | 16 | #include <linux/mm.h> |
17 | #include <linux/xattr.h> | 17 | #include <linux/xattr.h> |
18 | #include <linux/posix_acl.h> | 18 | #include <linux/posix_acl.h> |
19 | #include <linux/gfs2_ondisk.h> | 19 | #include <linux/gfs2_ondisk.h> |
20 | #include <linux/crc32.h> | 20 | #include <linux/crc32.h> |
21 | #include <linux/fiemap.h> | 21 | #include <linux/fiemap.h> |
22 | #include <asm/uaccess.h> | 22 | #include <asm/uaccess.h> |
23 | 23 | ||
24 | #include "gfs2.h" | 24 | #include "gfs2.h" |
25 | #include "incore.h" | 25 | #include "incore.h" |
26 | #include "acl.h" | 26 | #include "acl.h" |
27 | #include "bmap.h" | 27 | #include "bmap.h" |
28 | #include "dir.h" | 28 | #include "dir.h" |
29 | #include "eaops.h" | 29 | #include "eaops.h" |
30 | #include "eattr.h" | 30 | #include "eattr.h" |
31 | #include "glock.h" | 31 | #include "glock.h" |
32 | #include "inode.h" | 32 | #include "inode.h" |
33 | #include "meta_io.h" | 33 | #include "meta_io.h" |
34 | #include "quota.h" | 34 | #include "quota.h" |
35 | #include "rgrp.h" | 35 | #include "rgrp.h" |
36 | #include "trans.h" | 36 | #include "trans.h" |
37 | #include "util.h" | 37 | #include "util.h" |
38 | #include "super.h" | 38 | #include "super.h" |
39 | 39 | ||
40 | /** | 40 | /** |
41 | * gfs2_create - Create a file | 41 | * gfs2_create - Create a file |
42 | * @dir: The directory in which to create the file | 42 | * @dir: The directory in which to create the file |
43 | * @dentry: The dentry of the new file | 43 | * @dentry: The dentry of the new file |
44 | * @mode: The mode of the new file | 44 | * @mode: The mode of the new file |
45 | * | 45 | * |
46 | * Returns: errno | 46 | * Returns: errno |
47 | */ | 47 | */ |
48 | 48 | ||
49 | static int gfs2_create(struct inode *dir, struct dentry *dentry, | 49 | static int gfs2_create(struct inode *dir, struct dentry *dentry, |
50 | int mode, struct nameidata *nd) | 50 | int mode, struct nameidata *nd) |
51 | { | 51 | { |
52 | struct gfs2_inode *dip = GFS2_I(dir); | 52 | struct gfs2_inode *dip = GFS2_I(dir); |
53 | struct gfs2_sbd *sdp = GFS2_SB(dir); | 53 | struct gfs2_sbd *sdp = GFS2_SB(dir); |
54 | struct gfs2_holder ghs[2]; | 54 | struct gfs2_holder ghs[2]; |
55 | struct inode *inode; | 55 | struct inode *inode; |
56 | 56 | ||
57 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); | 57 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); |
58 | 58 | ||
59 | for (;;) { | 59 | for (;;) { |
60 | inode = gfs2_createi(ghs, &dentry->d_name, S_IFREG | mode, 0); | 60 | inode = gfs2_createi(ghs, &dentry->d_name, S_IFREG | mode, 0); |
61 | if (!IS_ERR(inode)) { | 61 | if (!IS_ERR(inode)) { |
62 | gfs2_trans_end(sdp); | 62 | gfs2_trans_end(sdp); |
63 | if (dip->i_alloc->al_rgd) | 63 | if (dip->i_alloc->al_rgd) |
64 | gfs2_inplace_release(dip); | 64 | gfs2_inplace_release(dip); |
65 | gfs2_quota_unlock(dip); | 65 | gfs2_quota_unlock(dip); |
66 | gfs2_alloc_put(dip); | 66 | gfs2_alloc_put(dip); |
67 | gfs2_glock_dq_uninit_m(2, ghs); | 67 | gfs2_glock_dq_uninit_m(2, ghs); |
68 | mark_inode_dirty(inode); | 68 | mark_inode_dirty(inode); |
69 | break; | 69 | break; |
70 | } else if (PTR_ERR(inode) != -EEXIST || | 70 | } else if (PTR_ERR(inode) != -EEXIST || |
71 | (nd && nd->flags & LOOKUP_EXCL)) { | 71 | (nd && nd->flags & LOOKUP_EXCL)) { |
72 | gfs2_holder_uninit(ghs); | 72 | gfs2_holder_uninit(ghs); |
73 | return PTR_ERR(inode); | 73 | return PTR_ERR(inode); |
74 | } | 74 | } |
75 | 75 | ||
76 | inode = gfs2_lookupi(dir, &dentry->d_name, 0); | 76 | inode = gfs2_lookupi(dir, &dentry->d_name, 0); |
77 | if (inode) { | 77 | if (inode) { |
78 | if (!IS_ERR(inode)) { | 78 | if (!IS_ERR(inode)) { |
79 | gfs2_holder_uninit(ghs); | 79 | gfs2_holder_uninit(ghs); |
80 | break; | 80 | break; |
81 | } else { | 81 | } else { |
82 | gfs2_holder_uninit(ghs); | 82 | gfs2_holder_uninit(ghs); |
83 | return PTR_ERR(inode); | 83 | return PTR_ERR(inode); |
84 | } | 84 | } |
85 | } | 85 | } |
86 | } | 86 | } |
87 | 87 | ||
88 | d_instantiate(dentry, inode); | 88 | d_instantiate(dentry, inode); |
89 | 89 | ||
90 | return 0; | 90 | return 0; |
91 | } | 91 | } |
92 | 92 | ||
93 | /** | 93 | /** |
94 | * gfs2_lookup - Look up a filename in a directory and return its inode | 94 | * gfs2_lookup - Look up a filename in a directory and return its inode |
95 | * @dir: The directory inode | 95 | * @dir: The directory inode |
96 | * @dentry: The dentry of the new inode | 96 | * @dentry: The dentry of the new inode |
97 | * @nd: passed from Linux VFS, ignored by us | 97 | * @nd: passed from Linux VFS, ignored by us |
98 | * | 98 | * |
99 | * Called by the VFS layer. Lock dir and call gfs2_lookupi() | 99 | * Called by the VFS layer. Lock dir and call gfs2_lookupi() |
100 | * | 100 | * |
101 | * Returns: errno | 101 | * Returns: errno |
102 | */ | 102 | */ |
103 | 103 | ||
104 | static struct dentry *gfs2_lookup(struct inode *dir, struct dentry *dentry, | 104 | static struct dentry *gfs2_lookup(struct inode *dir, struct dentry *dentry, |
105 | struct nameidata *nd) | 105 | struct nameidata *nd) |
106 | { | 106 | { |
107 | struct inode *inode = NULL; | 107 | struct inode *inode = NULL; |
108 | 108 | ||
109 | dentry->d_op = &gfs2_dops; | 109 | dentry->d_op = &gfs2_dops; |
110 | 110 | ||
111 | inode = gfs2_lookupi(dir, &dentry->d_name, 0); | 111 | inode = gfs2_lookupi(dir, &dentry->d_name, 0); |
112 | if (inode && IS_ERR(inode)) | 112 | if (inode && IS_ERR(inode)) |
113 | return ERR_CAST(inode); | 113 | return ERR_CAST(inode); |
114 | 114 | ||
115 | if (inode) { | 115 | if (inode) { |
116 | struct gfs2_glock *gl = GFS2_I(inode)->i_gl; | 116 | struct gfs2_glock *gl = GFS2_I(inode)->i_gl; |
117 | struct gfs2_holder gh; | 117 | struct gfs2_holder gh; |
118 | int error; | 118 | int error; |
119 | error = gfs2_glock_nq_init(gl, LM_ST_SHARED, LM_FLAG_ANY, &gh); | 119 | error = gfs2_glock_nq_init(gl, LM_ST_SHARED, LM_FLAG_ANY, &gh); |
120 | if (error) { | 120 | if (error) { |
121 | iput(inode); | 121 | iput(inode); |
122 | return ERR_PTR(error); | 122 | return ERR_PTR(error); |
123 | } | 123 | } |
124 | gfs2_glock_dq_uninit(&gh); | 124 | gfs2_glock_dq_uninit(&gh); |
125 | return d_splice_alias(inode, dentry); | 125 | return d_splice_alias(inode, dentry); |
126 | } | 126 | } |
127 | d_add(dentry, inode); | 127 | d_add(dentry, inode); |
128 | 128 | ||
129 | return NULL; | 129 | return NULL; |
130 | } | 130 | } |
131 | 131 | ||
132 | /** | 132 | /** |
133 | * gfs2_link - Link to a file | 133 | * gfs2_link - Link to a file |
134 | * @old_dentry: The inode to link | 134 | * @old_dentry: The inode to link |
135 | * @dir: Add link to this directory | 135 | * @dir: Add link to this directory |
136 | * @dentry: The name of the link | 136 | * @dentry: The name of the link |
137 | * | 137 | * |
138 | * Link the inode in "old_dentry" into the directory "dir" with the | 138 | * Link the inode in "old_dentry" into the directory "dir" with the |
139 | * name in "dentry". | 139 | * name in "dentry". |
140 | * | 140 | * |
141 | * Returns: errno | 141 | * Returns: errno |
142 | */ | 142 | */ |
143 | 143 | ||
144 | static int gfs2_link(struct dentry *old_dentry, struct inode *dir, | 144 | static int gfs2_link(struct dentry *old_dentry, struct inode *dir, |
145 | struct dentry *dentry) | 145 | struct dentry *dentry) |
146 | { | 146 | { |
147 | struct gfs2_inode *dip = GFS2_I(dir); | 147 | struct gfs2_inode *dip = GFS2_I(dir); |
148 | struct gfs2_sbd *sdp = GFS2_SB(dir); | 148 | struct gfs2_sbd *sdp = GFS2_SB(dir); |
149 | struct inode *inode = old_dentry->d_inode; | 149 | struct inode *inode = old_dentry->d_inode; |
150 | struct gfs2_inode *ip = GFS2_I(inode); | 150 | struct gfs2_inode *ip = GFS2_I(inode); |
151 | struct gfs2_holder ghs[2]; | 151 | struct gfs2_holder ghs[2]; |
152 | int alloc_required; | 152 | int alloc_required; |
153 | int error; | 153 | int error; |
154 | 154 | ||
155 | if (S_ISDIR(inode->i_mode)) | 155 | if (S_ISDIR(inode->i_mode)) |
156 | return -EPERM; | 156 | return -EPERM; |
157 | 157 | ||
158 | gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); | 158 | gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); |
159 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1); | 159 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1); |
160 | 160 | ||
161 | error = gfs2_glock_nq(ghs); /* parent */ | 161 | error = gfs2_glock_nq(ghs); /* parent */ |
162 | if (error) | 162 | if (error) |
163 | goto out_parent; | 163 | goto out_parent; |
164 | 164 | ||
165 | error = gfs2_glock_nq(ghs + 1); /* child */ | 165 | error = gfs2_glock_nq(ghs + 1); /* child */ |
166 | if (error) | 166 | if (error) |
167 | goto out_child; | 167 | goto out_child; |
168 | 168 | ||
169 | error = gfs2_permission(dir, MAY_WRITE | MAY_EXEC); | 169 | error = gfs2_permission(dir, MAY_WRITE | MAY_EXEC); |
170 | if (error) | 170 | if (error) |
171 | goto out_gunlock; | 171 | goto out_gunlock; |
172 | 172 | ||
173 | error = gfs2_dir_check(dir, &dentry->d_name, NULL); | 173 | error = gfs2_dir_check(dir, &dentry->d_name, NULL); |
174 | switch (error) { | 174 | switch (error) { |
175 | case -ENOENT: | 175 | case -ENOENT: |
176 | break; | 176 | break; |
177 | case 0: | 177 | case 0: |
178 | error = -EEXIST; | 178 | error = -EEXIST; |
179 | default: | 179 | default: |
180 | goto out_gunlock; | 180 | goto out_gunlock; |
181 | } | 181 | } |
182 | 182 | ||
183 | error = -EINVAL; | 183 | error = -EINVAL; |
184 | if (!dip->i_inode.i_nlink) | 184 | if (!dip->i_inode.i_nlink) |
185 | goto out_gunlock; | 185 | goto out_gunlock; |
186 | error = -EFBIG; | 186 | error = -EFBIG; |
187 | if (dip->i_entries == (u32)-1) | 187 | if (dip->i_entries == (u32)-1) |
188 | goto out_gunlock; | 188 | goto out_gunlock; |
189 | error = -EPERM; | 189 | error = -EPERM; |
190 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) | 190 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) |
191 | goto out_gunlock; | 191 | goto out_gunlock; |
192 | error = -EINVAL; | 192 | error = -EINVAL; |
193 | if (!ip->i_inode.i_nlink) | 193 | if (!ip->i_inode.i_nlink) |
194 | goto out_gunlock; | 194 | goto out_gunlock; |
195 | error = -EMLINK; | 195 | error = -EMLINK; |
196 | if (ip->i_inode.i_nlink == (u32)-1) | 196 | if (ip->i_inode.i_nlink == (u32)-1) |
197 | goto out_gunlock; | 197 | goto out_gunlock; |
198 | 198 | ||
199 | alloc_required = error = gfs2_diradd_alloc_required(dir, &dentry->d_name); | 199 | alloc_required = error = gfs2_diradd_alloc_required(dir, &dentry->d_name); |
200 | if (error < 0) | 200 | if (error < 0) |
201 | goto out_gunlock; | 201 | goto out_gunlock; |
202 | error = 0; | 202 | error = 0; |
203 | 203 | ||
204 | if (alloc_required) { | 204 | if (alloc_required) { |
205 | struct gfs2_alloc *al = gfs2_alloc_get(dip); | 205 | struct gfs2_alloc *al = gfs2_alloc_get(dip); |
206 | if (!al) { | 206 | if (!al) { |
207 | error = -ENOMEM; | 207 | error = -ENOMEM; |
208 | goto out_gunlock; | 208 | goto out_gunlock; |
209 | } | 209 | } |
210 | 210 | ||
211 | error = gfs2_quota_lock_check(dip); | 211 | error = gfs2_quota_lock_check(dip); |
212 | if (error) | 212 | if (error) |
213 | goto out_alloc; | 213 | goto out_alloc; |
214 | 214 | ||
215 | al->al_requested = sdp->sd_max_dirres; | 215 | al->al_requested = sdp->sd_max_dirres; |
216 | 216 | ||
217 | error = gfs2_inplace_reserve(dip); | 217 | error = gfs2_inplace_reserve(dip); |
218 | if (error) | 218 | if (error) |
219 | goto out_gunlock_q; | 219 | goto out_gunlock_q; |
220 | 220 | ||
221 | error = gfs2_trans_begin(sdp, sdp->sd_max_dirres + | 221 | error = gfs2_trans_begin(sdp, sdp->sd_max_dirres + |
222 | al->al_rgd->rd_length + | 222 | al->al_rgd->rd_length + |
223 | 2 * RES_DINODE + RES_STATFS + | 223 | 2 * RES_DINODE + RES_STATFS + |
224 | RES_QUOTA, 0); | 224 | RES_QUOTA, 0); |
225 | if (error) | 225 | if (error) |
226 | goto out_ipres; | 226 | goto out_ipres; |
227 | } else { | 227 | } else { |
228 | error = gfs2_trans_begin(sdp, 2 * RES_DINODE + RES_LEAF, 0); | 228 | error = gfs2_trans_begin(sdp, 2 * RES_DINODE + RES_LEAF, 0); |
229 | if (error) | 229 | if (error) |
230 | goto out_ipres; | 230 | goto out_ipres; |
231 | } | 231 | } |
232 | 232 | ||
233 | error = gfs2_dir_add(dir, &dentry->d_name, ip, IF2DT(inode->i_mode)); | 233 | error = gfs2_dir_add(dir, &dentry->d_name, ip, IF2DT(inode->i_mode)); |
234 | if (error) | 234 | if (error) |
235 | goto out_end_trans; | 235 | goto out_end_trans; |
236 | 236 | ||
237 | error = gfs2_change_nlink(ip, +1); | 237 | error = gfs2_change_nlink(ip, +1); |
238 | 238 | ||
239 | out_end_trans: | 239 | out_end_trans: |
240 | gfs2_trans_end(sdp); | 240 | gfs2_trans_end(sdp); |
241 | out_ipres: | 241 | out_ipres: |
242 | if (alloc_required) | 242 | if (alloc_required) |
243 | gfs2_inplace_release(dip); | 243 | gfs2_inplace_release(dip); |
244 | out_gunlock_q: | 244 | out_gunlock_q: |
245 | if (alloc_required) | 245 | if (alloc_required) |
246 | gfs2_quota_unlock(dip); | 246 | gfs2_quota_unlock(dip); |
247 | out_alloc: | 247 | out_alloc: |
248 | if (alloc_required) | 248 | if (alloc_required) |
249 | gfs2_alloc_put(dip); | 249 | gfs2_alloc_put(dip); |
250 | out_gunlock: | 250 | out_gunlock: |
251 | gfs2_glock_dq(ghs + 1); | 251 | gfs2_glock_dq(ghs + 1); |
252 | out_child: | 252 | out_child: |
253 | gfs2_glock_dq(ghs); | 253 | gfs2_glock_dq(ghs); |
254 | out_parent: | 254 | out_parent: |
255 | gfs2_holder_uninit(ghs); | 255 | gfs2_holder_uninit(ghs); |
256 | gfs2_holder_uninit(ghs + 1); | 256 | gfs2_holder_uninit(ghs + 1); |
257 | if (!error) { | 257 | if (!error) { |
258 | atomic_inc(&inode->i_count); | 258 | atomic_inc(&inode->i_count); |
259 | d_instantiate(dentry, inode); | 259 | d_instantiate(dentry, inode); |
260 | mark_inode_dirty(inode); | 260 | mark_inode_dirty(inode); |
261 | } | 261 | } |
262 | return error; | 262 | return error; |
263 | } | 263 | } |
264 | 264 | ||
265 | /* | ||
266 | * gfs2_unlink_ok - check to see that a inode is still in a directory | ||
267 | * @dip: the directory | ||
268 | * @name: the name of the file | ||
269 | * @ip: the inode | ||
270 | * | ||
271 | * Assumes that the lock on (at least) @dip is held. | ||
272 | * | ||
273 | * Returns: 0 if the parent/child relationship is correct, errno if it isn't | ||
274 | */ | ||
275 | |||
276 | static int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, | ||
277 | const struct gfs2_inode *ip) | ||
278 | { | ||
279 | int error; | ||
280 | |||
281 | if (IS_IMMUTABLE(&ip->i_inode) || IS_APPEND(&ip->i_inode)) | ||
282 | return -EPERM; | ||
283 | |||
284 | if ((dip->i_inode.i_mode & S_ISVTX) && | ||
285 | dip->i_inode.i_uid != current_fsuid() && | ||
286 | ip->i_inode.i_uid != current_fsuid() && !capable(CAP_FOWNER)) | ||
287 | return -EPERM; | ||
288 | |||
289 | if (IS_APPEND(&dip->i_inode)) | ||
290 | return -EPERM; | ||
291 | |||
292 | error = gfs2_permission(&dip->i_inode, MAY_WRITE | MAY_EXEC); | ||
293 | if (error) | ||
294 | return error; | ||
295 | |||
296 | error = gfs2_dir_check(&dip->i_inode, name, ip); | ||
297 | if (error) | ||
298 | return error; | ||
299 | |||
300 | return 0; | ||
301 | } | ||
302 | |||
265 | /** | 303 | /** |
266 | * gfs2_unlink - Unlink a file | 304 | * gfs2_unlink - Unlink a file |
267 | * @dir: The inode of the directory containing the file to unlink | 305 | * @dir: The inode of the directory containing the file to unlink |
268 | * @dentry: The file itself | 306 | * @dentry: The file itself |
269 | * | 307 | * |
270 | * Unlink a file. Call gfs2_unlinki() | 308 | * Unlink a file. Call gfs2_unlinki() |
271 | * | 309 | * |
272 | * Returns: errno | 310 | * Returns: errno |
273 | */ | 311 | */ |
274 | 312 | ||
275 | static int gfs2_unlink(struct inode *dir, struct dentry *dentry) | 313 | static int gfs2_unlink(struct inode *dir, struct dentry *dentry) |
276 | { | 314 | { |
277 | struct gfs2_inode *dip = GFS2_I(dir); | 315 | struct gfs2_inode *dip = GFS2_I(dir); |
278 | struct gfs2_sbd *sdp = GFS2_SB(dir); | 316 | struct gfs2_sbd *sdp = GFS2_SB(dir); |
279 | struct gfs2_inode *ip = GFS2_I(dentry->d_inode); | 317 | struct gfs2_inode *ip = GFS2_I(dentry->d_inode); |
280 | struct gfs2_holder ghs[3]; | 318 | struct gfs2_holder ghs[3]; |
281 | struct gfs2_rgrpd *rgd; | 319 | struct gfs2_rgrpd *rgd; |
282 | struct gfs2_holder ri_gh; | 320 | struct gfs2_holder ri_gh; |
283 | int error; | 321 | int error; |
284 | 322 | ||
285 | error = gfs2_rindex_hold(sdp, &ri_gh); | 323 | error = gfs2_rindex_hold(sdp, &ri_gh); |
286 | if (error) | 324 | if (error) |
287 | return error; | 325 | return error; |
288 | 326 | ||
289 | gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); | 327 | gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); |
290 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1); | 328 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1); |
291 | 329 | ||
292 | rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr); | 330 | rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr); |
293 | gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2); | 331 | gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2); |
294 | 332 | ||
295 | 333 | ||
296 | error = gfs2_glock_nq(ghs); /* parent */ | 334 | error = gfs2_glock_nq(ghs); /* parent */ |
297 | if (error) | 335 | if (error) |
298 | goto out_parent; | 336 | goto out_parent; |
299 | 337 | ||
300 | error = gfs2_glock_nq(ghs + 1); /* child */ | 338 | error = gfs2_glock_nq(ghs + 1); /* child */ |
301 | if (error) | 339 | if (error) |
302 | goto out_child; | 340 | goto out_child; |
303 | 341 | ||
304 | error = gfs2_glock_nq(ghs + 2); /* rgrp */ | 342 | error = gfs2_glock_nq(ghs + 2); /* rgrp */ |
305 | if (error) | 343 | if (error) |
306 | goto out_rgrp; | 344 | goto out_rgrp; |
307 | 345 | ||
308 | error = gfs2_unlink_ok(dip, &dentry->d_name, ip); | 346 | error = gfs2_unlink_ok(dip, &dentry->d_name, ip); |
309 | if (error) | 347 | if (error) |
310 | goto out_gunlock; | 348 | goto out_gunlock; |
311 | 349 | ||
312 | error = gfs2_trans_begin(sdp, 2*RES_DINODE + RES_LEAF + RES_RG_BIT, 0); | 350 | error = gfs2_trans_begin(sdp, 2*RES_DINODE + RES_LEAF + RES_RG_BIT, 0); |
313 | if (error) | 351 | if (error) |
314 | goto out_rgrp; | 352 | goto out_rgrp; |
315 | 353 | ||
316 | error = gfs2_dir_del(dip, &dentry->d_name); | 354 | error = gfs2_dir_del(dip, &dentry->d_name); |
317 | if (error) | 355 | if (error) |
318 | goto out_end_trans; | 356 | goto out_end_trans; |
319 | 357 | ||
320 | error = gfs2_change_nlink(ip, -1); | 358 | error = gfs2_change_nlink(ip, -1); |
321 | 359 | ||
322 | out_end_trans: | 360 | out_end_trans: |
323 | gfs2_trans_end(sdp); | 361 | gfs2_trans_end(sdp); |
324 | out_gunlock: | 362 | out_gunlock: |
325 | gfs2_glock_dq(ghs + 2); | 363 | gfs2_glock_dq(ghs + 2); |
326 | out_rgrp: | 364 | out_rgrp: |
327 | gfs2_holder_uninit(ghs + 2); | 365 | gfs2_holder_uninit(ghs + 2); |
328 | gfs2_glock_dq(ghs + 1); | 366 | gfs2_glock_dq(ghs + 1); |
329 | out_child: | 367 | out_child: |
330 | gfs2_holder_uninit(ghs + 1); | 368 | gfs2_holder_uninit(ghs + 1); |
331 | gfs2_glock_dq(ghs); | 369 | gfs2_glock_dq(ghs); |
332 | out_parent: | 370 | out_parent: |
333 | gfs2_holder_uninit(ghs); | 371 | gfs2_holder_uninit(ghs); |
334 | gfs2_glock_dq_uninit(&ri_gh); | 372 | gfs2_glock_dq_uninit(&ri_gh); |
335 | return error; | 373 | return error; |
336 | } | 374 | } |
337 | 375 | ||
338 | /** | 376 | /** |
339 | * gfs2_symlink - Create a symlink | 377 | * gfs2_symlink - Create a symlink |
340 | * @dir: The directory to create the symlink in | 378 | * @dir: The directory to create the symlink in |
341 | * @dentry: The dentry to put the symlink in | 379 | * @dentry: The dentry to put the symlink in |
342 | * @symname: The thing which the link points to | 380 | * @symname: The thing which the link points to |
343 | * | 381 | * |
344 | * Returns: errno | 382 | * Returns: errno |
345 | */ | 383 | */ |
346 | 384 | ||
347 | static int gfs2_symlink(struct inode *dir, struct dentry *dentry, | 385 | static int gfs2_symlink(struct inode *dir, struct dentry *dentry, |
348 | const char *symname) | 386 | const char *symname) |
349 | { | 387 | { |
350 | struct gfs2_inode *dip = GFS2_I(dir), *ip; | 388 | struct gfs2_inode *dip = GFS2_I(dir), *ip; |
351 | struct gfs2_sbd *sdp = GFS2_SB(dir); | 389 | struct gfs2_sbd *sdp = GFS2_SB(dir); |
352 | struct gfs2_holder ghs[2]; | 390 | struct gfs2_holder ghs[2]; |
353 | struct inode *inode; | 391 | struct inode *inode; |
354 | struct buffer_head *dibh; | 392 | struct buffer_head *dibh; |
355 | int size; | 393 | int size; |
356 | int error; | 394 | int error; |
357 | 395 | ||
358 | /* Must be stuffed with a null terminator for gfs2_follow_link() */ | 396 | /* Must be stuffed with a null terminator for gfs2_follow_link() */ |
359 | size = strlen(symname); | 397 | size = strlen(symname); |
360 | if (size > sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode) - 1) | 398 | if (size > sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode) - 1) |
361 | return -ENAMETOOLONG; | 399 | return -ENAMETOOLONG; |
362 | 400 | ||
363 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); | 401 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); |
364 | 402 | ||
365 | inode = gfs2_createi(ghs, &dentry->d_name, S_IFLNK | S_IRWXUGO, 0); | 403 | inode = gfs2_createi(ghs, &dentry->d_name, S_IFLNK | S_IRWXUGO, 0); |
366 | if (IS_ERR(inode)) { | 404 | if (IS_ERR(inode)) { |
367 | gfs2_holder_uninit(ghs); | 405 | gfs2_holder_uninit(ghs); |
368 | return PTR_ERR(inode); | 406 | return PTR_ERR(inode); |
369 | } | 407 | } |
370 | 408 | ||
371 | ip = ghs[1].gh_gl->gl_object; | 409 | ip = ghs[1].gh_gl->gl_object; |
372 | 410 | ||
373 | ip->i_disksize = size; | 411 | ip->i_disksize = size; |
374 | i_size_write(inode, size); | 412 | i_size_write(inode, size); |
375 | 413 | ||
376 | error = gfs2_meta_inode_buffer(ip, &dibh); | 414 | error = gfs2_meta_inode_buffer(ip, &dibh); |
377 | 415 | ||
378 | if (!gfs2_assert_withdraw(sdp, !error)) { | 416 | if (!gfs2_assert_withdraw(sdp, !error)) { |
379 | gfs2_dinode_out(ip, dibh->b_data); | 417 | gfs2_dinode_out(ip, dibh->b_data); |
380 | memcpy(dibh->b_data + sizeof(struct gfs2_dinode), symname, | 418 | memcpy(dibh->b_data + sizeof(struct gfs2_dinode), symname, |
381 | size); | 419 | size); |
382 | brelse(dibh); | 420 | brelse(dibh); |
383 | } | 421 | } |
384 | 422 | ||
385 | gfs2_trans_end(sdp); | 423 | gfs2_trans_end(sdp); |
386 | if (dip->i_alloc->al_rgd) | 424 | if (dip->i_alloc->al_rgd) |
387 | gfs2_inplace_release(dip); | 425 | gfs2_inplace_release(dip); |
388 | gfs2_quota_unlock(dip); | 426 | gfs2_quota_unlock(dip); |
389 | gfs2_alloc_put(dip); | 427 | gfs2_alloc_put(dip); |
390 | 428 | ||
391 | gfs2_glock_dq_uninit_m(2, ghs); | 429 | gfs2_glock_dq_uninit_m(2, ghs); |
392 | 430 | ||
393 | d_instantiate(dentry, inode); | 431 | d_instantiate(dentry, inode); |
394 | mark_inode_dirty(inode); | 432 | mark_inode_dirty(inode); |
395 | 433 | ||
396 | return 0; | 434 | return 0; |
397 | } | 435 | } |
398 | 436 | ||
399 | /** | 437 | /** |
400 | * gfs2_mkdir - Make a directory | 438 | * gfs2_mkdir - Make a directory |
401 | * @dir: The parent directory of the new one | 439 | * @dir: The parent directory of the new one |
402 | * @dentry: The dentry of the new directory | 440 | * @dentry: The dentry of the new directory |
403 | * @mode: The mode of the new directory | 441 | * @mode: The mode of the new directory |
404 | * | 442 | * |
405 | * Returns: errno | 443 | * Returns: errno |
406 | */ | 444 | */ |
407 | 445 | ||
408 | static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode) | 446 | static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode) |
409 | { | 447 | { |
410 | struct gfs2_inode *dip = GFS2_I(dir), *ip; | 448 | struct gfs2_inode *dip = GFS2_I(dir), *ip; |
411 | struct gfs2_sbd *sdp = GFS2_SB(dir); | 449 | struct gfs2_sbd *sdp = GFS2_SB(dir); |
412 | struct gfs2_holder ghs[2]; | 450 | struct gfs2_holder ghs[2]; |
413 | struct inode *inode; | 451 | struct inode *inode; |
414 | struct buffer_head *dibh; | 452 | struct buffer_head *dibh; |
415 | int error; | 453 | int error; |
416 | 454 | ||
417 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); | 455 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); |
418 | 456 | ||
419 | inode = gfs2_createi(ghs, &dentry->d_name, S_IFDIR | mode, 0); | 457 | inode = gfs2_createi(ghs, &dentry->d_name, S_IFDIR | mode, 0); |
420 | if (IS_ERR(inode)) { | 458 | if (IS_ERR(inode)) { |
421 | gfs2_holder_uninit(ghs); | 459 | gfs2_holder_uninit(ghs); |
422 | return PTR_ERR(inode); | 460 | return PTR_ERR(inode); |
423 | } | 461 | } |
424 | 462 | ||
425 | ip = ghs[1].gh_gl->gl_object; | 463 | ip = ghs[1].gh_gl->gl_object; |
426 | 464 | ||
427 | ip->i_inode.i_nlink = 2; | 465 | ip->i_inode.i_nlink = 2; |
428 | ip->i_disksize = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode); | 466 | ip->i_disksize = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode); |
429 | ip->i_diskflags |= GFS2_DIF_JDATA; | 467 | ip->i_diskflags |= GFS2_DIF_JDATA; |
430 | ip->i_entries = 2; | 468 | ip->i_entries = 2; |
431 | 469 | ||
432 | error = gfs2_meta_inode_buffer(ip, &dibh); | 470 | error = gfs2_meta_inode_buffer(ip, &dibh); |
433 | 471 | ||
434 | if (!gfs2_assert_withdraw(sdp, !error)) { | 472 | if (!gfs2_assert_withdraw(sdp, !error)) { |
435 | struct gfs2_dinode *di = (struct gfs2_dinode *)dibh->b_data; | 473 | struct gfs2_dinode *di = (struct gfs2_dinode *)dibh->b_data; |
436 | struct gfs2_dirent *dent = (struct gfs2_dirent *)(di+1); | 474 | struct gfs2_dirent *dent = (struct gfs2_dirent *)(di+1); |
437 | struct qstr str; | 475 | struct qstr str; |
438 | 476 | ||
439 | gfs2_str2qstr(&str, "."); | 477 | gfs2_str2qstr(&str, "."); |
440 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 478 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
441 | gfs2_qstr2dirent(&str, GFS2_DIRENT_SIZE(str.len), dent); | 479 | gfs2_qstr2dirent(&str, GFS2_DIRENT_SIZE(str.len), dent); |
442 | dent->de_inum = di->di_num; /* already GFS2 endian */ | 480 | dent->de_inum = di->di_num; /* already GFS2 endian */ |
443 | dent->de_type = cpu_to_be16(DT_DIR); | 481 | dent->de_type = cpu_to_be16(DT_DIR); |
444 | di->di_entries = cpu_to_be32(1); | 482 | di->di_entries = cpu_to_be32(1); |
445 | 483 | ||
446 | gfs2_str2qstr(&str, ".."); | 484 | gfs2_str2qstr(&str, ".."); |
447 | dent = (struct gfs2_dirent *)((char*)dent + GFS2_DIRENT_SIZE(1)); | 485 | dent = (struct gfs2_dirent *)((char*)dent + GFS2_DIRENT_SIZE(1)); |
448 | gfs2_qstr2dirent(&str, dibh->b_size - GFS2_DIRENT_SIZE(1) - sizeof(struct gfs2_dinode), dent); | 486 | gfs2_qstr2dirent(&str, dibh->b_size - GFS2_DIRENT_SIZE(1) - sizeof(struct gfs2_dinode), dent); |
449 | 487 | ||
450 | gfs2_inum_out(dip, dent); | 488 | gfs2_inum_out(dip, dent); |
451 | dent->de_type = cpu_to_be16(DT_DIR); | 489 | dent->de_type = cpu_to_be16(DT_DIR); |
452 | 490 | ||
453 | gfs2_dinode_out(ip, di); | 491 | gfs2_dinode_out(ip, di); |
454 | 492 | ||
455 | brelse(dibh); | 493 | brelse(dibh); |
456 | } | 494 | } |
457 | 495 | ||
458 | error = gfs2_change_nlink(dip, +1); | 496 | error = gfs2_change_nlink(dip, +1); |
459 | gfs2_assert_withdraw(sdp, !error); /* dip already pinned */ | 497 | gfs2_assert_withdraw(sdp, !error); /* dip already pinned */ |
460 | 498 | ||
461 | gfs2_trans_end(sdp); | 499 | gfs2_trans_end(sdp); |
462 | if (dip->i_alloc->al_rgd) | 500 | if (dip->i_alloc->al_rgd) |
463 | gfs2_inplace_release(dip); | 501 | gfs2_inplace_release(dip); |
464 | gfs2_quota_unlock(dip); | 502 | gfs2_quota_unlock(dip); |
465 | gfs2_alloc_put(dip); | 503 | gfs2_alloc_put(dip); |
466 | 504 | ||
467 | gfs2_glock_dq_uninit_m(2, ghs); | 505 | gfs2_glock_dq_uninit_m(2, ghs); |
468 | 506 | ||
469 | d_instantiate(dentry, inode); | 507 | d_instantiate(dentry, inode); |
470 | mark_inode_dirty(inode); | 508 | mark_inode_dirty(inode); |
471 | 509 | ||
472 | return 0; | 510 | return 0; |
473 | } | 511 | } |
474 | 512 | ||
475 | /** | 513 | /** |
476 | * gfs2_rmdiri - Remove a directory | 514 | * gfs2_rmdiri - Remove a directory |
477 | * @dip: The parent directory of the directory to be removed | 515 | * @dip: The parent directory of the directory to be removed |
478 | * @name: The name of the directory to be removed | 516 | * @name: The name of the directory to be removed |
479 | * @ip: The GFS2 inode of the directory to be removed | 517 | * @ip: The GFS2 inode of the directory to be removed |
480 | * | 518 | * |
481 | * Assumes Glocks on dip and ip are held | 519 | * Assumes Glocks on dip and ip are held |
482 | * | 520 | * |
483 | * Returns: errno | 521 | * Returns: errno |
484 | */ | 522 | */ |
485 | 523 | ||
486 | static int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, | 524 | static int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, |
487 | struct gfs2_inode *ip) | 525 | struct gfs2_inode *ip) |
488 | { | 526 | { |
489 | struct qstr dotname; | 527 | struct qstr dotname; |
490 | int error; | 528 | int error; |
491 | 529 | ||
492 | if (ip->i_entries != 2) { | 530 | if (ip->i_entries != 2) { |
493 | if (gfs2_consist_inode(ip)) | 531 | if (gfs2_consist_inode(ip)) |
494 | gfs2_dinode_print(ip); | 532 | gfs2_dinode_print(ip); |
495 | return -EIO; | 533 | return -EIO; |
496 | } | 534 | } |
497 | 535 | ||
498 | error = gfs2_dir_del(dip, name); | 536 | error = gfs2_dir_del(dip, name); |
499 | if (error) | 537 | if (error) |
500 | return error; | 538 | return error; |
501 | 539 | ||
502 | error = gfs2_change_nlink(dip, -1); | 540 | error = gfs2_change_nlink(dip, -1); |
503 | if (error) | 541 | if (error) |
504 | return error; | 542 | return error; |
505 | 543 | ||
506 | gfs2_str2qstr(&dotname, "."); | 544 | gfs2_str2qstr(&dotname, "."); |
507 | error = gfs2_dir_del(ip, &dotname); | 545 | error = gfs2_dir_del(ip, &dotname); |
508 | if (error) | 546 | if (error) |
509 | return error; | 547 | return error; |
510 | 548 | ||
511 | gfs2_str2qstr(&dotname, ".."); | 549 | gfs2_str2qstr(&dotname, ".."); |
512 | error = gfs2_dir_del(ip, &dotname); | 550 | error = gfs2_dir_del(ip, &dotname); |
513 | if (error) | 551 | if (error) |
514 | return error; | 552 | return error; |
515 | 553 | ||
516 | /* It looks odd, but it really should be done twice */ | 554 | /* It looks odd, but it really should be done twice */ |
517 | error = gfs2_change_nlink(ip, -1); | 555 | error = gfs2_change_nlink(ip, -1); |
518 | if (error) | 556 | if (error) |
519 | return error; | 557 | return error; |
520 | 558 | ||
521 | error = gfs2_change_nlink(ip, -1); | 559 | error = gfs2_change_nlink(ip, -1); |
522 | if (error) | 560 | if (error) |
523 | return error; | 561 | return error; |
524 | 562 | ||
525 | return error; | 563 | return error; |
526 | } | 564 | } |
527 | 565 | ||
528 | /** | 566 | /** |
529 | * gfs2_rmdir - Remove a directory | 567 | * gfs2_rmdir - Remove a directory |
530 | * @dir: The parent directory of the directory to be removed | 568 | * @dir: The parent directory of the directory to be removed |
531 | * @dentry: The dentry of the directory to remove | 569 | * @dentry: The dentry of the directory to remove |
532 | * | 570 | * |
533 | * Remove a directory. Call gfs2_rmdiri() | 571 | * Remove a directory. Call gfs2_rmdiri() |
534 | * | 572 | * |
535 | * Returns: errno | 573 | * Returns: errno |
536 | */ | 574 | */ |
537 | 575 | ||
538 | static int gfs2_rmdir(struct inode *dir, struct dentry *dentry) | 576 | static int gfs2_rmdir(struct inode *dir, struct dentry *dentry) |
539 | { | 577 | { |
540 | struct gfs2_inode *dip = GFS2_I(dir); | 578 | struct gfs2_inode *dip = GFS2_I(dir); |
541 | struct gfs2_sbd *sdp = GFS2_SB(dir); | 579 | struct gfs2_sbd *sdp = GFS2_SB(dir); |
542 | struct gfs2_inode *ip = GFS2_I(dentry->d_inode); | 580 | struct gfs2_inode *ip = GFS2_I(dentry->d_inode); |
543 | struct gfs2_holder ghs[3]; | 581 | struct gfs2_holder ghs[3]; |
544 | struct gfs2_rgrpd *rgd; | 582 | struct gfs2_rgrpd *rgd; |
545 | struct gfs2_holder ri_gh; | 583 | struct gfs2_holder ri_gh; |
546 | int error; | 584 | int error; |
547 | 585 | ||
548 | error = gfs2_rindex_hold(sdp, &ri_gh); | 586 | error = gfs2_rindex_hold(sdp, &ri_gh); |
549 | if (error) | 587 | if (error) |
550 | return error; | 588 | return error; |
551 | gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); | 589 | gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); |
552 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1); | 590 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1); |
553 | 591 | ||
554 | rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr); | 592 | rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr); |
555 | gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2); | 593 | gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2); |
556 | 594 | ||
557 | error = gfs2_glock_nq(ghs); /* parent */ | 595 | error = gfs2_glock_nq(ghs); /* parent */ |
558 | if (error) | 596 | if (error) |
559 | goto out_parent; | 597 | goto out_parent; |
560 | 598 | ||
561 | error = gfs2_glock_nq(ghs + 1); /* child */ | 599 | error = gfs2_glock_nq(ghs + 1); /* child */ |
562 | if (error) | 600 | if (error) |
563 | goto out_child; | 601 | goto out_child; |
564 | 602 | ||
565 | error = gfs2_glock_nq(ghs + 2); /* rgrp */ | 603 | error = gfs2_glock_nq(ghs + 2); /* rgrp */ |
566 | if (error) | 604 | if (error) |
567 | goto out_rgrp; | 605 | goto out_rgrp; |
568 | 606 | ||
569 | error = gfs2_unlink_ok(dip, &dentry->d_name, ip); | 607 | error = gfs2_unlink_ok(dip, &dentry->d_name, ip); |
570 | if (error) | 608 | if (error) |
571 | goto out_gunlock; | 609 | goto out_gunlock; |
572 | 610 | ||
573 | if (ip->i_entries < 2) { | 611 | if (ip->i_entries < 2) { |
574 | if (gfs2_consist_inode(ip)) | 612 | if (gfs2_consist_inode(ip)) |
575 | gfs2_dinode_print(ip); | 613 | gfs2_dinode_print(ip); |
576 | error = -EIO; | 614 | error = -EIO; |
577 | goto out_gunlock; | 615 | goto out_gunlock; |
578 | } | 616 | } |
579 | if (ip->i_entries > 2) { | 617 | if (ip->i_entries > 2) { |
580 | error = -ENOTEMPTY; | 618 | error = -ENOTEMPTY; |
581 | goto out_gunlock; | 619 | goto out_gunlock; |
582 | } | 620 | } |
583 | 621 | ||
584 | error = gfs2_trans_begin(sdp, 2 * RES_DINODE + 3 * RES_LEAF + RES_RG_BIT, 0); | 622 | error = gfs2_trans_begin(sdp, 2 * RES_DINODE + 3 * RES_LEAF + RES_RG_BIT, 0); |
585 | if (error) | 623 | if (error) |
586 | goto out_gunlock; | 624 | goto out_gunlock; |
587 | 625 | ||
588 | error = gfs2_rmdiri(dip, &dentry->d_name, ip); | 626 | error = gfs2_rmdiri(dip, &dentry->d_name, ip); |
589 | 627 | ||
590 | gfs2_trans_end(sdp); | 628 | gfs2_trans_end(sdp); |
591 | 629 | ||
592 | out_gunlock: | 630 | out_gunlock: |
593 | gfs2_glock_dq(ghs + 2); | 631 | gfs2_glock_dq(ghs + 2); |
594 | out_rgrp: | 632 | out_rgrp: |
595 | gfs2_holder_uninit(ghs + 2); | 633 | gfs2_holder_uninit(ghs + 2); |
596 | gfs2_glock_dq(ghs + 1); | 634 | gfs2_glock_dq(ghs + 1); |
597 | out_child: | 635 | out_child: |
598 | gfs2_holder_uninit(ghs + 1); | 636 | gfs2_holder_uninit(ghs + 1); |
599 | gfs2_glock_dq(ghs); | 637 | gfs2_glock_dq(ghs); |
600 | out_parent: | 638 | out_parent: |
601 | gfs2_holder_uninit(ghs); | 639 | gfs2_holder_uninit(ghs); |
602 | gfs2_glock_dq_uninit(&ri_gh); | 640 | gfs2_glock_dq_uninit(&ri_gh); |
603 | return error; | 641 | return error; |
604 | } | 642 | } |
605 | 643 | ||
606 | /** | 644 | /** |
607 | * gfs2_mknod - Make a special file | 645 | * gfs2_mknod - Make a special file |
608 | * @dir: The directory in which the special file will reside | 646 | * @dir: The directory in which the special file will reside |
609 | * @dentry: The dentry of the special file | 647 | * @dentry: The dentry of the special file |
610 | * @mode: The mode of the special file | 648 | * @mode: The mode of the special file |
611 | * @rdev: The device specification of the special file | 649 | * @rdev: The device specification of the special file |
612 | * | 650 | * |
613 | */ | 651 | */ |
614 | 652 | ||
615 | static int gfs2_mknod(struct inode *dir, struct dentry *dentry, int mode, | 653 | static int gfs2_mknod(struct inode *dir, struct dentry *dentry, int mode, |
616 | dev_t dev) | 654 | dev_t dev) |
617 | { | 655 | { |
618 | struct gfs2_inode *dip = GFS2_I(dir); | 656 | struct gfs2_inode *dip = GFS2_I(dir); |
619 | struct gfs2_sbd *sdp = GFS2_SB(dir); | 657 | struct gfs2_sbd *sdp = GFS2_SB(dir); |
620 | struct gfs2_holder ghs[2]; | 658 | struct gfs2_holder ghs[2]; |
621 | struct inode *inode; | 659 | struct inode *inode; |
622 | 660 | ||
623 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); | 661 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); |
624 | 662 | ||
625 | inode = gfs2_createi(ghs, &dentry->d_name, mode, dev); | 663 | inode = gfs2_createi(ghs, &dentry->d_name, mode, dev); |
626 | if (IS_ERR(inode)) { | 664 | if (IS_ERR(inode)) { |
627 | gfs2_holder_uninit(ghs); | 665 | gfs2_holder_uninit(ghs); |
628 | return PTR_ERR(inode); | 666 | return PTR_ERR(inode); |
629 | } | 667 | } |
630 | 668 | ||
631 | gfs2_trans_end(sdp); | 669 | gfs2_trans_end(sdp); |
632 | if (dip->i_alloc->al_rgd) | 670 | if (dip->i_alloc->al_rgd) |
633 | gfs2_inplace_release(dip); | 671 | gfs2_inplace_release(dip); |
634 | gfs2_quota_unlock(dip); | 672 | gfs2_quota_unlock(dip); |
635 | gfs2_alloc_put(dip); | 673 | gfs2_alloc_put(dip); |
636 | 674 | ||
637 | gfs2_glock_dq_uninit_m(2, ghs); | 675 | gfs2_glock_dq_uninit_m(2, ghs); |
638 | 676 | ||
639 | d_instantiate(dentry, inode); | 677 | d_instantiate(dentry, inode); |
640 | mark_inode_dirty(inode); | 678 | mark_inode_dirty(inode); |
641 | 679 | ||
642 | return 0; | 680 | return 0; |
643 | } | 681 | } |
644 | 682 | ||
645 | /* | 683 | /* |
646 | * gfs2_ok_to_move - check if it's ok to move a directory to another directory | 684 | * gfs2_ok_to_move - check if it's ok to move a directory to another directory |
647 | * @this: move this | 685 | * @this: move this |
648 | * @to: to here | 686 | * @to: to here |
649 | * | 687 | * |
650 | * Follow @to back to the root and make sure we don't encounter @this | 688 | * Follow @to back to the root and make sure we don't encounter @this |
651 | * Assumes we already hold the rename lock. | 689 | * Assumes we already hold the rename lock. |
652 | * | 690 | * |
653 | * Returns: errno | 691 | * Returns: errno |
654 | */ | 692 | */ |
655 | 693 | ||
656 | static int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to) | 694 | static int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to) |
657 | { | 695 | { |
658 | struct inode *dir = &to->i_inode; | 696 | struct inode *dir = &to->i_inode; |
659 | struct super_block *sb = dir->i_sb; | 697 | struct super_block *sb = dir->i_sb; |
660 | struct inode *tmp; | 698 | struct inode *tmp; |
661 | struct qstr dotdot; | 699 | struct qstr dotdot; |
662 | int error = 0; | 700 | int error = 0; |
663 | 701 | ||
664 | gfs2_str2qstr(&dotdot, ".."); | 702 | gfs2_str2qstr(&dotdot, ".."); |
665 | 703 | ||
666 | igrab(dir); | 704 | igrab(dir); |
667 | 705 | ||
668 | for (;;) { | 706 | for (;;) { |
669 | if (dir == &this->i_inode) { | 707 | if (dir == &this->i_inode) { |
670 | error = -EINVAL; | 708 | error = -EINVAL; |
671 | break; | 709 | break; |
672 | } | 710 | } |
673 | if (dir == sb->s_root->d_inode) { | 711 | if (dir == sb->s_root->d_inode) { |
674 | error = 0; | 712 | error = 0; |
675 | break; | 713 | break; |
676 | } | 714 | } |
677 | 715 | ||
678 | tmp = gfs2_lookupi(dir, &dotdot, 1); | 716 | tmp = gfs2_lookupi(dir, &dotdot, 1); |
679 | if (IS_ERR(tmp)) { | 717 | if (IS_ERR(tmp)) { |
680 | error = PTR_ERR(tmp); | 718 | error = PTR_ERR(tmp); |
681 | break; | 719 | break; |
682 | } | 720 | } |
683 | 721 | ||
684 | iput(dir); | 722 | iput(dir); |
685 | dir = tmp; | 723 | dir = tmp; |
686 | } | 724 | } |
687 | 725 | ||
688 | iput(dir); | 726 | iput(dir); |
689 | 727 | ||
690 | return error; | 728 | return error; |
691 | } | 729 | } |
692 | 730 | ||
693 | /** | 731 | /** |
694 | * gfs2_rename - Rename a file | 732 | * gfs2_rename - Rename a file |
695 | * @odir: Parent directory of old file name | 733 | * @odir: Parent directory of old file name |
696 | * @odentry: The old dentry of the file | 734 | * @odentry: The old dentry of the file |
697 | * @ndir: Parent directory of new file name | 735 | * @ndir: Parent directory of new file name |
698 | * @ndentry: The new dentry of the file | 736 | * @ndentry: The new dentry of the file |
699 | * | 737 | * |
700 | * Returns: errno | 738 | * Returns: errno |
701 | */ | 739 | */ |
702 | 740 | ||
703 | static int gfs2_rename(struct inode *odir, struct dentry *odentry, | 741 | static int gfs2_rename(struct inode *odir, struct dentry *odentry, |
704 | struct inode *ndir, struct dentry *ndentry) | 742 | struct inode *ndir, struct dentry *ndentry) |
705 | { | 743 | { |
706 | struct gfs2_inode *odip = GFS2_I(odir); | 744 | struct gfs2_inode *odip = GFS2_I(odir); |
707 | struct gfs2_inode *ndip = GFS2_I(ndir); | 745 | struct gfs2_inode *ndip = GFS2_I(ndir); |
708 | struct gfs2_inode *ip = GFS2_I(odentry->d_inode); | 746 | struct gfs2_inode *ip = GFS2_I(odentry->d_inode); |
709 | struct gfs2_inode *nip = NULL; | 747 | struct gfs2_inode *nip = NULL; |
710 | struct gfs2_sbd *sdp = GFS2_SB(odir); | 748 | struct gfs2_sbd *sdp = GFS2_SB(odir); |
711 | struct gfs2_holder ghs[5], r_gh = { .gh_gl = NULL, }; | 749 | struct gfs2_holder ghs[5], r_gh = { .gh_gl = NULL, }; |
712 | struct gfs2_rgrpd *nrgd; | 750 | struct gfs2_rgrpd *nrgd; |
713 | unsigned int num_gh; | 751 | unsigned int num_gh; |
714 | int dir_rename = 0; | 752 | int dir_rename = 0; |
715 | int alloc_required; | 753 | int alloc_required; |
716 | unsigned int x; | 754 | unsigned int x; |
717 | int error; | 755 | int error; |
718 | 756 | ||
719 | if (ndentry->d_inode) { | 757 | if (ndentry->d_inode) { |
720 | nip = GFS2_I(ndentry->d_inode); | 758 | nip = GFS2_I(ndentry->d_inode); |
721 | if (ip == nip) | 759 | if (ip == nip) |
722 | return 0; | 760 | return 0; |
723 | } | 761 | } |
724 | 762 | ||
725 | 763 | ||
726 | if (odip != ndip) { | 764 | if (odip != ndip) { |
727 | error = gfs2_glock_nq_init(sdp->sd_rename_gl, LM_ST_EXCLUSIVE, | 765 | error = gfs2_glock_nq_init(sdp->sd_rename_gl, LM_ST_EXCLUSIVE, |
728 | 0, &r_gh); | 766 | 0, &r_gh); |
729 | if (error) | 767 | if (error) |
730 | goto out; | 768 | goto out; |
731 | 769 | ||
732 | if (S_ISDIR(ip->i_inode.i_mode)) { | 770 | if (S_ISDIR(ip->i_inode.i_mode)) { |
733 | dir_rename = 1; | 771 | dir_rename = 1; |
734 | /* don't move a dirctory into it's subdir */ | 772 | /* don't move a dirctory into it's subdir */ |
735 | error = gfs2_ok_to_move(ip, ndip); | 773 | error = gfs2_ok_to_move(ip, ndip); |
736 | if (error) | 774 | if (error) |
737 | goto out_gunlock_r; | 775 | goto out_gunlock_r; |
738 | } | 776 | } |
739 | } | 777 | } |
740 | 778 | ||
741 | num_gh = 1; | 779 | num_gh = 1; |
742 | gfs2_holder_init(odip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); | 780 | gfs2_holder_init(odip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); |
743 | if (odip != ndip) { | 781 | if (odip != ndip) { |
744 | gfs2_holder_init(ndip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh); | 782 | gfs2_holder_init(ndip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh); |
745 | num_gh++; | 783 | num_gh++; |
746 | } | 784 | } |
747 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh); | 785 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh); |
748 | num_gh++; | 786 | num_gh++; |
749 | 787 | ||
750 | if (nip) { | 788 | if (nip) { |
751 | gfs2_holder_init(nip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh); | 789 | gfs2_holder_init(nip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh); |
752 | num_gh++; | 790 | num_gh++; |
753 | /* grab the resource lock for unlink flag twiddling | 791 | /* grab the resource lock for unlink flag twiddling |
754 | * this is the case of the target file already existing | 792 | * this is the case of the target file already existing |
755 | * so we unlink before doing the rename | 793 | * so we unlink before doing the rename |
756 | */ | 794 | */ |
757 | nrgd = gfs2_blk2rgrpd(sdp, nip->i_no_addr); | 795 | nrgd = gfs2_blk2rgrpd(sdp, nip->i_no_addr); |
758 | if (nrgd) | 796 | if (nrgd) |
759 | gfs2_holder_init(nrgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh++); | 797 | gfs2_holder_init(nrgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh++); |
760 | } | 798 | } |
761 | 799 | ||
762 | for (x = 0; x < num_gh; x++) { | 800 | for (x = 0; x < num_gh; x++) { |
763 | error = gfs2_glock_nq(ghs + x); | 801 | error = gfs2_glock_nq(ghs + x); |
764 | if (error) | 802 | if (error) |
765 | goto out_gunlock; | 803 | goto out_gunlock; |
766 | } | 804 | } |
767 | 805 | ||
768 | /* Check out the old directory */ | 806 | /* Check out the old directory */ |
769 | 807 | ||
770 | error = gfs2_unlink_ok(odip, &odentry->d_name, ip); | 808 | error = gfs2_unlink_ok(odip, &odentry->d_name, ip); |
771 | if (error) | 809 | if (error) |
772 | goto out_gunlock; | 810 | goto out_gunlock; |
773 | 811 | ||
774 | /* Check out the new directory */ | 812 | /* Check out the new directory */ |
775 | 813 | ||
776 | if (nip) { | 814 | if (nip) { |
777 | error = gfs2_unlink_ok(ndip, &ndentry->d_name, nip); | 815 | error = gfs2_unlink_ok(ndip, &ndentry->d_name, nip); |
778 | if (error) | 816 | if (error) |
779 | goto out_gunlock; | 817 | goto out_gunlock; |
780 | 818 | ||
781 | if (S_ISDIR(nip->i_inode.i_mode)) { | 819 | if (S_ISDIR(nip->i_inode.i_mode)) { |
782 | if (nip->i_entries < 2) { | 820 | if (nip->i_entries < 2) { |
783 | if (gfs2_consist_inode(nip)) | 821 | if (gfs2_consist_inode(nip)) |
784 | gfs2_dinode_print(nip); | 822 | gfs2_dinode_print(nip); |
785 | error = -EIO; | 823 | error = -EIO; |
786 | goto out_gunlock; | 824 | goto out_gunlock; |
787 | } | 825 | } |
788 | if (nip->i_entries > 2) { | 826 | if (nip->i_entries > 2) { |
789 | error = -ENOTEMPTY; | 827 | error = -ENOTEMPTY; |
790 | goto out_gunlock; | 828 | goto out_gunlock; |
791 | } | 829 | } |
792 | } | 830 | } |
793 | } else { | 831 | } else { |
794 | error = gfs2_permission(ndir, MAY_WRITE | MAY_EXEC); | 832 | error = gfs2_permission(ndir, MAY_WRITE | MAY_EXEC); |
795 | if (error) | 833 | if (error) |
796 | goto out_gunlock; | 834 | goto out_gunlock; |
797 | 835 | ||
798 | error = gfs2_dir_check(ndir, &ndentry->d_name, NULL); | 836 | error = gfs2_dir_check(ndir, &ndentry->d_name, NULL); |
799 | switch (error) { | 837 | switch (error) { |
800 | case -ENOENT: | 838 | case -ENOENT: |
801 | error = 0; | 839 | error = 0; |
802 | break; | 840 | break; |
803 | case 0: | 841 | case 0: |
804 | error = -EEXIST; | 842 | error = -EEXIST; |
805 | default: | 843 | default: |
806 | goto out_gunlock; | 844 | goto out_gunlock; |
807 | }; | 845 | }; |
808 | 846 | ||
809 | if (odip != ndip) { | 847 | if (odip != ndip) { |
810 | if (!ndip->i_inode.i_nlink) { | 848 | if (!ndip->i_inode.i_nlink) { |
811 | error = -EINVAL; | 849 | error = -EINVAL; |
812 | goto out_gunlock; | 850 | goto out_gunlock; |
813 | } | 851 | } |
814 | if (ndip->i_entries == (u32)-1) { | 852 | if (ndip->i_entries == (u32)-1) { |
815 | error = -EFBIG; | 853 | error = -EFBIG; |
816 | goto out_gunlock; | 854 | goto out_gunlock; |
817 | } | 855 | } |
818 | if (S_ISDIR(ip->i_inode.i_mode) && | 856 | if (S_ISDIR(ip->i_inode.i_mode) && |
819 | ndip->i_inode.i_nlink == (u32)-1) { | 857 | ndip->i_inode.i_nlink == (u32)-1) { |
820 | error = -EMLINK; | 858 | error = -EMLINK; |
821 | goto out_gunlock; | 859 | goto out_gunlock; |
822 | } | 860 | } |
823 | } | 861 | } |
824 | } | 862 | } |
825 | 863 | ||
826 | /* Check out the dir to be renamed */ | 864 | /* Check out the dir to be renamed */ |
827 | 865 | ||
828 | if (dir_rename) { | 866 | if (dir_rename) { |
829 | error = gfs2_permission(odentry->d_inode, MAY_WRITE); | 867 | error = gfs2_permission(odentry->d_inode, MAY_WRITE); |
830 | if (error) | 868 | if (error) |
831 | goto out_gunlock; | 869 | goto out_gunlock; |
832 | } | 870 | } |
833 | 871 | ||
834 | alloc_required = error = gfs2_diradd_alloc_required(ndir, &ndentry->d_name); | 872 | alloc_required = error = gfs2_diradd_alloc_required(ndir, &ndentry->d_name); |
835 | if (error < 0) | 873 | if (error < 0) |
836 | goto out_gunlock; | 874 | goto out_gunlock; |
837 | error = 0; | 875 | error = 0; |
838 | 876 | ||
839 | if (alloc_required) { | 877 | if (alloc_required) { |
840 | struct gfs2_alloc *al = gfs2_alloc_get(ndip); | 878 | struct gfs2_alloc *al = gfs2_alloc_get(ndip); |
841 | if (!al) { | 879 | if (!al) { |
842 | error = -ENOMEM; | 880 | error = -ENOMEM; |
843 | goto out_gunlock; | 881 | goto out_gunlock; |
844 | } | 882 | } |
845 | 883 | ||
846 | error = gfs2_quota_lock_check(ndip); | 884 | error = gfs2_quota_lock_check(ndip); |
847 | if (error) | 885 | if (error) |
848 | goto out_alloc; | 886 | goto out_alloc; |
849 | 887 | ||
850 | al->al_requested = sdp->sd_max_dirres; | 888 | al->al_requested = sdp->sd_max_dirres; |
851 | 889 | ||
852 | error = gfs2_inplace_reserve(ndip); | 890 | error = gfs2_inplace_reserve(ndip); |
853 | if (error) | 891 | if (error) |
854 | goto out_gunlock_q; | 892 | goto out_gunlock_q; |
855 | 893 | ||
856 | error = gfs2_trans_begin(sdp, sdp->sd_max_dirres + | 894 | error = gfs2_trans_begin(sdp, sdp->sd_max_dirres + |
857 | al->al_rgd->rd_length + | 895 | al->al_rgd->rd_length + |
858 | 4 * RES_DINODE + 4 * RES_LEAF + | 896 | 4 * RES_DINODE + 4 * RES_LEAF + |
859 | RES_STATFS + RES_QUOTA + 4, 0); | 897 | RES_STATFS + RES_QUOTA + 4, 0); |
860 | if (error) | 898 | if (error) |
861 | goto out_ipreserv; | 899 | goto out_ipreserv; |
862 | } else { | 900 | } else { |
863 | error = gfs2_trans_begin(sdp, 4 * RES_DINODE + | 901 | error = gfs2_trans_begin(sdp, 4 * RES_DINODE + |
864 | 5 * RES_LEAF + 4, 0); | 902 | 5 * RES_LEAF + 4, 0); |
865 | if (error) | 903 | if (error) |
866 | goto out_gunlock; | 904 | goto out_gunlock; |
867 | } | 905 | } |
868 | 906 | ||
869 | /* Remove the target file, if it exists */ | 907 | /* Remove the target file, if it exists */ |
870 | 908 | ||
871 | if (nip) { | 909 | if (nip) { |
872 | if (S_ISDIR(nip->i_inode.i_mode)) | 910 | if (S_ISDIR(nip->i_inode.i_mode)) |
873 | error = gfs2_rmdiri(ndip, &ndentry->d_name, nip); | 911 | error = gfs2_rmdiri(ndip, &ndentry->d_name, nip); |
874 | else { | 912 | else { |
875 | error = gfs2_dir_del(ndip, &ndentry->d_name); | 913 | error = gfs2_dir_del(ndip, &ndentry->d_name); |
876 | if (error) | 914 | if (error) |
877 | goto out_end_trans; | 915 | goto out_end_trans; |
878 | error = gfs2_change_nlink(nip, -1); | 916 | error = gfs2_change_nlink(nip, -1); |
879 | } | 917 | } |
880 | if (error) | 918 | if (error) |
881 | goto out_end_trans; | 919 | goto out_end_trans; |
882 | } | 920 | } |
883 | 921 | ||
884 | if (dir_rename) { | 922 | if (dir_rename) { |
885 | struct qstr name; | 923 | struct qstr name; |
886 | gfs2_str2qstr(&name, ".."); | 924 | gfs2_str2qstr(&name, ".."); |
887 | 925 | ||
888 | error = gfs2_change_nlink(ndip, +1); | 926 | error = gfs2_change_nlink(ndip, +1); |
889 | if (error) | 927 | if (error) |
890 | goto out_end_trans; | 928 | goto out_end_trans; |
891 | error = gfs2_change_nlink(odip, -1); | 929 | error = gfs2_change_nlink(odip, -1); |
892 | if (error) | 930 | if (error) |
893 | goto out_end_trans; | 931 | goto out_end_trans; |
894 | 932 | ||
895 | error = gfs2_dir_mvino(ip, &name, ndip, DT_DIR); | 933 | error = gfs2_dir_mvino(ip, &name, ndip, DT_DIR); |
896 | if (error) | 934 | if (error) |
897 | goto out_end_trans; | 935 | goto out_end_trans; |
898 | } else { | 936 | } else { |
899 | struct buffer_head *dibh; | 937 | struct buffer_head *dibh; |
900 | error = gfs2_meta_inode_buffer(ip, &dibh); | 938 | error = gfs2_meta_inode_buffer(ip, &dibh); |
901 | if (error) | 939 | if (error) |
902 | goto out_end_trans; | 940 | goto out_end_trans; |
903 | ip->i_inode.i_ctime = CURRENT_TIME; | 941 | ip->i_inode.i_ctime = CURRENT_TIME; |
904 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 942 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
905 | gfs2_dinode_out(ip, dibh->b_data); | 943 | gfs2_dinode_out(ip, dibh->b_data); |
906 | brelse(dibh); | 944 | brelse(dibh); |
907 | } | 945 | } |
908 | 946 | ||
909 | error = gfs2_dir_del(odip, &odentry->d_name); | 947 | error = gfs2_dir_del(odip, &odentry->d_name); |
910 | if (error) | 948 | if (error) |
911 | goto out_end_trans; | 949 | goto out_end_trans; |
912 | 950 | ||
913 | error = gfs2_dir_add(ndir, &ndentry->d_name, ip, IF2DT(ip->i_inode.i_mode)); | 951 | error = gfs2_dir_add(ndir, &ndentry->d_name, ip, IF2DT(ip->i_inode.i_mode)); |
914 | if (error) | 952 | if (error) |
915 | goto out_end_trans; | 953 | goto out_end_trans; |
916 | 954 | ||
917 | out_end_trans: | 955 | out_end_trans: |
918 | gfs2_trans_end(sdp); | 956 | gfs2_trans_end(sdp); |
919 | out_ipreserv: | 957 | out_ipreserv: |
920 | if (alloc_required) | 958 | if (alloc_required) |
921 | gfs2_inplace_release(ndip); | 959 | gfs2_inplace_release(ndip); |
922 | out_gunlock_q: | 960 | out_gunlock_q: |
923 | if (alloc_required) | 961 | if (alloc_required) |
924 | gfs2_quota_unlock(ndip); | 962 | gfs2_quota_unlock(ndip); |
925 | out_alloc: | 963 | out_alloc: |
926 | if (alloc_required) | 964 | if (alloc_required) |
927 | gfs2_alloc_put(ndip); | 965 | gfs2_alloc_put(ndip); |
928 | out_gunlock: | 966 | out_gunlock: |
929 | while (x--) { | 967 | while (x--) { |
930 | gfs2_glock_dq(ghs + x); | 968 | gfs2_glock_dq(ghs + x); |
931 | gfs2_holder_uninit(ghs + x); | 969 | gfs2_holder_uninit(ghs + x); |
932 | } | 970 | } |
933 | out_gunlock_r: | 971 | out_gunlock_r: |
934 | if (r_gh.gh_gl) | 972 | if (r_gh.gh_gl) |
935 | gfs2_glock_dq_uninit(&r_gh); | 973 | gfs2_glock_dq_uninit(&r_gh); |
936 | out: | 974 | out: |
937 | return error; | 975 | return error; |
938 | } | 976 | } |
939 | 977 | ||
940 | /** | 978 | /** |
941 | * gfs2_readlinki - return the contents of a symlink | 979 | * gfs2_readlinki - return the contents of a symlink |
942 | * @ip: the symlink's inode | 980 | * @ip: the symlink's inode |
943 | * @buf: a pointer to the buffer to be filled | 981 | * @buf: a pointer to the buffer to be filled |
944 | * @len: a pointer to the length of @buf | 982 | * @len: a pointer to the length of @buf |
945 | * | 983 | * |
946 | * If @buf is too small, a piece of memory is kmalloc()ed and needs | 984 | * If @buf is too small, a piece of memory is kmalloc()ed and needs |
947 | * to be freed by the caller. | 985 | * to be freed by the caller. |
948 | * | 986 | * |
949 | * Returns: errno | 987 | * Returns: errno |
950 | */ | 988 | */ |
951 | 989 | ||
952 | static int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len) | 990 | static int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len) |
953 | { | 991 | { |
954 | struct gfs2_holder i_gh; | 992 | struct gfs2_holder i_gh; |
955 | struct buffer_head *dibh; | 993 | struct buffer_head *dibh; |
956 | unsigned int x; | 994 | unsigned int x; |
957 | int error; | 995 | int error; |
958 | 996 | ||
959 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &i_gh); | 997 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &i_gh); |
960 | error = gfs2_glock_nq(&i_gh); | 998 | error = gfs2_glock_nq(&i_gh); |
961 | if (error) { | 999 | if (error) { |
962 | gfs2_holder_uninit(&i_gh); | 1000 | gfs2_holder_uninit(&i_gh); |
963 | return error; | 1001 | return error; |
964 | } | 1002 | } |
965 | 1003 | ||
966 | if (!ip->i_disksize) { | 1004 | if (!ip->i_disksize) { |
967 | gfs2_consist_inode(ip); | 1005 | gfs2_consist_inode(ip); |
968 | error = -EIO; | 1006 | error = -EIO; |
969 | goto out; | 1007 | goto out; |
970 | } | 1008 | } |
971 | 1009 | ||
972 | error = gfs2_meta_inode_buffer(ip, &dibh); | 1010 | error = gfs2_meta_inode_buffer(ip, &dibh); |
973 | if (error) | 1011 | if (error) |
974 | goto out; | 1012 | goto out; |
975 | 1013 | ||
976 | x = ip->i_disksize + 1; | 1014 | x = ip->i_disksize + 1; |
977 | if (x > *len) { | 1015 | if (x > *len) { |
978 | *buf = kmalloc(x, GFP_NOFS); | 1016 | *buf = kmalloc(x, GFP_NOFS); |
979 | if (!*buf) { | 1017 | if (!*buf) { |
980 | error = -ENOMEM; | 1018 | error = -ENOMEM; |
981 | goto out_brelse; | 1019 | goto out_brelse; |
982 | } | 1020 | } |
983 | } | 1021 | } |
984 | 1022 | ||
985 | memcpy(*buf, dibh->b_data + sizeof(struct gfs2_dinode), x); | 1023 | memcpy(*buf, dibh->b_data + sizeof(struct gfs2_dinode), x); |
986 | *len = x; | 1024 | *len = x; |
987 | 1025 | ||
988 | out_brelse: | 1026 | out_brelse: |
989 | brelse(dibh); | 1027 | brelse(dibh); |
990 | out: | 1028 | out: |
991 | gfs2_glock_dq_uninit(&i_gh); | 1029 | gfs2_glock_dq_uninit(&i_gh); |
992 | return error; | 1030 | return error; |
993 | } | 1031 | } |
994 | 1032 | ||
995 | /** | 1033 | /** |
996 | * gfs2_readlink - Read the value of a symlink | 1034 | * gfs2_readlink - Read the value of a symlink |
997 | * @dentry: the symlink | 1035 | * @dentry: the symlink |
998 | * @buf: the buffer to read the symlink data into | 1036 | * @buf: the buffer to read the symlink data into |
999 | * @size: the size of the buffer | 1037 | * @size: the size of the buffer |
1000 | * | 1038 | * |
1001 | * Returns: errno | 1039 | * Returns: errno |
1002 | */ | 1040 | */ |
1003 | 1041 | ||
1004 | static int gfs2_readlink(struct dentry *dentry, char __user *user_buf, | 1042 | static int gfs2_readlink(struct dentry *dentry, char __user *user_buf, |
1005 | int user_size) | 1043 | int user_size) |
1006 | { | 1044 | { |
1007 | struct gfs2_inode *ip = GFS2_I(dentry->d_inode); | 1045 | struct gfs2_inode *ip = GFS2_I(dentry->d_inode); |
1008 | char array[GFS2_FAST_NAME_SIZE], *buf = array; | 1046 | char array[GFS2_FAST_NAME_SIZE], *buf = array; |
1009 | unsigned int len = GFS2_FAST_NAME_SIZE; | 1047 | unsigned int len = GFS2_FAST_NAME_SIZE; |
1010 | int error; | 1048 | int error; |
1011 | 1049 | ||
1012 | error = gfs2_readlinki(ip, &buf, &len); | 1050 | error = gfs2_readlinki(ip, &buf, &len); |
1013 | if (error) | 1051 | if (error) |
1014 | return error; | 1052 | return error; |
1015 | 1053 | ||
1016 | if (user_size > len - 1) | 1054 | if (user_size > len - 1) |
1017 | user_size = len - 1; | 1055 | user_size = len - 1; |
1018 | 1056 | ||
1019 | if (copy_to_user(user_buf, buf, user_size)) | 1057 | if (copy_to_user(user_buf, buf, user_size)) |
1020 | error = -EFAULT; | 1058 | error = -EFAULT; |
1021 | else | 1059 | else |
1022 | error = user_size; | 1060 | error = user_size; |
1023 | 1061 | ||
1024 | if (buf != array) | 1062 | if (buf != array) |
1025 | kfree(buf); | 1063 | kfree(buf); |
1026 | 1064 | ||
1027 | return error; | 1065 | return error; |
1028 | } | 1066 | } |
1029 | 1067 | ||
1030 | /** | 1068 | /** |
1031 | * gfs2_follow_link - Follow a symbolic link | 1069 | * gfs2_follow_link - Follow a symbolic link |
1032 | * @dentry: The dentry of the link | 1070 | * @dentry: The dentry of the link |
1033 | * @nd: Data that we pass to vfs_follow_link() | 1071 | * @nd: Data that we pass to vfs_follow_link() |
1034 | * | 1072 | * |
1035 | * This can handle symlinks of any size. It is optimised for symlinks | 1073 | * This can handle symlinks of any size. It is optimised for symlinks |
1036 | * under GFS2_FAST_NAME_SIZE. | 1074 | * under GFS2_FAST_NAME_SIZE. |
1037 | * | 1075 | * |
1038 | * Returns: 0 on success or error code | 1076 | * Returns: 0 on success or error code |
1039 | */ | 1077 | */ |
1040 | 1078 | ||
1041 | static void *gfs2_follow_link(struct dentry *dentry, struct nameidata *nd) | 1079 | static void *gfs2_follow_link(struct dentry *dentry, struct nameidata *nd) |
1042 | { | 1080 | { |
1043 | struct gfs2_inode *ip = GFS2_I(dentry->d_inode); | 1081 | struct gfs2_inode *ip = GFS2_I(dentry->d_inode); |
1044 | char array[GFS2_FAST_NAME_SIZE], *buf = array; | 1082 | char array[GFS2_FAST_NAME_SIZE], *buf = array; |
1045 | unsigned int len = GFS2_FAST_NAME_SIZE; | 1083 | unsigned int len = GFS2_FAST_NAME_SIZE; |
1046 | int error; | 1084 | int error; |
1047 | 1085 | ||
1048 | error = gfs2_readlinki(ip, &buf, &len); | 1086 | error = gfs2_readlinki(ip, &buf, &len); |
1049 | if (!error) { | 1087 | if (!error) { |
1050 | error = vfs_follow_link(nd, buf); | 1088 | error = vfs_follow_link(nd, buf); |
1051 | if (buf != array) | 1089 | if (buf != array) |
1052 | kfree(buf); | 1090 | kfree(buf); |
1053 | } | 1091 | } |
1054 | 1092 | ||
1055 | return ERR_PTR(error); | 1093 | return ERR_PTR(error); |
1056 | } | 1094 | } |
1057 | 1095 | ||
1058 | /** | 1096 | /** |
1059 | * gfs2_permission - | 1097 | * gfs2_permission - |
1060 | * @inode: | 1098 | * @inode: |
1061 | * @mask: | 1099 | * @mask: |
1062 | * @nd: passed from Linux VFS, ignored by us | 1100 | * @nd: passed from Linux VFS, ignored by us |
1063 | * | 1101 | * |
1064 | * This may be called from the VFS directly, or from within GFS2 with the | 1102 | * This may be called from the VFS directly, or from within GFS2 with the |
1065 | * inode locked, so we look to see if the glock is already locked and only | 1103 | * inode locked, so we look to see if the glock is already locked and only |
1066 | * lock the glock if its not already been done. | 1104 | * lock the glock if its not already been done. |
1067 | * | 1105 | * |
1068 | * Returns: errno | 1106 | * Returns: errno |
1069 | */ | 1107 | */ |
1070 | 1108 | ||
1071 | int gfs2_permission(struct inode *inode, int mask) | 1109 | int gfs2_permission(struct inode *inode, int mask) |
1072 | { | 1110 | { |
1073 | struct gfs2_inode *ip = GFS2_I(inode); | 1111 | struct gfs2_inode *ip = GFS2_I(inode); |
1074 | struct gfs2_holder i_gh; | 1112 | struct gfs2_holder i_gh; |
1075 | int error; | 1113 | int error; |
1076 | int unlock = 0; | 1114 | int unlock = 0; |
1077 | 1115 | ||
1078 | if (gfs2_glock_is_locked_by_me(ip->i_gl) == NULL) { | 1116 | if (gfs2_glock_is_locked_by_me(ip->i_gl) == NULL) { |
1079 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); | 1117 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); |
1080 | if (error) | 1118 | if (error) |
1081 | return error; | 1119 | return error; |
1082 | unlock = 1; | 1120 | unlock = 1; |
1083 | } | 1121 | } |
1084 | 1122 | ||
1085 | if ((mask & MAY_WRITE) && IS_IMMUTABLE(inode)) | 1123 | if ((mask & MAY_WRITE) && IS_IMMUTABLE(inode)) |
1086 | error = -EACCES; | 1124 | error = -EACCES; |
1087 | else | 1125 | else |
1088 | error = generic_permission(inode, mask, gfs2_check_acl); | 1126 | error = generic_permission(inode, mask, gfs2_check_acl); |
1089 | if (unlock) | 1127 | if (unlock) |
1090 | gfs2_glock_dq_uninit(&i_gh); | 1128 | gfs2_glock_dq_uninit(&i_gh); |
1091 | 1129 | ||
1092 | return error; | 1130 | return error; |
1093 | } | 1131 | } |
1094 | 1132 | ||
1095 | static int setattr_size(struct inode *inode, struct iattr *attr) | 1133 | static int setattr_size(struct inode *inode, struct iattr *attr) |
1096 | { | 1134 | { |
1097 | struct gfs2_inode *ip = GFS2_I(inode); | 1135 | struct gfs2_inode *ip = GFS2_I(inode); |
1098 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 1136 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
1099 | int error; | 1137 | int error; |
1100 | 1138 | ||
1101 | if (attr->ia_size != ip->i_disksize) { | 1139 | if (attr->ia_size != ip->i_disksize) { |
1102 | error = gfs2_trans_begin(sdp, 0, sdp->sd_jdesc->jd_blocks); | 1140 | error = gfs2_trans_begin(sdp, 0, sdp->sd_jdesc->jd_blocks); |
1103 | if (error) | 1141 | if (error) |
1104 | return error; | 1142 | return error; |
1105 | error = vmtruncate(inode, attr->ia_size); | 1143 | error = vmtruncate(inode, attr->ia_size); |
1106 | gfs2_trans_end(sdp); | 1144 | gfs2_trans_end(sdp); |
1107 | if (error) | 1145 | if (error) |
1108 | return error; | 1146 | return error; |
1109 | } | 1147 | } |
1110 | 1148 | ||
1111 | error = gfs2_truncatei(ip, attr->ia_size); | 1149 | error = gfs2_truncatei(ip, attr->ia_size); |
1112 | if (error && (inode->i_size != ip->i_disksize)) | 1150 | if (error && (inode->i_size != ip->i_disksize)) |
1113 | i_size_write(inode, ip->i_disksize); | 1151 | i_size_write(inode, ip->i_disksize); |
1114 | 1152 | ||
1115 | return error; | 1153 | return error; |
1116 | } | 1154 | } |
1117 | 1155 | ||
1118 | static int setattr_chown(struct inode *inode, struct iattr *attr) | 1156 | static int setattr_chown(struct inode *inode, struct iattr *attr) |
1119 | { | 1157 | { |
1120 | struct gfs2_inode *ip = GFS2_I(inode); | 1158 | struct gfs2_inode *ip = GFS2_I(inode); |
1121 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 1159 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
1122 | struct buffer_head *dibh; | 1160 | struct buffer_head *dibh; |
1123 | u32 ouid, ogid, nuid, ngid; | 1161 | u32 ouid, ogid, nuid, ngid; |
1124 | int error; | 1162 | int error; |
1125 | 1163 | ||
1126 | ouid = inode->i_uid; | 1164 | ouid = inode->i_uid; |
1127 | ogid = inode->i_gid; | 1165 | ogid = inode->i_gid; |
1128 | nuid = attr->ia_uid; | 1166 | nuid = attr->ia_uid; |
1129 | ngid = attr->ia_gid; | 1167 | ngid = attr->ia_gid; |
1130 | 1168 | ||
1131 | if (!(attr->ia_valid & ATTR_UID) || ouid == nuid) | 1169 | if (!(attr->ia_valid & ATTR_UID) || ouid == nuid) |
1132 | ouid = nuid = NO_QUOTA_CHANGE; | 1170 | ouid = nuid = NO_QUOTA_CHANGE; |
1133 | if (!(attr->ia_valid & ATTR_GID) || ogid == ngid) | 1171 | if (!(attr->ia_valid & ATTR_GID) || ogid == ngid) |
1134 | ogid = ngid = NO_QUOTA_CHANGE; | 1172 | ogid = ngid = NO_QUOTA_CHANGE; |
1135 | 1173 | ||
1136 | if (!gfs2_alloc_get(ip)) | 1174 | if (!gfs2_alloc_get(ip)) |
1137 | return -ENOMEM; | 1175 | return -ENOMEM; |
1138 | 1176 | ||
1139 | error = gfs2_quota_lock(ip, nuid, ngid); | 1177 | error = gfs2_quota_lock(ip, nuid, ngid); |
1140 | if (error) | 1178 | if (error) |
1141 | goto out_alloc; | 1179 | goto out_alloc; |
1142 | 1180 | ||
1143 | if (ouid != NO_QUOTA_CHANGE || ogid != NO_QUOTA_CHANGE) { | 1181 | if (ouid != NO_QUOTA_CHANGE || ogid != NO_QUOTA_CHANGE) { |
1144 | error = gfs2_quota_check(ip, nuid, ngid); | 1182 | error = gfs2_quota_check(ip, nuid, ngid); |
1145 | if (error) | 1183 | if (error) |
1146 | goto out_gunlock_q; | 1184 | goto out_gunlock_q; |
1147 | } | 1185 | } |
1148 | 1186 | ||
1149 | error = gfs2_trans_begin(sdp, RES_DINODE + 2 * RES_QUOTA, 0); | 1187 | error = gfs2_trans_begin(sdp, RES_DINODE + 2 * RES_QUOTA, 0); |
1150 | if (error) | 1188 | if (error) |
1151 | goto out_gunlock_q; | 1189 | goto out_gunlock_q; |
1152 | 1190 | ||
1153 | error = gfs2_meta_inode_buffer(ip, &dibh); | 1191 | error = gfs2_meta_inode_buffer(ip, &dibh); |
1154 | if (error) | 1192 | if (error) |
1155 | goto out_end_trans; | 1193 | goto out_end_trans; |
1156 | 1194 | ||
1157 | error = inode_setattr(inode, attr); | 1195 | error = inode_setattr(inode, attr); |
1158 | gfs2_assert_warn(sdp, !error); | 1196 | gfs2_assert_warn(sdp, !error); |
1159 | 1197 | ||
1160 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 1198 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
1161 | gfs2_dinode_out(ip, dibh->b_data); | 1199 | gfs2_dinode_out(ip, dibh->b_data); |
1162 | brelse(dibh); | 1200 | brelse(dibh); |
1163 | 1201 | ||
1164 | if (ouid != NO_QUOTA_CHANGE || ogid != NO_QUOTA_CHANGE) { | 1202 | if (ouid != NO_QUOTA_CHANGE || ogid != NO_QUOTA_CHANGE) { |
1165 | u64 blocks = gfs2_get_inode_blocks(&ip->i_inode); | 1203 | u64 blocks = gfs2_get_inode_blocks(&ip->i_inode); |
1166 | gfs2_quota_change(ip, -blocks, ouid, ogid); | 1204 | gfs2_quota_change(ip, -blocks, ouid, ogid); |
1167 | gfs2_quota_change(ip, blocks, nuid, ngid); | 1205 | gfs2_quota_change(ip, blocks, nuid, ngid); |
1168 | } | 1206 | } |
1169 | 1207 | ||
1170 | out_end_trans: | 1208 | out_end_trans: |
1171 | gfs2_trans_end(sdp); | 1209 | gfs2_trans_end(sdp); |
1172 | out_gunlock_q: | 1210 | out_gunlock_q: |
1173 | gfs2_quota_unlock(ip); | 1211 | gfs2_quota_unlock(ip); |
1174 | out_alloc: | 1212 | out_alloc: |
1175 | gfs2_alloc_put(ip); | 1213 | gfs2_alloc_put(ip); |
1176 | return error; | 1214 | return error; |
1177 | } | 1215 | } |
1178 | 1216 | ||
1179 | /** | 1217 | /** |
1180 | * gfs2_setattr - Change attributes on an inode | 1218 | * gfs2_setattr - Change attributes on an inode |
1181 | * @dentry: The dentry which is changing | 1219 | * @dentry: The dentry which is changing |
1182 | * @attr: The structure describing the change | 1220 | * @attr: The structure describing the change |
1183 | * | 1221 | * |
1184 | * The VFS layer wants to change one or more of an inodes attributes. Write | 1222 | * The VFS layer wants to change one or more of an inodes attributes. Write |
1185 | * that change out to disk. | 1223 | * that change out to disk. |
1186 | * | 1224 | * |
1187 | * Returns: errno | 1225 | * Returns: errno |
1188 | */ | 1226 | */ |
1189 | 1227 | ||
1190 | static int gfs2_setattr(struct dentry *dentry, struct iattr *attr) | 1228 | static int gfs2_setattr(struct dentry *dentry, struct iattr *attr) |
1191 | { | 1229 | { |
1192 | struct inode *inode = dentry->d_inode; | 1230 | struct inode *inode = dentry->d_inode; |
1193 | struct gfs2_inode *ip = GFS2_I(inode); | 1231 | struct gfs2_inode *ip = GFS2_I(inode); |
1194 | struct gfs2_holder i_gh; | 1232 | struct gfs2_holder i_gh; |
1195 | int error; | 1233 | int error; |
1196 | 1234 | ||
1197 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh); | 1235 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh); |
1198 | if (error) | 1236 | if (error) |
1199 | return error; | 1237 | return error; |
1200 | 1238 | ||
1201 | error = -EPERM; | 1239 | error = -EPERM; |
1202 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) | 1240 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) |
1203 | goto out; | 1241 | goto out; |
1204 | 1242 | ||
1205 | error = inode_change_ok(inode, attr); | 1243 | error = inode_change_ok(inode, attr); |
1206 | if (error) | 1244 | if (error) |
1207 | goto out; | 1245 | goto out; |
1208 | 1246 | ||
1209 | if (attr->ia_valid & ATTR_SIZE) | 1247 | if (attr->ia_valid & ATTR_SIZE) |
1210 | error = setattr_size(inode, attr); | 1248 | error = setattr_size(inode, attr); |
1211 | else if (attr->ia_valid & (ATTR_UID | ATTR_GID)) | 1249 | else if (attr->ia_valid & (ATTR_UID | ATTR_GID)) |
1212 | error = setattr_chown(inode, attr); | 1250 | error = setattr_chown(inode, attr); |
1213 | else if ((attr->ia_valid & ATTR_MODE) && IS_POSIXACL(inode)) | 1251 | else if ((attr->ia_valid & ATTR_MODE) && IS_POSIXACL(inode)) |
1214 | error = gfs2_acl_chmod(ip, attr); | 1252 | error = gfs2_acl_chmod(ip, attr); |
1215 | else | 1253 | else |
1216 | error = gfs2_setattr_simple(ip, attr); | 1254 | error = gfs2_setattr_simple(ip, attr); |
1217 | 1255 | ||
1218 | out: | 1256 | out: |
1219 | gfs2_glock_dq_uninit(&i_gh); | 1257 | gfs2_glock_dq_uninit(&i_gh); |
1220 | if (!error) | 1258 | if (!error) |
1221 | mark_inode_dirty(inode); | 1259 | mark_inode_dirty(inode); |
1222 | return error; | 1260 | return error; |
1223 | } | 1261 | } |
1224 | 1262 | ||
1225 | /** | 1263 | /** |
1226 | * gfs2_getattr - Read out an inode's attributes | 1264 | * gfs2_getattr - Read out an inode's attributes |
1227 | * @mnt: The vfsmount the inode is being accessed from | 1265 | * @mnt: The vfsmount the inode is being accessed from |
1228 | * @dentry: The dentry to stat | 1266 | * @dentry: The dentry to stat |
1229 | * @stat: The inode's stats | 1267 | * @stat: The inode's stats |
1230 | * | 1268 | * |
1231 | * This may be called from the VFS directly, or from within GFS2 with the | 1269 | * This may be called from the VFS directly, or from within GFS2 with the |
1232 | * inode locked, so we look to see if the glock is already locked and only | 1270 | * inode locked, so we look to see if the glock is already locked and only |
1233 | * lock the glock if its not already been done. Note that its the NFS | 1271 | * lock the glock if its not already been done. Note that its the NFS |
1234 | * readdirplus operation which causes this to be called (from filldir) | 1272 | * readdirplus operation which causes this to be called (from filldir) |
1235 | * with the glock already held. | 1273 | * with the glock already held. |
1236 | * | 1274 | * |
1237 | * Returns: errno | 1275 | * Returns: errno |
1238 | */ | 1276 | */ |
1239 | 1277 | ||
1240 | static int gfs2_getattr(struct vfsmount *mnt, struct dentry *dentry, | 1278 | static int gfs2_getattr(struct vfsmount *mnt, struct dentry *dentry, |
1241 | struct kstat *stat) | 1279 | struct kstat *stat) |
1242 | { | 1280 | { |
1243 | struct inode *inode = dentry->d_inode; | 1281 | struct inode *inode = dentry->d_inode; |
1244 | struct gfs2_inode *ip = GFS2_I(inode); | 1282 | struct gfs2_inode *ip = GFS2_I(inode); |
1245 | struct gfs2_holder gh; | 1283 | struct gfs2_holder gh; |
1246 | int error; | 1284 | int error; |
1247 | int unlock = 0; | 1285 | int unlock = 0; |
1248 | 1286 | ||
1249 | if (gfs2_glock_is_locked_by_me(ip->i_gl) == NULL) { | 1287 | if (gfs2_glock_is_locked_by_me(ip->i_gl) == NULL) { |
1250 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh); | 1288 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh); |
1251 | if (error) | 1289 | if (error) |
1252 | return error; | 1290 | return error; |
1253 | unlock = 1; | 1291 | unlock = 1; |
1254 | } | 1292 | } |
1255 | 1293 | ||
1256 | generic_fillattr(inode, stat); | 1294 | generic_fillattr(inode, stat); |
1257 | if (unlock) | 1295 | if (unlock) |
1258 | gfs2_glock_dq_uninit(&gh); | 1296 | gfs2_glock_dq_uninit(&gh); |
1259 | 1297 | ||
1260 | return 0; | 1298 | return 0; |
1261 | } | 1299 | } |
1262 | 1300 | ||
1263 | static int gfs2_setxattr(struct dentry *dentry, const char *name, | 1301 | static int gfs2_setxattr(struct dentry *dentry, const char *name, |
1264 | const void *data, size_t size, int flags) | 1302 | const void *data, size_t size, int flags) |
1265 | { | 1303 | { |
1266 | struct inode *inode = dentry->d_inode; | 1304 | struct inode *inode = dentry->d_inode; |
1267 | struct gfs2_ea_request er; | 1305 | struct gfs2_ea_request er; |
1268 | 1306 | ||
1269 | memset(&er, 0, sizeof(struct gfs2_ea_request)); | 1307 | memset(&er, 0, sizeof(struct gfs2_ea_request)); |
1270 | er.er_type = gfs2_ea_name2type(name, &er.er_name); | 1308 | er.er_type = gfs2_ea_name2type(name, &er.er_name); |
1271 | if (er.er_type == GFS2_EATYPE_UNUSED) | 1309 | if (er.er_type == GFS2_EATYPE_UNUSED) |
1272 | return -EOPNOTSUPP; | 1310 | return -EOPNOTSUPP; |
1273 | er.er_data = (char *)data; | 1311 | er.er_data = (char *)data; |
1274 | er.er_name_len = strlen(er.er_name); | 1312 | er.er_name_len = strlen(er.er_name); |
1275 | er.er_data_len = size; | 1313 | er.er_data_len = size; |
1276 | er.er_flags = flags; | 1314 | er.er_flags = flags; |
1277 | 1315 | ||
1278 | gfs2_assert_warn(GFS2_SB(inode), !(er.er_flags & GFS2_ERF_MODE)); | 1316 | gfs2_assert_warn(GFS2_SB(inode), !(er.er_flags & GFS2_ERF_MODE)); |
1279 | 1317 | ||
1280 | return gfs2_ea_set(GFS2_I(inode), &er); | 1318 | return gfs2_ea_set(GFS2_I(inode), &er); |
1281 | } | 1319 | } |
1282 | 1320 | ||
1283 | static ssize_t gfs2_getxattr(struct dentry *dentry, const char *name, | 1321 | static ssize_t gfs2_getxattr(struct dentry *dentry, const char *name, |
1284 | void *data, size_t size) | 1322 | void *data, size_t size) |
1285 | { | 1323 | { |
1286 | struct gfs2_ea_request er; | 1324 | struct gfs2_ea_request er; |
1287 | 1325 | ||
1288 | memset(&er, 0, sizeof(struct gfs2_ea_request)); | 1326 | memset(&er, 0, sizeof(struct gfs2_ea_request)); |
1289 | er.er_type = gfs2_ea_name2type(name, &er.er_name); | 1327 | er.er_type = gfs2_ea_name2type(name, &er.er_name); |
1290 | if (er.er_type == GFS2_EATYPE_UNUSED) | 1328 | if (er.er_type == GFS2_EATYPE_UNUSED) |
1291 | return -EOPNOTSUPP; | 1329 | return -EOPNOTSUPP; |
1292 | er.er_data = data; | 1330 | er.er_data = data; |
1293 | er.er_name_len = strlen(er.er_name); | 1331 | er.er_name_len = strlen(er.er_name); |
1294 | er.er_data_len = size; | 1332 | er.er_data_len = size; |
1295 | 1333 | ||
1296 | return gfs2_ea_get(GFS2_I(dentry->d_inode), &er); | 1334 | return gfs2_ea_get(GFS2_I(dentry->d_inode), &er); |
1297 | } | 1335 | } |
1298 | 1336 | ||
1299 | static ssize_t gfs2_listxattr(struct dentry *dentry, char *buffer, size_t size) | 1337 | static ssize_t gfs2_listxattr(struct dentry *dentry, char *buffer, size_t size) |
1300 | { | 1338 | { |
1301 | struct gfs2_ea_request er; | 1339 | struct gfs2_ea_request er; |
1302 | 1340 | ||
1303 | memset(&er, 0, sizeof(struct gfs2_ea_request)); | 1341 | memset(&er, 0, sizeof(struct gfs2_ea_request)); |
1304 | er.er_data = (size) ? buffer : NULL; | 1342 | er.er_data = (size) ? buffer : NULL; |
1305 | er.er_data_len = size; | 1343 | er.er_data_len = size; |
1306 | 1344 | ||
1307 | return gfs2_ea_list(GFS2_I(dentry->d_inode), &er); | 1345 | return gfs2_ea_list(GFS2_I(dentry->d_inode), &er); |
1308 | } | 1346 | } |
1309 | 1347 | ||
1310 | static int gfs2_removexattr(struct dentry *dentry, const char *name) | 1348 | static int gfs2_removexattr(struct dentry *dentry, const char *name) |
1311 | { | 1349 | { |
1312 | struct gfs2_ea_request er; | 1350 | struct gfs2_ea_request er; |
1313 | 1351 | ||
1314 | memset(&er, 0, sizeof(struct gfs2_ea_request)); | 1352 | memset(&er, 0, sizeof(struct gfs2_ea_request)); |
1315 | er.er_type = gfs2_ea_name2type(name, &er.er_name); | 1353 | er.er_type = gfs2_ea_name2type(name, &er.er_name); |
1316 | if (er.er_type == GFS2_EATYPE_UNUSED) | 1354 | if (er.er_type == GFS2_EATYPE_UNUSED) |
1317 | return -EOPNOTSUPP; | 1355 | return -EOPNOTSUPP; |
1318 | er.er_name_len = strlen(er.er_name); | 1356 | er.er_name_len = strlen(er.er_name); |
1319 | 1357 | ||
1320 | return gfs2_ea_remove(GFS2_I(dentry->d_inode), &er); | 1358 | return gfs2_ea_remove(GFS2_I(dentry->d_inode), &er); |
1321 | } | 1359 | } |
1322 | 1360 | ||
1323 | static int gfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | 1361 | static int gfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, |
1324 | u64 start, u64 len) | 1362 | u64 start, u64 len) |
1325 | { | 1363 | { |
1326 | struct gfs2_inode *ip = GFS2_I(inode); | 1364 | struct gfs2_inode *ip = GFS2_I(inode); |
1327 | struct gfs2_holder gh; | 1365 | struct gfs2_holder gh; |
1328 | int ret; | 1366 | int ret; |
1329 | 1367 | ||
1330 | ret = fiemap_check_flags(fieinfo, FIEMAP_FLAG_SYNC); | 1368 | ret = fiemap_check_flags(fieinfo, FIEMAP_FLAG_SYNC); |
1331 | if (ret) | 1369 | if (ret) |
1332 | return ret; | 1370 | return ret; |
1333 | 1371 | ||
1334 | mutex_lock(&inode->i_mutex); | 1372 | mutex_lock(&inode->i_mutex); |
1335 | 1373 | ||
1336 | ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &gh); | 1374 | ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &gh); |
1337 | if (ret) | 1375 | if (ret) |
1338 | goto out; | 1376 | goto out; |
1339 | 1377 | ||
1340 | if (gfs2_is_stuffed(ip)) { | 1378 | if (gfs2_is_stuffed(ip)) { |
1341 | u64 phys = ip->i_no_addr << inode->i_blkbits; | 1379 | u64 phys = ip->i_no_addr << inode->i_blkbits; |
1342 | u64 size = i_size_read(inode); | 1380 | u64 size = i_size_read(inode); |
1343 | u32 flags = FIEMAP_EXTENT_LAST|FIEMAP_EXTENT_NOT_ALIGNED| | 1381 | u32 flags = FIEMAP_EXTENT_LAST|FIEMAP_EXTENT_NOT_ALIGNED| |
1344 | FIEMAP_EXTENT_DATA_INLINE; | 1382 | FIEMAP_EXTENT_DATA_INLINE; |
1345 | phys += sizeof(struct gfs2_dinode); | 1383 | phys += sizeof(struct gfs2_dinode); |
1346 | phys += start; | 1384 | phys += start; |
1347 | if (start + len > size) | 1385 | if (start + len > size) |
1348 | len = size - start; | 1386 | len = size - start; |
1349 | if (start < size) | 1387 | if (start < size) |
1350 | ret = fiemap_fill_next_extent(fieinfo, start, phys, | 1388 | ret = fiemap_fill_next_extent(fieinfo, start, phys, |
1351 | len, flags); | 1389 | len, flags); |
1352 | if (ret == 1) | 1390 | if (ret == 1) |
1353 | ret = 0; | 1391 | ret = 0; |
1354 | } else { | 1392 | } else { |
1355 | ret = __generic_block_fiemap(inode, fieinfo, start, len, | 1393 | ret = __generic_block_fiemap(inode, fieinfo, start, len, |
1356 | gfs2_block_map); | 1394 | gfs2_block_map); |
1357 | } | 1395 | } |
1358 | 1396 | ||
1359 | gfs2_glock_dq_uninit(&gh); | 1397 | gfs2_glock_dq_uninit(&gh); |
1360 | out: | 1398 | out: |
1361 | mutex_unlock(&inode->i_mutex); | 1399 | mutex_unlock(&inode->i_mutex); |
1362 | return ret; | 1400 | return ret; |
1363 | } | 1401 | } |
1364 | 1402 | ||
1365 | const struct inode_operations gfs2_file_iops = { | 1403 | const struct inode_operations gfs2_file_iops = { |
1366 | .permission = gfs2_permission, | 1404 | .permission = gfs2_permission, |
1367 | .setattr = gfs2_setattr, | 1405 | .setattr = gfs2_setattr, |
1368 | .getattr = gfs2_getattr, | 1406 | .getattr = gfs2_getattr, |
1369 | .setxattr = gfs2_setxattr, | 1407 | .setxattr = gfs2_setxattr, |
1370 | .getxattr = gfs2_getxattr, | 1408 | .getxattr = gfs2_getxattr, |
1371 | .listxattr = gfs2_listxattr, | 1409 | .listxattr = gfs2_listxattr, |
1372 | .removexattr = gfs2_removexattr, | 1410 | .removexattr = gfs2_removexattr, |
1373 | .fiemap = gfs2_fiemap, | 1411 | .fiemap = gfs2_fiemap, |
1374 | }; | 1412 | }; |
1375 | 1413 | ||
1376 | const struct inode_operations gfs2_dir_iops = { | 1414 | const struct inode_operations gfs2_dir_iops = { |
1377 | .create = gfs2_create, | 1415 | .create = gfs2_create, |
1378 | .lookup = gfs2_lookup, | 1416 | .lookup = gfs2_lookup, |
1379 | .link = gfs2_link, | 1417 | .link = gfs2_link, |
1380 | .unlink = gfs2_unlink, | 1418 | .unlink = gfs2_unlink, |
1381 | .symlink = gfs2_symlink, | 1419 | .symlink = gfs2_symlink, |
1382 | .mkdir = gfs2_mkdir, | 1420 | .mkdir = gfs2_mkdir, |
1383 | .rmdir = gfs2_rmdir, | 1421 | .rmdir = gfs2_rmdir, |
1384 | .mknod = gfs2_mknod, | 1422 | .mknod = gfs2_mknod, |
1385 | .rename = gfs2_rename, | 1423 | .rename = gfs2_rename, |
1386 | .permission = gfs2_permission, | 1424 | .permission = gfs2_permission, |
1387 | .setattr = gfs2_setattr, | 1425 | .setattr = gfs2_setattr, |
1388 | .getattr = gfs2_getattr, | 1426 | .getattr = gfs2_getattr, |
1389 | .setxattr = gfs2_setxattr, | 1427 | .setxattr = gfs2_setxattr, |
1390 | .getxattr = gfs2_getxattr, | 1428 | .getxattr = gfs2_getxattr, |
1391 | .listxattr = gfs2_listxattr, | 1429 | .listxattr = gfs2_listxattr, |
1392 | .removexattr = gfs2_removexattr, | 1430 | .removexattr = gfs2_removexattr, |
1393 | .fiemap = gfs2_fiemap, | 1431 | .fiemap = gfs2_fiemap, |
1394 | }; | 1432 | }; |
1395 | 1433 | ||
1396 | const struct inode_operations gfs2_symlink_iops = { | 1434 | const struct inode_operations gfs2_symlink_iops = { |
1397 | .readlink = gfs2_readlink, | 1435 | .readlink = gfs2_readlink, |
1398 | .follow_link = gfs2_follow_link, | 1436 | .follow_link = gfs2_follow_link, |
1399 | .permission = gfs2_permission, | 1437 | .permission = gfs2_permission, |
1400 | .setattr = gfs2_setattr, | 1438 | .setattr = gfs2_setattr, |
1401 | .getattr = gfs2_getattr, | 1439 | .getattr = gfs2_getattr, |
1402 | .setxattr = gfs2_setxattr, | 1440 | .setxattr = gfs2_setxattr, |
1403 | .getxattr = gfs2_getxattr, | 1441 | .getxattr = gfs2_getxattr, |
1404 | .listxattr = gfs2_listxattr, | 1442 | .listxattr = gfs2_listxattr, |
1405 | .removexattr = gfs2_removexattr, | 1443 | .removexattr = gfs2_removexattr, |
1406 | .fiemap = gfs2_fiemap, | 1444 | .fiemap = gfs2_fiemap, |
1407 | }; | 1445 | }; |
1408 | 1446 | ||
1409 | 1447 |