blob: 9084d6037a0cd2b1f74dcf65dfd55c262b22c80d [file] [log] [blame]
David Teiglandb3b94fa2006-01-16 16:50:04 +00001/*
2 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
3 * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
4 *
5 * This copyrighted material is made available to anyone wishing to use,
6 * modify, copy, or redistribute it subject to the terms and conditions
7 * of the GNU General Public License v.2.
8 */
9
10#include <linux/sched.h>
11#include <linux/slab.h>
12#include <linux/spinlock.h>
13#include <linux/completion.h>
14#include <linux/buffer_head.h>
15#include <linux/posix_acl.h>
16#include <linux/sort.h>
Steven Whitehouse5c676f62006-02-27 17:23:27 -050017#include <linux/gfs2_ondisk.h>
Steven Whitehouse71b86f52006-03-28 14:14:04 -050018#include <linux/crc32.h>
David Teiglandb3b94fa2006-01-16 16:50:04 +000019#include <asm/semaphore.h>
20
21#include "gfs2.h"
Steven Whitehouse5c676f62006-02-27 17:23:27 -050022#include "lm_interface.h"
23#include "incore.h"
David Teiglandb3b94fa2006-01-16 16:50:04 +000024#include "acl.h"
25#include "bmap.h"
26#include "dir.h"
27#include "eattr.h"
28#include "glock.h"
29#include "glops.h"
30#include "inode.h"
31#include "log.h"
32#include "meta_io.h"
33#include "ops_address.h"
34#include "ops_file.h"
35#include "ops_inode.h"
36#include "quota.h"
37#include "rgrp.h"
38#include "trans.h"
39#include "unlinked.h"
Steven Whitehouse5c676f62006-02-27 17:23:27 -050040#include "util.h"
David Teiglandb3b94fa2006-01-16 16:50:04 +000041
42/**
43 * inode_attr_in - Copy attributes from the dinode into the VFS inode
44 * @ip: The GFS2 inode (with embedded disk inode data)
45 * @inode: The Linux VFS inode
46 *
47 */
48
49static void inode_attr_in(struct gfs2_inode *ip, struct inode *inode)
50{
51 inode->i_ino = ip->i_num.no_formal_ino;
52
53 switch (ip->i_di.di_mode & S_IFMT) {
54 case S_IFBLK:
55 case S_IFCHR:
56 inode->i_rdev = MKDEV(ip->i_di.di_major, ip->i_di.di_minor);
57 break;
58 default:
59 inode->i_rdev = 0;
60 break;
61 };
62
63 inode->i_mode = ip->i_di.di_mode;
64 inode->i_nlink = ip->i_di.di_nlink;
65 inode->i_uid = ip->i_di.di_uid;
66 inode->i_gid = ip->i_di.di_gid;
67 i_size_write(inode, ip->i_di.di_size);
68 inode->i_atime.tv_sec = ip->i_di.di_atime;
69 inode->i_mtime.tv_sec = ip->i_di.di_mtime;
70 inode->i_ctime.tv_sec = ip->i_di.di_ctime;
71 inode->i_atime.tv_nsec = 0;
72 inode->i_mtime.tv_nsec = 0;
73 inode->i_ctime.tv_nsec = 0;
74 inode->i_blksize = PAGE_SIZE;
75 inode->i_blocks = ip->i_di.di_blocks <<
76 (ip->i_sbd->sd_sb.sb_bsize_shift - GFS2_BASIC_BLOCK_SHIFT);
77
78 if (ip->i_di.di_flags & GFS2_DIF_IMMUTABLE)
79 inode->i_flags |= S_IMMUTABLE;
80 else
81 inode->i_flags &= ~S_IMMUTABLE;
82
83 if (ip->i_di.di_flags & GFS2_DIF_APPENDONLY)
84 inode->i_flags |= S_APPEND;
85 else
86 inode->i_flags &= ~S_APPEND;
87}
88
89/**
90 * gfs2_inode_attr_in - Copy attributes from the dinode into the VFS inode
91 * @ip: The GFS2 inode (with embedded disk inode data)
92 *
93 */
94
95void gfs2_inode_attr_in(struct gfs2_inode *ip)
96{
97 struct inode *inode;
98
99 inode = gfs2_ip2v_lookup(ip);
100 if (inode) {
101 inode_attr_in(ip, inode);
102 iput(inode);
103 }
104}
105
106/**
107 * gfs2_inode_attr_out - Copy attributes from VFS inode into the dinode
108 * @ip: The GFS2 inode
109 *
110 * Only copy out the attributes that we want the VFS layer
111 * to be able to modify.
112 */
113
114void gfs2_inode_attr_out(struct gfs2_inode *ip)
115{
116 struct inode *inode = ip->i_vnode;
117
118 gfs2_assert_withdraw(ip->i_sbd,
119 (ip->i_di.di_mode & S_IFMT) == (inode->i_mode & S_IFMT));
120 ip->i_di.di_mode = inode->i_mode;
121 ip->i_di.di_uid = inode->i_uid;
122 ip->i_di.di_gid = inode->i_gid;
123 ip->i_di.di_atime = inode->i_atime.tv_sec;
124 ip->i_di.di_mtime = inode->i_mtime.tv_sec;
125 ip->i_di.di_ctime = inode->i_ctime.tv_sec;
126}
127
128/**
129 * gfs2_ip2v_lookup - Get the struct inode for a struct gfs2_inode
130 * @ip: the struct gfs2_inode to get the struct inode for
131 *
132 * Returns: A VFS inode, or NULL if none
133 */
134
135struct inode *gfs2_ip2v_lookup(struct gfs2_inode *ip)
136{
137 struct inode *inode = NULL;
138
139 gfs2_assert_warn(ip->i_sbd, test_bit(GIF_MIN_INIT, &ip->i_flags));
140
141 spin_lock(&ip->i_spin);
142 if (ip->i_vnode)
143 inode = igrab(ip->i_vnode);
144 spin_unlock(&ip->i_spin);
145
146 return inode;
147}
148
149/**
150 * gfs2_ip2v - Get/Create a struct inode for a struct gfs2_inode
151 * @ip: the struct gfs2_inode to get the struct inode for
152 *
153 * Returns: A VFS inode, or NULL if no mem
154 */
155
156struct inode *gfs2_ip2v(struct gfs2_inode *ip)
157{
158 struct inode *inode, *tmp;
159
160 inode = gfs2_ip2v_lookup(ip);
161 if (inode)
162 return inode;
163
164 tmp = new_inode(ip->i_sbd->sd_vfs);
165 if (!tmp)
166 return NULL;
167
168 inode_attr_in(ip, tmp);
169
170 if (S_ISREG(ip->i_di.di_mode)) {
171 tmp->i_op = &gfs2_file_iops;
172 tmp->i_fop = &gfs2_file_fops;
173 tmp->i_mapping->a_ops = &gfs2_file_aops;
174 } else if (S_ISDIR(ip->i_di.di_mode)) {
175 tmp->i_op = &gfs2_dir_iops;
176 tmp->i_fop = &gfs2_dir_fops;
177 } else if (S_ISLNK(ip->i_di.di_mode)) {
178 tmp->i_op = &gfs2_symlink_iops;
179 } else {
180 tmp->i_op = &gfs2_dev_iops;
181 init_special_inode(tmp, tmp->i_mode, tmp->i_rdev);
182 }
183
Steven Whitehouse5c676f62006-02-27 17:23:27 -0500184 tmp->u.generic_ip = NULL;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000185
186 for (;;) {
187 spin_lock(&ip->i_spin);
188 if (!ip->i_vnode)
189 break;
190 inode = igrab(ip->i_vnode);
191 spin_unlock(&ip->i_spin);
192
193 if (inode) {
194 iput(tmp);
195 return inode;
196 }
197 yield();
198 }
199
200 inode = tmp;
201
202 gfs2_inode_hold(ip);
203 ip->i_vnode = inode;
Steven Whitehouse5c676f62006-02-27 17:23:27 -0500204 inode->u.generic_ip = ip;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000205
206 spin_unlock(&ip->i_spin);
207
208 insert_inode_hash(inode);
209
210 return inode;
211}
212
213static int iget_test(struct inode *inode, void *opaque)
214{
Steven Whitehouse5c676f62006-02-27 17:23:27 -0500215 struct gfs2_inode *ip = inode->u.generic_ip;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000216 struct gfs2_inum *inum = (struct gfs2_inum *)opaque;
217
218 if (ip && ip->i_num.no_addr == inum->no_addr)
219 return 1;
220
221 return 0;
222}
223
224struct inode *gfs2_iget(struct super_block *sb, struct gfs2_inum *inum)
225{
226 return ilookup5(sb, (unsigned long)inum->no_formal_ino,
227 iget_test, inum);
228}
229
230void gfs2_inode_min_init(struct gfs2_inode *ip, unsigned int type)
231{
David Teiglandb3b94fa2006-01-16 16:50:04 +0000232 if (!test_and_set_bit(GIF_MIN_INIT, &ip->i_flags)) {
233 ip->i_di.di_nlink = 1;
234 ip->i_di.di_mode = DT2IF(type);
235 }
David Teiglandb3b94fa2006-01-16 16:50:04 +0000236}
237
238/**
239 * gfs2_inode_refresh - Refresh the incore copy of the dinode
240 * @ip: The GFS2 inode
241 *
242 * Returns: errno
243 */
244
245int gfs2_inode_refresh(struct gfs2_inode *ip)
246{
247 struct buffer_head *dibh;
248 int error;
249
250 error = gfs2_meta_inode_buffer(ip, &dibh);
251 if (error)
252 return error;
253
254 if (gfs2_metatype_check(ip->i_sbd, dibh, GFS2_METATYPE_DI)) {
255 brelse(dibh);
256 return -EIO;
257 }
258
David Teiglandb3b94fa2006-01-16 16:50:04 +0000259 gfs2_dinode_in(&ip->i_di, dibh->b_data);
260 set_bit(GIF_MIN_INIT, &ip->i_flags);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000261
262 brelse(dibh);
263
264 if (ip->i_num.no_addr != ip->i_di.di_num.no_addr) {
265 if (gfs2_consist_inode(ip))
266 gfs2_dinode_print(&ip->i_di);
267 return -EIO;
268 }
269 if (ip->i_num.no_formal_ino != ip->i_di.di_num.no_formal_ino)
270 return -ESTALE;
271
272 ip->i_vn = ip->i_gl->gl_vn;
273
274 return 0;
275}
276
277/**
278 * inode_create - create a struct gfs2_inode
279 * @i_gl: The glock covering the inode
280 * @inum: The inode number
281 * @io_gl: the iopen glock to acquire/hold (using holder in new gfs2_inode)
282 * @io_state: the state the iopen glock should be acquired in
283 * @ipp: pointer to put the returned inode in
284 *
285 * Returns: errno
286 */
287
Steven Whitehousec9fd4302006-03-01 15:31:02 -0500288static int inode_create(struct gfs2_glock *i_gl, const struct gfs2_inum *inum,
David Teiglandb3b94fa2006-01-16 16:50:04 +0000289 struct gfs2_glock *io_gl, unsigned int io_state,
Steven Whitehouse36327522006-04-28 10:46:21 -0400290 struct gfs2_inode **ipp, int need_lock)
David Teiglandb3b94fa2006-01-16 16:50:04 +0000291{
292 struct gfs2_sbd *sdp = i_gl->gl_sbd;
293 struct gfs2_inode *ip;
294 int error = 0;
295
296 ip = kmem_cache_alloc(gfs2_inode_cachep, GFP_KERNEL);
297 if (!ip)
298 return -ENOMEM;
299 memset(ip, 0, sizeof(struct gfs2_inode));
300
301 ip->i_num = *inum;
302
303 atomic_set(&ip->i_count, 1);
304
305 ip->i_vn = i_gl->gl_vn - 1;
306
307 ip->i_gl = i_gl;
308 ip->i_sbd = sdp;
309
310 spin_lock_init(&ip->i_spin);
311 init_rwsem(&ip->i_rw_mutex);
312
313 ip->i_greedy = gfs2_tune_get(sdp, gt_greedy_default);
314
Steven Whitehouse36327522006-04-28 10:46:21 -0400315 if (need_lock) {
316 error = gfs2_glock_nq_init(io_gl,
317 io_state, GL_LOCAL_EXCL | GL_EXACT,
318 &ip->i_iopen_gh);
319 if (error)
320 goto fail;
321 }
David Teiglandb3b94fa2006-01-16 16:50:04 +0000322 ip->i_iopen_gh.gh_owner = NULL;
323
324 spin_lock(&io_gl->gl_spin);
325 gfs2_glock_hold(i_gl);
Steven Whitehouse5c676f62006-02-27 17:23:27 -0500326 io_gl->gl_object = i_gl;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000327 spin_unlock(&io_gl->gl_spin);
328
329 gfs2_glock_hold(i_gl);
Steven Whitehouse5c676f62006-02-27 17:23:27 -0500330 i_gl->gl_object = ip;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000331
332 atomic_inc(&sdp->sd_inode_count);
333
334 *ipp = ip;
335
336 return 0;
337
338 fail:
339 gfs2_meta_cache_flush(ip);
340 kmem_cache_free(gfs2_inode_cachep, ip);
341 *ipp = NULL;
342
343 return error;
344}
345
346/**
347 * gfs2_inode_get - Create or get a reference on an inode
348 * @i_gl: The glock covering the inode
349 * @inum: The inode number
350 * @create:
351 * @ipp: pointer to put the returned inode in
352 *
353 * Returns: errno
354 */
355
Steven Whitehousec9fd4302006-03-01 15:31:02 -0500356int gfs2_inode_get(struct gfs2_glock *i_gl, const struct gfs2_inum *inum,
357 int create, struct gfs2_inode **ipp)
David Teiglandb3b94fa2006-01-16 16:50:04 +0000358{
359 struct gfs2_sbd *sdp = i_gl->gl_sbd;
360 struct gfs2_glock *io_gl;
361 int error = 0;
362
363 gfs2_glmutex_lock(i_gl);
364
Steven Whitehouse5c676f62006-02-27 17:23:27 -0500365 *ipp = i_gl->gl_object;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000366 if (*ipp) {
367 error = -ESTALE;
368 if ((*ipp)->i_num.no_formal_ino != inum->no_formal_ino)
369 goto out;
370 atomic_inc(&(*ipp)->i_count);
371 error = 0;
372 goto out;
373 }
374
375 if (!create)
376 goto out;
377
378 error = gfs2_glock_get(sdp, inum->no_addr, &gfs2_iopen_glops,
379 CREATE, &io_gl);
380 if (!error) {
Steven Whitehouse36327522006-04-28 10:46:21 -0400381 error = inode_create(i_gl, inum, io_gl, LM_ST_SHARED, ipp, 1);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000382 gfs2_glock_put(io_gl);
383 }
384
385 out:
386 gfs2_glmutex_unlock(i_gl);
387
388 return error;
389}
390
391void gfs2_inode_hold(struct gfs2_inode *ip)
392{
393 gfs2_assert(ip->i_sbd, atomic_read(&ip->i_count) > 0);
394 atomic_inc(&ip->i_count);
395}
396
397void gfs2_inode_put(struct gfs2_inode *ip)
398{
399 gfs2_assert(ip->i_sbd, atomic_read(&ip->i_count) > 0);
400 atomic_dec(&ip->i_count);
401}
402
Steven Whitehouse36327522006-04-28 10:46:21 -0400403void gfs2_inode_destroy(struct gfs2_inode *ip, int unlock)
David Teiglandb3b94fa2006-01-16 16:50:04 +0000404{
405 struct gfs2_sbd *sdp = ip->i_sbd;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000406 struct gfs2_glock *i_gl = ip->i_gl;
407
408 gfs2_assert_warn(sdp, !atomic_read(&ip->i_count));
Steven Whitehouse36327522006-04-28 10:46:21 -0400409 if (unlock) {
410 struct gfs2_glock *io_gl = ip->i_iopen_gh.gh_gl;
411 gfs2_assert(sdp, io_gl->gl_object == i_gl);
412
413 spin_lock(&io_gl->gl_spin);
414 io_gl->gl_object = NULL;
415 spin_unlock(&io_gl->gl_spin);
416 gfs2_glock_put(i_gl);
417
418 gfs2_glock_dq_uninit(&ip->i_iopen_gh);
419 }
David Teiglandb3b94fa2006-01-16 16:50:04 +0000420
421 gfs2_meta_cache_flush(ip);
422 kmem_cache_free(gfs2_inode_cachep, ip);
423
Steven Whitehouse5c676f62006-02-27 17:23:27 -0500424 i_gl->gl_object = NULL;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000425 gfs2_glock_put(i_gl);
426
427 atomic_dec(&sdp->sd_inode_count);
428}
429
430static int dinode_dealloc(struct gfs2_inode *ip, struct gfs2_unlinked *ul)
431{
432 struct gfs2_sbd *sdp = ip->i_sbd;
433 struct gfs2_alloc *al;
434 struct gfs2_rgrpd *rgd;
435 int error;
436
437 if (ip->i_di.di_blocks != 1) {
438 if (gfs2_consist_inode(ip))
439 gfs2_dinode_print(&ip->i_di);
440 return -EIO;
441 }
442
443 al = gfs2_alloc_get(ip);
444
445 error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
446 if (error)
447 goto out;
448
449 error = gfs2_rindex_hold(sdp, &al->al_ri_gh);
450 if (error)
451 goto out_qs;
452
453 rgd = gfs2_blk2rgrpd(sdp, ip->i_num.no_addr);
454 if (!rgd) {
455 gfs2_consist_inode(ip);
456 error = -EIO;
457 goto out_rindex_relse;
458 }
459
460 error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0,
461 &al->al_rgd_gh);
462 if (error)
463 goto out_rindex_relse;
464
465 error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_UNLINKED +
466 RES_STATFS + RES_QUOTA, 1);
467 if (error)
468 goto out_rg_gunlock;
469
470 gfs2_trans_add_gl(ip->i_gl);
471
472 gfs2_free_di(rgd, ip);
473
474 error = gfs2_unlinked_ondisk_rm(sdp, ul);
475
476 gfs2_trans_end(sdp);
477 clear_bit(GLF_STICKY, &ip->i_gl->gl_flags);
478
479 out_rg_gunlock:
480 gfs2_glock_dq_uninit(&al->al_rgd_gh);
481
482 out_rindex_relse:
483 gfs2_glock_dq_uninit(&al->al_ri_gh);
484
485 out_qs:
486 gfs2_quota_unhold(ip);
487
488 out:
489 gfs2_alloc_put(ip);
490
491 return error;
492}
493
494/**
495 * inode_dealloc - Deallocate all on-disk blocks for an inode (dinode)
496 * @sdp: the filesystem
497 * @inum: the inode number to deallocate
498 * @io_gh: a holder for the iopen glock for this inode
499 *
Steven Whitehouse36327522006-04-28 10:46:21 -0400500 * N.B. When we enter this we already hold the iopen glock and getting
501 * the glock for the inode means that we are grabbing the locks in the
502 * "wrong" order so we must only so a try lock operation and fail if we
503 * don't get the lock. Thats ok, since if we fail it means someone else
504 * is using the inode still and thus we shouldn't be deallocating it
505 * anyway.
506 *
David Teiglandb3b94fa2006-01-16 16:50:04 +0000507 * Returns: errno
508 */
509
510static int inode_dealloc(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul,
511 struct gfs2_holder *io_gh)
512{
513 struct gfs2_inode *ip;
514 struct gfs2_holder i_gh;
515 int error;
516
Steven Whitehouse36327522006-04-28 10:46:21 -0400517 error = gfs2_glock_nq_num(sdp, ul->ul_ut.ut_inum.no_addr,
518 &gfs2_inode_glops, LM_ST_EXCLUSIVE,
519 LM_FLAG_TRY_1CB, &i_gh);
520 switch(error) {
David Teiglandb3b94fa2006-01-16 16:50:04 +0000521 case 0:
522 break;
523 case GLR_TRYFAILED:
Steven Whitehouse36327522006-04-28 10:46:21 -0400524 return 1; /* or back off and relock in different order? */
David Teiglandb3b94fa2006-01-16 16:50:04 +0000525 default:
Steven Whitehouse36327522006-04-28 10:46:21 -0400526 return error;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000527 }
528
Steven Whitehouse5c676f62006-02-27 17:23:27 -0500529 gfs2_assert_warn(sdp, !i_gh.gh_gl->gl_object);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000530 error = inode_create(i_gh.gh_gl, &ul->ul_ut.ut_inum, io_gh->gh_gl,
Steven Whitehouse36327522006-04-28 10:46:21 -0400531 LM_ST_EXCLUSIVE, &ip, 0);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000532
533 if (error)
534 goto out;
535
536 error = gfs2_inode_refresh(ip);
537 if (error)
538 goto out_iput;
539
540 if (ip->i_di.di_nlink) {
541 if (gfs2_consist_inode(ip))
542 gfs2_dinode_print(&ip->i_di);
543 error = -EIO;
544 goto out_iput;
545 }
546
547 if (S_ISDIR(ip->i_di.di_mode) &&
548 (ip->i_di.di_flags & GFS2_DIF_EXHASH)) {
549 error = gfs2_dir_exhash_dealloc(ip);
550 if (error)
551 goto out_iput;
552 }
553
554 if (ip->i_di.di_eattr) {
555 error = gfs2_ea_dealloc(ip);
556 if (error)
557 goto out_iput;
558 }
559
560 if (!gfs2_is_stuffed(ip)) {
561 error = gfs2_file_dealloc(ip);
562 if (error)
563 goto out_iput;
564 }
565
566 error = dinode_dealloc(ip, ul);
567 if (error)
568 goto out_iput;
569
Steven Whitehouse36327522006-04-28 10:46:21 -0400570out_iput:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000571 gfs2_glmutex_lock(i_gh.gh_gl);
572 gfs2_inode_put(ip);
Steven Whitehouse36327522006-04-28 10:46:21 -0400573 gfs2_inode_destroy(ip, 0);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000574 gfs2_glmutex_unlock(i_gh.gh_gl);
575
Steven Whitehouse36327522006-04-28 10:46:21 -0400576out:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000577 gfs2_glock_dq_uninit(&i_gh);
578
579 return error;
580}
581
582/**
583 * try_inode_dealloc - Try to deallocate an inode and all its blocks
584 * @sdp: the filesystem
585 *
586 * Returns: 0 on success, -errno on error, 1 on busy (inode open)
587 */
588
589static int try_inode_dealloc(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
590{
David Teiglandb3b94fa2006-01-16 16:50:04 +0000591 int error = 0;
Steven Whitehouse36327522006-04-28 10:46:21 -0400592 struct gfs2_holder iogh;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000593
594 gfs2_try_toss_inode(sdp, &ul->ul_ut.ut_inum);
Steven Whitehouse36327522006-04-28 10:46:21 -0400595 error = gfs2_glock_nq_num(sdp, ul->ul_ut.ut_inum.no_addr,
596 &gfs2_iopen_glops, LM_ST_EXCLUSIVE,
597 LM_FLAG_TRY_1CB, &iogh);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000598 switch (error) {
599 case 0:
600 break;
601 case GLR_TRYFAILED:
602 return 1;
603 default:
604 return error;
605 }
606
Steven Whitehouse36327522006-04-28 10:46:21 -0400607 error = inode_dealloc(sdp, ul, &iogh);
608 gfs2_glock_dq_uninit(&iogh);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000609
610 return error;
611}
612
613static int inode_dealloc_uninit(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
614{
615 struct gfs2_rgrpd *rgd;
616 struct gfs2_holder ri_gh, rgd_gh;
617 int error;
618
619 error = gfs2_rindex_hold(sdp, &ri_gh);
620 if (error)
621 return error;
622
623 rgd = gfs2_blk2rgrpd(sdp, ul->ul_ut.ut_inum.no_addr);
624 if (!rgd) {
625 gfs2_consist(sdp);
626 error = -EIO;
627 goto out;
628 }
629
630 error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, &rgd_gh);
631 if (error)
632 goto out;
633
Steven Whitehouse36327522006-04-28 10:46:21 -0400634 error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_UNLINKED + RES_STATFS, 0);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000635 if (error)
636 goto out_gunlock;
637
638 gfs2_free_uninit_di(rgd, ul->ul_ut.ut_inum.no_addr);
639 gfs2_unlinked_ondisk_rm(sdp, ul);
640
641 gfs2_trans_end(sdp);
642
643 out_gunlock:
644 gfs2_glock_dq_uninit(&rgd_gh);
645 out:
646 gfs2_glock_dq_uninit(&ri_gh);
647
648 return error;
649}
650
651int gfs2_inode_dealloc(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
652{
653 if (ul->ul_ut.ut_flags & GFS2_UTF_UNINIT)
654 return inode_dealloc_uninit(sdp, ul);
655 else
656 return try_inode_dealloc(sdp, ul);
657}
658
659/**
660 * gfs2_change_nlink - Change nlink count on inode
661 * @ip: The GFS2 inode
662 * @diff: The change in the nlink count required
663 *
664 * Returns: errno
665 */
666
667int gfs2_change_nlink(struct gfs2_inode *ip, int diff)
668{
669 struct buffer_head *dibh;
670 uint32_t nlink;
671 int error;
672
673 nlink = ip->i_di.di_nlink + diff;
674
675 /* If we are reducing the nlink count, but the new value ends up being
676 bigger than the old one, we must have underflowed. */
677 if (diff < 0 && nlink > ip->i_di.di_nlink) {
678 if (gfs2_consist_inode(ip))
679 gfs2_dinode_print(&ip->i_di);
680 return -EIO;
681 }
682
683 error = gfs2_meta_inode_buffer(ip, &dibh);
684 if (error)
685 return error;
686
687 ip->i_di.di_nlink = nlink;
688 ip->i_di.di_ctime = get_seconds();
689
Steven Whitehoused4e9c4c2006-01-18 11:19:28 +0000690 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000691 gfs2_dinode_out(&ip->i_di, dibh->b_data);
692 brelse(dibh);
693
694 return 0;
695}
696
Steven Whitehousec7526662006-03-20 12:30:04 -0500697struct inode *gfs2_lookup_simple(struct inode *dip, const char *name)
698{
699 struct qstr qstr;
Steven Whitehouse71b86f52006-03-28 14:14:04 -0500700 gfs2_str2qstr(&qstr, name);
Steven Whitehousec7526662006-03-20 12:30:04 -0500701 return gfs2_lookupi(dip, &qstr, 1, NULL);
702}
703
704
David Teiglandb3b94fa2006-01-16 16:50:04 +0000705/**
706 * gfs2_lookupi - Look up a filename in a directory and return its inode
707 * @d_gh: An initialized holder for the directory glock
708 * @name: The name of the inode to look for
709 * @is_root: If 1, ignore the caller's permissions
710 * @i_gh: An uninitialized holder for the new inode glock
711 *
712 * There will always be a vnode (Linux VFS inode) for the d_gh inode unless
713 * @is_root is true.
714 *
715 * Returns: errno
716 */
717
Steven Whitehousec7526662006-03-20 12:30:04 -0500718struct inode *gfs2_lookupi(struct inode *dir, struct qstr *name, int is_root,
719 struct nameidata *nd)
720
David Teiglandb3b94fa2006-01-16 16:50:04 +0000721{
Steven Whitehousec9fd4302006-03-01 15:31:02 -0500722 struct super_block *sb = dir->i_sb;
Steven Whitehouse7359a192006-02-13 12:27:43 +0000723 struct gfs2_inode *ipp;
Steven Whitehouse5c676f62006-02-27 17:23:27 -0500724 struct gfs2_inode *dip = dir->u.generic_ip;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000725 struct gfs2_sbd *sdp = dip->i_sbd;
726 struct gfs2_holder d_gh;
727 struct gfs2_inum inum;
728 unsigned int type;
729 struct gfs2_glock *gl;
Steven Whitehouse7359a192006-02-13 12:27:43 +0000730 int error = 0;
Steven Whitehousec7526662006-03-20 12:30:04 -0500731 struct inode *inode = NULL;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000732
733 if (!name->len || name->len > GFS2_FNAMESIZE)
Steven Whitehousec7526662006-03-20 12:30:04 -0500734 return ERR_PTR(-ENAMETOOLONG);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000735
Steven Whitehousec7526662006-03-20 12:30:04 -0500736 if ((name->len == 1 && memcmp(name->name, ".", 1) == 0) ||
737 (name->len == 2 && memcmp(name->name, "..", 2) == 0 &&
738 dir == sb->s_root->d_inode)) {
David Teiglandb3b94fa2006-01-16 16:50:04 +0000739 gfs2_inode_hold(dip);
Steven Whitehouse7359a192006-02-13 12:27:43 +0000740 ipp = dip;
741 goto done;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000742 }
743
744 error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &d_gh);
745 if (error)
Steven Whitehousec7526662006-03-20 12:30:04 -0500746 return ERR_PTR(error);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000747
748 if (!is_root) {
749 error = gfs2_repermission(dip->i_vnode, MAY_EXEC, NULL);
750 if (error)
751 goto out;
752 }
753
Steven Whitehousec7526662006-03-20 12:30:04 -0500754 error = gfs2_dir_search(dir, name, &inum, &type);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000755 if (error)
756 goto out;
757
758 error = gfs2_glock_get(sdp, inum.no_addr, &gfs2_inode_glops,
759 CREATE, &gl);
760 if (error)
761 goto out;
762
Steven Whitehouse7359a192006-02-13 12:27:43 +0000763 error = gfs2_inode_get(gl, &inum, CREATE, &ipp);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000764 if (!error)
Steven Whitehouse7359a192006-02-13 12:27:43 +0000765 gfs2_inode_min_init(ipp, type);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000766
767 gfs2_glock_put(gl);
768
Steven Whitehouse7359a192006-02-13 12:27:43 +0000769out:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000770 gfs2_glock_dq_uninit(&d_gh);
Steven Whitehouse7359a192006-02-13 12:27:43 +0000771done:
Steven Whitehousec7526662006-03-20 12:30:04 -0500772 if (error == -ENOENT)
773 return NULL;
Steven Whitehouse7359a192006-02-13 12:27:43 +0000774 if (error == 0) {
Steven Whitehousec7526662006-03-20 12:30:04 -0500775 inode = gfs2_ip2v(ipp);
Steven Whitehouse7359a192006-02-13 12:27:43 +0000776 gfs2_inode_put(ipp);
Steven Whitehousec7526662006-03-20 12:30:04 -0500777 if (!inode)
778 return ERR_PTR(-ENOMEM);
779 return inode;
Steven Whitehouse7359a192006-02-13 12:27:43 +0000780 }
Steven Whitehousec7526662006-03-20 12:30:04 -0500781 return ERR_PTR(error);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000782}
783
784static int pick_formal_ino_1(struct gfs2_sbd *sdp, uint64_t *formal_ino)
785{
Steven Whitehouse5c676f62006-02-27 17:23:27 -0500786 struct gfs2_inode *ip = sdp->sd_ir_inode->u.generic_ip;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000787 struct buffer_head *bh;
788 struct gfs2_inum_range ir;
789 int error;
790
791 error = gfs2_trans_begin(sdp, RES_DINODE, 0);
792 if (error)
793 return error;
Steven Whitehousef55ab262006-02-21 12:51:39 +0000794 mutex_lock(&sdp->sd_inum_mutex);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000795
796 error = gfs2_meta_inode_buffer(ip, &bh);
797 if (error) {
Steven Whitehousef55ab262006-02-21 12:51:39 +0000798 mutex_unlock(&sdp->sd_inum_mutex);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000799 gfs2_trans_end(sdp);
800 return error;
801 }
802
803 gfs2_inum_range_in(&ir, bh->b_data + sizeof(struct gfs2_dinode));
804
805 if (ir.ir_length) {
806 *formal_ino = ir.ir_start++;
807 ir.ir_length--;
Steven Whitehoused4e9c4c2006-01-18 11:19:28 +0000808 gfs2_trans_add_bh(ip->i_gl, bh, 1);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000809 gfs2_inum_range_out(&ir,
810 bh->b_data + sizeof(struct gfs2_dinode));
811 brelse(bh);
Steven Whitehousef55ab262006-02-21 12:51:39 +0000812 mutex_unlock(&sdp->sd_inum_mutex);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000813 gfs2_trans_end(sdp);
814 return 0;
815 }
816
817 brelse(bh);
818
Steven Whitehousef55ab262006-02-21 12:51:39 +0000819 mutex_unlock(&sdp->sd_inum_mutex);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000820 gfs2_trans_end(sdp);
821
822 return 1;
823}
824
825static int pick_formal_ino_2(struct gfs2_sbd *sdp, uint64_t *formal_ino)
826{
Steven Whitehouse5c676f62006-02-27 17:23:27 -0500827 struct gfs2_inode *ip = sdp->sd_ir_inode->u.generic_ip;
828 struct gfs2_inode *m_ip = sdp->sd_inum_inode->u.generic_ip;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000829 struct gfs2_holder gh;
830 struct buffer_head *bh;
831 struct gfs2_inum_range ir;
832 int error;
833
834 error = gfs2_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
835 if (error)
836 return error;
837
838 error = gfs2_trans_begin(sdp, 2 * RES_DINODE, 0);
839 if (error)
840 goto out;
Steven Whitehousef55ab262006-02-21 12:51:39 +0000841 mutex_lock(&sdp->sd_inum_mutex);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000842
843 error = gfs2_meta_inode_buffer(ip, &bh);
844 if (error)
845 goto out_end_trans;
846
847 gfs2_inum_range_in(&ir, bh->b_data + sizeof(struct gfs2_dinode));
848
849 if (!ir.ir_length) {
850 struct buffer_head *m_bh;
851 uint64_t x, y;
852
853 error = gfs2_meta_inode_buffer(m_ip, &m_bh);
854 if (error)
855 goto out_brelse;
856
857 x = *(uint64_t *)(m_bh->b_data + sizeof(struct gfs2_dinode));
858 x = y = be64_to_cpu(x);
859 ir.ir_start = x;
860 ir.ir_length = GFS2_INUM_QUANTUM;
861 x += GFS2_INUM_QUANTUM;
862 if (x < y)
863 gfs2_consist_inode(m_ip);
864 x = cpu_to_be64(x);
Steven Whitehoused4e9c4c2006-01-18 11:19:28 +0000865 gfs2_trans_add_bh(m_ip->i_gl, m_bh, 1);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000866 *(uint64_t *)(m_bh->b_data + sizeof(struct gfs2_dinode)) = x;
867
868 brelse(m_bh);
869 }
870
871 *formal_ino = ir.ir_start++;
872 ir.ir_length--;
873
Steven Whitehoused4e9c4c2006-01-18 11:19:28 +0000874 gfs2_trans_add_bh(ip->i_gl, bh, 1);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000875 gfs2_inum_range_out(&ir, bh->b_data + sizeof(struct gfs2_dinode));
876
877 out_brelse:
878 brelse(bh);
879
880 out_end_trans:
Steven Whitehousef55ab262006-02-21 12:51:39 +0000881 mutex_unlock(&sdp->sd_inum_mutex);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000882 gfs2_trans_end(sdp);
883
884 out:
885 gfs2_glock_dq_uninit(&gh);
886
887 return error;
888}
889
890static int pick_formal_ino(struct gfs2_sbd *sdp, uint64_t *inum)
891{
892 int error;
893
894 error = pick_formal_ino_1(sdp, inum);
895 if (error <= 0)
896 return error;
897
898 error = pick_formal_ino_2(sdp, inum);
899
900 return error;
901}
902
903/**
904 * create_ok - OK to create a new on-disk inode here?
905 * @dip: Directory in which dinode is to be created
906 * @name: Name of new dinode
907 * @mode:
908 *
909 * Returns: errno
910 */
911
912static int create_ok(struct gfs2_inode *dip, struct qstr *name,
913 unsigned int mode)
914{
915 int error;
916
917 error = gfs2_repermission(dip->i_vnode, MAY_WRITE | MAY_EXEC, NULL);
918 if (error)
919 return error;
920
921 /* Don't create entries in an unlinked directory */
922 if (!dip->i_di.di_nlink)
923 return -EPERM;
924
Steven Whitehousec7526662006-03-20 12:30:04 -0500925 error = gfs2_dir_search(dip->i_vnode, name, NULL, NULL);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000926 switch (error) {
927 case -ENOENT:
928 error = 0;
929 break;
930 case 0:
931 return -EEXIST;
932 default:
933 return error;
934 }
935
936 if (dip->i_di.di_entries == (uint32_t)-1)
937 return -EFBIG;
938 if (S_ISDIR(mode) && dip->i_di.di_nlink == (uint32_t)-1)
939 return -EMLINK;
940
941 return 0;
942}
943
944static void munge_mode_uid_gid(struct gfs2_inode *dip, unsigned int *mode,
945 unsigned int *uid, unsigned int *gid)
946{
947 if (dip->i_sbd->sd_args.ar_suiddir &&
948 (dip->i_di.di_mode & S_ISUID) &&
949 dip->i_di.di_uid) {
950 if (S_ISDIR(*mode))
951 *mode |= S_ISUID;
952 else if (dip->i_di.di_uid != current->fsuid)
953 *mode &= ~07111;
954 *uid = dip->i_di.di_uid;
955 } else
956 *uid = current->fsuid;
957
958 if (dip->i_di.di_mode & S_ISGID) {
959 if (S_ISDIR(*mode))
960 *mode |= S_ISGID;
961 *gid = dip->i_di.di_gid;
962 } else
963 *gid = current->fsgid;
964}
965
966static int alloc_dinode(struct gfs2_inode *dip, struct gfs2_unlinked *ul)
967{
968 struct gfs2_sbd *sdp = dip->i_sbd;
969 int error;
970
971 gfs2_alloc_get(dip);
972
973 dip->i_alloc.al_requested = RES_DINODE;
974 error = gfs2_inplace_reserve(dip);
975 if (error)
976 goto out;
977
978 error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_UNLINKED +
979 RES_STATFS, 0);
980 if (error)
981 goto out_ipreserv;
982
983 ul->ul_ut.ut_inum.no_addr = gfs2_alloc_di(dip);
984
985 ul->ul_ut.ut_flags = GFS2_UTF_UNINIT;
986 error = gfs2_unlinked_ondisk_add(sdp, ul);
987
988 gfs2_trans_end(sdp);
989
990 out_ipreserv:
991 gfs2_inplace_release(dip);
992
993 out:
994 gfs2_alloc_put(dip);
995
996 return error;
997}
998
999/**
1000 * init_dinode - Fill in a new dinode structure
1001 * @dip: the directory this inode is being created in
1002 * @gl: The glock covering the new inode
1003 * @inum: the inode number
1004 * @mode: the file permissions
1005 * @uid:
1006 * @gid:
1007 *
1008 */
1009
1010static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl,
1011 struct gfs2_inum *inum, unsigned int mode,
1012 unsigned int uid, unsigned int gid)
1013{
1014 struct gfs2_sbd *sdp = dip->i_sbd;
Steven Whitehouseb96ca4f2006-01-18 10:57:10 +00001015 struct gfs2_dinode *di;
David Teiglandb3b94fa2006-01-16 16:50:04 +00001016 struct buffer_head *dibh;
1017
1018 dibh = gfs2_meta_new(gl, inum->no_addr);
Steven Whitehoused4e9c4c2006-01-18 11:19:28 +00001019 gfs2_trans_add_bh(gl, dibh, 1);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001020 gfs2_metatype_set(dibh, GFS2_METATYPE_DI, GFS2_FORMAT_DI);
1021 gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode));
Steven Whitehouseb96ca4f2006-01-18 10:57:10 +00001022 di = (struct gfs2_dinode *)dibh->b_data;
David Teiglandb3b94fa2006-01-16 16:50:04 +00001023
Steven Whitehouse2442a092006-01-30 11:49:32 +00001024 di->di_num.no_formal_ino = cpu_to_be64(inum->no_formal_ino);
1025 di->di_num.no_addr = cpu_to_be64(inum->no_addr);
Steven Whitehouseb96ca4f2006-01-18 10:57:10 +00001026 di->di_mode = cpu_to_be32(mode);
1027 di->di_uid = cpu_to_be32(uid);
1028 di->di_gid = cpu_to_be32(gid);
1029 di->di_nlink = cpu_to_be32(0);
1030 di->di_size = cpu_to_be64(0);
1031 di->di_blocks = cpu_to_be64(1);
1032 di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(get_seconds());
1033 di->di_major = di->di_minor = cpu_to_be32(0);
1034 di->di_goal_meta = di->di_goal_data = cpu_to_be64(inum->no_addr);
1035 di->__pad[0] = di->__pad[1] = 0;
1036 di->di_flags = cpu_to_be32(0);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001037
1038 if (S_ISREG(mode)) {
1039 if ((dip->i_di.di_flags & GFS2_DIF_INHERIT_JDATA) ||
1040 gfs2_tune_get(sdp, gt_new_files_jdata))
Steven Whitehouseb96ca4f2006-01-18 10:57:10 +00001041 di->di_flags |= cpu_to_be32(GFS2_DIF_JDATA);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001042 if ((dip->i_di.di_flags & GFS2_DIF_INHERIT_DIRECTIO) ||
1043 gfs2_tune_get(sdp, gt_new_files_directio))
Steven Whitehouseb96ca4f2006-01-18 10:57:10 +00001044 di->di_flags |= cpu_to_be32(GFS2_DIF_DIRECTIO);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001045 } else if (S_ISDIR(mode)) {
Steven Whitehouse568f4c92006-02-27 12:00:42 -05001046 di->di_flags |= cpu_to_be32(dip->i_di.di_flags &
1047 GFS2_DIF_INHERIT_DIRECTIO);
1048 di->di_flags |= cpu_to_be32(dip->i_di.di_flags &
1049 GFS2_DIF_INHERIT_JDATA);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001050 }
1051
Steven Whitehouseb96ca4f2006-01-18 10:57:10 +00001052 di->__pad1 = 0;
1053 di->di_height = cpu_to_be32(0);
1054 di->__pad2 = 0;
1055 di->__pad3 = 0;
1056 di->di_depth = cpu_to_be16(0);
1057 di->di_entries = cpu_to_be32(0);
1058 memset(&di->__pad4, 0, sizeof(di->__pad4));
1059 di->di_eattr = cpu_to_be64(0);
1060 memset(&di->di_reserved, 0, sizeof(di->di_reserved));
1061
David Teiglandb3b94fa2006-01-16 16:50:04 +00001062 brelse(dibh);
1063}
1064
1065static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl,
1066 unsigned int mode, struct gfs2_unlinked *ul)
1067{
1068 struct gfs2_sbd *sdp = dip->i_sbd;
1069 unsigned int uid, gid;
1070 int error;
1071
1072 munge_mode_uid_gid(dip, &mode, &uid, &gid);
1073
1074 gfs2_alloc_get(dip);
1075
1076 error = gfs2_quota_lock(dip, uid, gid);
1077 if (error)
1078 goto out;
1079
1080 error = gfs2_quota_check(dip, uid, gid);
1081 if (error)
1082 goto out_quota;
1083
1084 error = gfs2_trans_begin(sdp, RES_DINODE + RES_UNLINKED +
1085 RES_QUOTA, 0);
1086 if (error)
1087 goto out_quota;
1088
1089 ul->ul_ut.ut_flags = 0;
1090 error = gfs2_unlinked_ondisk_munge(sdp, ul);
1091
1092 init_dinode(dip, gl, &ul->ul_ut.ut_inum,
1093 mode, uid, gid);
1094
1095 gfs2_quota_change(dip, +1, uid, gid);
1096
1097 gfs2_trans_end(sdp);
1098
1099 out_quota:
1100 gfs2_quota_unlock(dip);
1101
1102 out:
1103 gfs2_alloc_put(dip);
1104
1105 return error;
1106}
1107
1108static int link_dinode(struct gfs2_inode *dip, struct qstr *name,
1109 struct gfs2_inode *ip, struct gfs2_unlinked *ul)
1110{
1111 struct gfs2_sbd *sdp = dip->i_sbd;
1112 struct gfs2_alloc *al;
1113 int alloc_required;
1114 struct buffer_head *dibh;
1115 int error;
1116
1117 al = gfs2_alloc_get(dip);
1118
1119 error = gfs2_quota_lock(dip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
1120 if (error)
1121 goto fail;
1122
Steven Whitehousec7526662006-03-20 12:30:04 -05001123 error = alloc_required = gfs2_diradd_alloc_required(dip->i_vnode, name);
1124 if (alloc_required < 0)
1125 goto fail;
David Teiglandb3b94fa2006-01-16 16:50:04 +00001126 if (alloc_required) {
1127 error = gfs2_quota_check(dip, dip->i_di.di_uid,
1128 dip->i_di.di_gid);
1129 if (error)
1130 goto fail_quota_locks;
1131
1132 al->al_requested = sdp->sd_max_dirres;
1133
1134 error = gfs2_inplace_reserve(dip);
1135 if (error)
1136 goto fail_quota_locks;
1137
1138 error = gfs2_trans_begin(sdp,
1139 sdp->sd_max_dirres +
1140 al->al_rgd->rd_ri.ri_length +
1141 2 * RES_DINODE + RES_UNLINKED +
1142 RES_STATFS + RES_QUOTA, 0);
1143 if (error)
1144 goto fail_ipreserv;
1145 } else {
1146 error = gfs2_trans_begin(sdp,
1147 RES_LEAF +
1148 2 * RES_DINODE +
1149 RES_UNLINKED, 0);
1150 if (error)
1151 goto fail_quota_locks;
1152 }
1153
Steven Whitehousec7526662006-03-20 12:30:04 -05001154 error = gfs2_dir_add(dip->i_vnode, name, &ip->i_num, IF2DT(ip->i_di.di_mode));
David Teiglandb3b94fa2006-01-16 16:50:04 +00001155 if (error)
1156 goto fail_end_trans;
1157
1158 error = gfs2_meta_inode_buffer(ip, &dibh);
1159 if (error)
1160 goto fail_end_trans;
1161 ip->i_di.di_nlink = 1;
Steven Whitehoused4e9c4c2006-01-18 11:19:28 +00001162 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001163 gfs2_dinode_out(&ip->i_di, dibh->b_data);
1164 brelse(dibh);
1165
1166 error = gfs2_unlinked_ondisk_rm(sdp, ul);
1167 if (error)
1168 goto fail_end_trans;
1169
1170 return 0;
1171
1172 fail_end_trans:
1173 gfs2_trans_end(sdp);
1174
1175 fail_ipreserv:
1176 if (dip->i_alloc.al_rgd)
1177 gfs2_inplace_release(dip);
1178
1179 fail_quota_locks:
1180 gfs2_quota_unlock(dip);
1181
1182 fail:
1183 gfs2_alloc_put(dip);
1184
1185 return error;
1186}
1187
1188/**
1189 * gfs2_createi - Create a new inode
1190 * @ghs: An array of two holders
1191 * @name: The name of the new file
1192 * @mode: the permissions on the new inode
1193 *
1194 * @ghs[0] is an initialized holder for the directory
1195 * @ghs[1] is the holder for the inode lock
1196 *
Steven Whitehouse7359a192006-02-13 12:27:43 +00001197 * If the return value is not NULL, the glocks on both the directory and the new
David Teiglandb3b94fa2006-01-16 16:50:04 +00001198 * file are held. A transaction has been started and an inplace reservation
1199 * is held, as well.
1200 *
Steven Whitehouse7359a192006-02-13 12:27:43 +00001201 * Returns: An inode
David Teiglandb3b94fa2006-01-16 16:50:04 +00001202 */
1203
Steven Whitehouse568f4c92006-02-27 12:00:42 -05001204struct inode *gfs2_createi(struct gfs2_holder *ghs, struct qstr *name,
1205 unsigned int mode)
David Teiglandb3b94fa2006-01-16 16:50:04 +00001206{
Steven Whitehouse7359a192006-02-13 12:27:43 +00001207 struct inode *inode;
Steven Whitehouse5c676f62006-02-27 17:23:27 -05001208 struct gfs2_inode *dip = ghs->gh_gl->gl_object;
David Teiglandb3b94fa2006-01-16 16:50:04 +00001209 struct gfs2_sbd *sdp = dip->i_sbd;
1210 struct gfs2_unlinked *ul;
1211 struct gfs2_inode *ip;
1212 int error;
1213
1214 if (!name->len || name->len > GFS2_FNAMESIZE)
Steven Whitehouse7359a192006-02-13 12:27:43 +00001215 return ERR_PTR(-ENAMETOOLONG);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001216
1217 error = gfs2_unlinked_get(sdp, &ul);
1218 if (error)
Steven Whitehouse7359a192006-02-13 12:27:43 +00001219 return ERR_PTR(error);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001220
1221 gfs2_holder_reinit(LM_ST_EXCLUSIVE, 0, ghs);
1222 error = gfs2_glock_nq(ghs);
1223 if (error)
1224 goto fail;
1225
1226 error = create_ok(dip, name, mode);
1227 if (error)
1228 goto fail_gunlock;
1229
1230 error = pick_formal_ino(sdp, &ul->ul_ut.ut_inum.no_formal_ino);
1231 if (error)
1232 goto fail_gunlock;
1233
1234 error = alloc_dinode(dip, ul);
1235 if (error)
1236 goto fail_gunlock;
1237
1238 if (ul->ul_ut.ut_inum.no_addr < dip->i_num.no_addr) {
1239 gfs2_glock_dq(ghs);
1240
1241 error = gfs2_glock_nq_num(sdp,
1242 ul->ul_ut.ut_inum.no_addr,
1243 &gfs2_inode_glops,
1244 LM_ST_EXCLUSIVE, GL_SKIP,
1245 ghs + 1);
1246 if (error) {
1247 gfs2_unlinked_put(sdp, ul);
Steven Whitehouse7359a192006-02-13 12:27:43 +00001248 return ERR_PTR(error);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001249 }
1250
1251 gfs2_holder_reinit(LM_ST_EXCLUSIVE, 0, ghs);
1252 error = gfs2_glock_nq(ghs);
1253 if (error) {
1254 gfs2_glock_dq_uninit(ghs + 1);
1255 gfs2_unlinked_put(sdp, ul);
Steven Whitehouse7359a192006-02-13 12:27:43 +00001256 return ERR_PTR(error);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001257 }
1258
1259 error = create_ok(dip, name, mode);
1260 if (error)
1261 goto fail_gunlock2;
1262 } else {
1263 error = gfs2_glock_nq_num(sdp,
1264 ul->ul_ut.ut_inum.no_addr,
1265 &gfs2_inode_glops,
1266 LM_ST_EXCLUSIVE, GL_SKIP,
1267 ghs + 1);
1268 if (error)
1269 goto fail_gunlock;
1270 }
1271
1272 error = make_dinode(dip, ghs[1].gh_gl, mode, ul);
1273 if (error)
1274 goto fail_gunlock2;
1275
1276 error = gfs2_inode_get(ghs[1].gh_gl, &ul->ul_ut.ut_inum, CREATE, &ip);
1277 if (error)
1278 goto fail_gunlock2;
1279
1280 error = gfs2_inode_refresh(ip);
1281 if (error)
1282 goto fail_iput;
1283
1284 error = gfs2_acl_create(dip, ip);
1285 if (error)
1286 goto fail_iput;
1287
1288 error = link_dinode(dip, name, ip, ul);
1289 if (error)
1290 goto fail_iput;
1291
1292 gfs2_unlinked_put(sdp, ul);
1293
Steven Whitehouse7359a192006-02-13 12:27:43 +00001294 inode = gfs2_ip2v(ip);
1295 gfs2_inode_put(ip);
1296 if (!inode)
1297 return ERR_PTR(-ENOMEM);
1298 return inode;
David Teiglandb3b94fa2006-01-16 16:50:04 +00001299
1300 fail_iput:
1301 gfs2_inode_put(ip);
1302
1303 fail_gunlock2:
1304 gfs2_glock_dq_uninit(ghs + 1);
1305
1306 fail_gunlock:
1307 gfs2_glock_dq(ghs);
1308
1309 fail:
1310 gfs2_unlinked_put(sdp, ul);
1311
Steven Whitehouse7359a192006-02-13 12:27:43 +00001312 return ERR_PTR(error);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001313}
1314
1315/**
1316 * gfs2_unlinki - Unlink a file
1317 * @dip: The inode of the directory
1318 * @name: The name of the file to be unlinked
1319 * @ip: The inode of the file to be removed
1320 *
1321 * Assumes Glocks on both dip and ip are held.
1322 *
1323 * Returns: errno
1324 */
1325
1326int gfs2_unlinki(struct gfs2_inode *dip, struct qstr *name,
1327 struct gfs2_inode *ip, struct gfs2_unlinked *ul)
1328{
1329 struct gfs2_sbd *sdp = dip->i_sbd;
1330 int error;
1331
1332 error = gfs2_dir_del(dip, name);
1333 if (error)
1334 return error;
1335
1336 error = gfs2_change_nlink(ip, -1);
1337 if (error)
1338 return error;
1339
1340 /* If this inode is being unlinked from the directory structure,
1341 we need to mark that in the log so that it isn't lost during
1342 a crash. */
1343
1344 if (!ip->i_di.di_nlink) {
1345 ul->ul_ut.ut_inum = ip->i_num;
1346 error = gfs2_unlinked_ondisk_add(sdp, ul);
1347 if (!error)
1348 set_bit(GLF_STICKY, &ip->i_gl->gl_flags);
1349 }
1350
1351 return error;
1352}
1353
1354/**
1355 * gfs2_rmdiri - Remove a directory
1356 * @dip: The parent directory of the directory to be removed
1357 * @name: The name of the directory to be removed
1358 * @ip: The GFS2 inode of the directory to be removed
1359 *
1360 * Assumes Glocks on dip and ip are held
1361 *
1362 * Returns: errno
1363 */
1364
1365int gfs2_rmdiri(struct gfs2_inode *dip, struct qstr *name,
1366 struct gfs2_inode *ip, struct gfs2_unlinked *ul)
1367{
1368 struct gfs2_sbd *sdp = dip->i_sbd;
1369 struct qstr dotname;
1370 int error;
1371
1372 if (ip->i_di.di_entries != 2) {
1373 if (gfs2_consist_inode(ip))
1374 gfs2_dinode_print(&ip->i_di);
1375 return -EIO;
1376 }
1377
1378 error = gfs2_dir_del(dip, name);
1379 if (error)
1380 return error;
1381
1382 error = gfs2_change_nlink(dip, -1);
1383 if (error)
1384 return error;
1385
Steven Whitehouse71b86f52006-03-28 14:14:04 -05001386 gfs2_str2qstr(&dotname, ".");
David Teiglandb3b94fa2006-01-16 16:50:04 +00001387 error = gfs2_dir_del(ip, &dotname);
1388 if (error)
1389 return error;
1390
1391 dotname.len = 2;
1392 dotname.name = "..";
Steven Whitehousec7526662006-03-20 12:30:04 -05001393 dotname.hash = gfs2_disk_hash(dotname.name, dotname.len);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001394 error = gfs2_dir_del(ip, &dotname);
1395 if (error)
1396 return error;
1397
1398 error = gfs2_change_nlink(ip, -2);
1399 if (error)
1400 return error;
1401
1402 /* This inode is being unlinked from the directory structure and
1403 we need to mark that in the log so that it isn't lost during
1404 a crash. */
1405
1406 ul->ul_ut.ut_inum = ip->i_num;
1407 error = gfs2_unlinked_ondisk_add(sdp, ul);
1408 if (!error)
1409 set_bit(GLF_STICKY, &ip->i_gl->gl_flags);
1410
1411 return error;
1412}
1413
1414/*
1415 * gfs2_unlink_ok - check to see that a inode is still in a directory
1416 * @dip: the directory
1417 * @name: the name of the file
1418 * @ip: the inode
1419 *
1420 * Assumes that the lock on (at least) @dip is held.
1421 *
1422 * Returns: 0 if the parent/child relationship is correct, errno if it isn't
1423 */
1424
1425int gfs2_unlink_ok(struct gfs2_inode *dip, struct qstr *name,
1426 struct gfs2_inode *ip)
1427{
1428 struct gfs2_inum inum;
1429 unsigned int type;
1430 int error;
1431
1432 if (IS_IMMUTABLE(ip->i_vnode) || IS_APPEND(ip->i_vnode))
1433 return -EPERM;
1434
1435 if ((dip->i_di.di_mode & S_ISVTX) &&
1436 dip->i_di.di_uid != current->fsuid &&
1437 ip->i_di.di_uid != current->fsuid &&
1438 !capable(CAP_FOWNER))
1439 return -EPERM;
1440
1441 if (IS_APPEND(dip->i_vnode))
1442 return -EPERM;
1443
1444 error = gfs2_repermission(dip->i_vnode, MAY_WRITE | MAY_EXEC, NULL);
1445 if (error)
1446 return error;
1447
Steven Whitehousec7526662006-03-20 12:30:04 -05001448 error = gfs2_dir_search(dip->i_vnode, name, &inum, &type);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001449 if (error)
1450 return error;
1451
1452 if (!gfs2_inum_equal(&inum, &ip->i_num))
1453 return -ENOENT;
1454
1455 if (IF2DT(ip->i_di.di_mode) != type) {
1456 gfs2_consist_inode(dip);
1457 return -EIO;
1458 }
1459
1460 return 0;
1461}
1462
1463/*
1464 * gfs2_ok_to_move - check if it's ok to move a directory to another directory
1465 * @this: move this
1466 * @to: to here
1467 *
1468 * Follow @to back to the root and make sure we don't encounter @this
1469 * Assumes we already hold the rename lock.
1470 *
1471 * Returns: errno
1472 */
1473
1474int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to)
1475{
Steven Whitehouse7359a192006-02-13 12:27:43 +00001476 struct inode *dir = to->i_vnode;
Steven Whitehousec9fd4302006-03-01 15:31:02 -05001477 struct super_block *sb = dir->i_sb;
Steven Whitehouse7359a192006-02-13 12:27:43 +00001478 struct inode *tmp;
David Teiglandb3b94fa2006-01-16 16:50:04 +00001479 struct qstr dotdot;
1480 int error = 0;
1481
Steven Whitehouse71b86f52006-03-28 14:14:04 -05001482 gfs2_str2qstr(&dotdot, "..");
David Teiglandb3b94fa2006-01-16 16:50:04 +00001483
Steven Whitehouse7359a192006-02-13 12:27:43 +00001484 igrab(dir);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001485
1486 for (;;) {
Steven Whitehouse7359a192006-02-13 12:27:43 +00001487 if (dir == this->i_vnode) {
David Teiglandb3b94fa2006-01-16 16:50:04 +00001488 error = -EINVAL;
1489 break;
1490 }
Steven Whitehousec9fd4302006-03-01 15:31:02 -05001491 if (dir == sb->s_root->d_inode) {
David Teiglandb3b94fa2006-01-16 16:50:04 +00001492 error = 0;
1493 break;
1494 }
1495
Steven Whitehousec7526662006-03-20 12:30:04 -05001496 tmp = gfs2_lookupi(dir, &dotdot, 1, NULL);
1497 if (IS_ERR(tmp)) {
1498 error = PTR_ERR(tmp);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001499 break;
Steven Whitehousec7526662006-03-20 12:30:04 -05001500 }
David Teiglandb3b94fa2006-01-16 16:50:04 +00001501
Steven Whitehouse7359a192006-02-13 12:27:43 +00001502 iput(dir);
1503 dir = tmp;
David Teiglandb3b94fa2006-01-16 16:50:04 +00001504 }
1505
Steven Whitehouse7359a192006-02-13 12:27:43 +00001506 iput(dir);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001507
1508 return error;
1509}
1510
1511/**
1512 * gfs2_readlinki - return the contents of a symlink
1513 * @ip: the symlink's inode
1514 * @buf: a pointer to the buffer to be filled
1515 * @len: a pointer to the length of @buf
1516 *
1517 * If @buf is too small, a piece of memory is kmalloc()ed and needs
1518 * to be freed by the caller.
1519 *
1520 * Returns: errno
1521 */
1522
1523int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len)
1524{
1525 struct gfs2_holder i_gh;
1526 struct buffer_head *dibh;
1527 unsigned int x;
1528 int error;
1529
1530 gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &i_gh);
1531 error = gfs2_glock_nq_atime(&i_gh);
1532 if (error) {
1533 gfs2_holder_uninit(&i_gh);
1534 return error;
1535 }
1536
1537 if (!ip->i_di.di_size) {
1538 gfs2_consist_inode(ip);
1539 error = -EIO;
1540 goto out;
1541 }
1542
1543 error = gfs2_meta_inode_buffer(ip, &dibh);
1544 if (error)
1545 goto out;
1546
1547 x = ip->i_di.di_size + 1;
1548 if (x > *len) {
1549 *buf = kmalloc(x, GFP_KERNEL);
1550 if (!*buf) {
1551 error = -ENOMEM;
1552 goto out_brelse;
1553 }
1554 }
1555
1556 memcpy(*buf, dibh->b_data + sizeof(struct gfs2_dinode), x);
1557 *len = x;
1558
1559 out_brelse:
1560 brelse(dibh);
1561
1562 out:
1563 gfs2_glock_dq_uninit(&i_gh);
1564
1565 return error;
1566}
1567
1568/**
1569 * gfs2_glock_nq_atime - Acquire a hold on an inode's glock, and
1570 * conditionally update the inode's atime
1571 * @gh: the holder to acquire
1572 *
1573 * Tests atime (access time) for gfs2_read, gfs2_readdir and gfs2_mmap
1574 * Update if the difference between the current time and the inode's current
1575 * atime is greater than an interval specified at mount.
1576 *
1577 * Returns: errno
1578 */
1579
1580int gfs2_glock_nq_atime(struct gfs2_holder *gh)
1581{
1582 struct gfs2_glock *gl = gh->gh_gl;
1583 struct gfs2_sbd *sdp = gl->gl_sbd;
Steven Whitehouse5c676f62006-02-27 17:23:27 -05001584 struct gfs2_inode *ip = gl->gl_object;
David Teiglandb3b94fa2006-01-16 16:50:04 +00001585 int64_t curtime, quantum = gfs2_tune_get(sdp, gt_atime_quantum);
1586 unsigned int state;
1587 int flags;
1588 int error;
1589
1590 if (gfs2_assert_warn(sdp, gh->gh_flags & GL_ATIME) ||
1591 gfs2_assert_warn(sdp, !(gh->gh_flags & GL_ASYNC)) ||
1592 gfs2_assert_warn(sdp, gl->gl_ops == &gfs2_inode_glops))
1593 return -EINVAL;
1594
1595 state = gh->gh_state;
1596 flags = gh->gh_flags;
1597
1598 error = gfs2_glock_nq(gh);
1599 if (error)
1600 return error;
1601
1602 if (test_bit(SDF_NOATIME, &sdp->sd_flags) ||
1603 (sdp->sd_vfs->s_flags & MS_RDONLY))
1604 return 0;
1605
1606 curtime = get_seconds();
1607 if (curtime - ip->i_di.di_atime >= quantum) {
1608 gfs2_glock_dq(gh);
1609 gfs2_holder_reinit(LM_ST_EXCLUSIVE,
1610 gh->gh_flags & ~LM_FLAG_ANY,
1611 gh);
1612 error = gfs2_glock_nq(gh);
1613 if (error)
1614 return error;
1615
1616 /* Verify that atime hasn't been updated while we were
1617 trying to get exclusive lock. */
1618
1619 curtime = get_seconds();
1620 if (curtime - ip->i_di.di_atime >= quantum) {
1621 struct buffer_head *dibh;
1622
1623 error = gfs2_trans_begin(sdp, RES_DINODE, 0);
1624 if (error == -EROFS)
1625 return 0;
1626 if (error)
1627 goto fail;
1628
1629 error = gfs2_meta_inode_buffer(ip, &dibh);
1630 if (error)
1631 goto fail_end_trans;
1632
1633 ip->i_di.di_atime = curtime;
1634
Steven Whitehoused4e9c4c2006-01-18 11:19:28 +00001635 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001636 gfs2_dinode_out(&ip->i_di, dibh->b_data);
1637 brelse(dibh);
1638
1639 gfs2_trans_end(sdp);
1640 }
1641
1642 /* If someone else has asked for the glock,
1643 unlock and let them have it. Then reacquire
1644 in the original state. */
1645 if (gfs2_glock_is_blocking(gl)) {
1646 gfs2_glock_dq(gh);
1647 gfs2_holder_reinit(state, flags, gh);
1648 return gfs2_glock_nq(gh);
1649 }
1650 }
1651
1652 return 0;
1653
1654 fail_end_trans:
1655 gfs2_trans_end(sdp);
1656
1657 fail:
1658 gfs2_glock_dq(gh);
1659
1660 return error;
1661}
1662
1663/**
1664 * glock_compare_atime - Compare two struct gfs2_glock structures for sort
1665 * @arg_a: the first structure
1666 * @arg_b: the second structure
1667 *
1668 * Returns: 1 if A > B
1669 * -1 if A < B
1670 * 0 if A = B
1671 */
1672
1673static int glock_compare_atime(const void *arg_a, const void *arg_b)
1674{
1675 struct gfs2_holder *gh_a = *(struct gfs2_holder **)arg_a;
1676 struct gfs2_holder *gh_b = *(struct gfs2_holder **)arg_b;
1677 struct lm_lockname *a = &gh_a->gh_gl->gl_name;
1678 struct lm_lockname *b = &gh_b->gh_gl->gl_name;
1679 int ret = 0;
1680
1681 if (a->ln_number > b->ln_number)
1682 ret = 1;
1683 else if (a->ln_number < b->ln_number)
1684 ret = -1;
1685 else {
1686 if (gh_a->gh_state == LM_ST_SHARED &&
1687 gh_b->gh_state == LM_ST_EXCLUSIVE)
1688 ret = 1;
1689 else if (gh_a->gh_state == LM_ST_SHARED &&
1690 (gh_b->gh_flags & GL_ATIME))
1691 ret = 1;
1692 }
1693
1694 return ret;
1695}
1696
1697/**
1698 * gfs2_glock_nq_m_atime - acquire multiple glocks where one may need an
1699 * atime update
1700 * @num_gh: the number of structures
1701 * @ghs: an array of struct gfs2_holder structures
1702 *
1703 * Returns: 0 on success (all glocks acquired),
1704 * errno on failure (no glocks acquired)
1705 */
1706
1707int gfs2_glock_nq_m_atime(unsigned int num_gh, struct gfs2_holder *ghs)
1708{
1709 struct gfs2_holder **p;
1710 unsigned int x;
1711 int error = 0;
1712
1713 if (!num_gh)
1714 return 0;
1715
1716 if (num_gh == 1) {
1717 ghs->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC);
1718 if (ghs->gh_flags & GL_ATIME)
1719 error = gfs2_glock_nq_atime(ghs);
1720 else
1721 error = gfs2_glock_nq(ghs);
1722 return error;
1723 }
1724
1725 p = kcalloc(num_gh, sizeof(struct gfs2_holder *), GFP_KERNEL);
1726 if (!p)
1727 return -ENOMEM;
1728
1729 for (x = 0; x < num_gh; x++)
1730 p[x] = &ghs[x];
1731
1732 sort(p, num_gh, sizeof(struct gfs2_holder *), glock_compare_atime,NULL);
1733
1734 for (x = 0; x < num_gh; x++) {
1735 p[x]->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC);
1736
1737 if (p[x]->gh_flags & GL_ATIME)
1738 error = gfs2_glock_nq_atime(p[x]);
1739 else
1740 error = gfs2_glock_nq(p[x]);
1741
1742 if (error) {
1743 while (x--)
1744 gfs2_glock_dq(p[x]);
1745 break;
1746 }
1747 }
1748
1749 kfree(p);
1750
1751 return error;
1752}
1753
1754/**
1755 * gfs2_try_toss_vnode - See if we can toss a vnode from memory
1756 * @ip: the inode
1757 *
1758 * Returns: 1 if the vnode was tossed
1759 */
1760
1761void gfs2_try_toss_vnode(struct gfs2_inode *ip)
1762{
1763 struct inode *inode;
1764
1765 inode = gfs2_ip2v_lookup(ip);
1766 if (!inode)
1767 return;
1768
1769 d_prune_aliases(inode);
1770
1771 if (S_ISDIR(ip->i_di.di_mode)) {
1772 struct list_head *head = &inode->i_dentry;
1773 struct dentry *d = NULL;
1774
1775 spin_lock(&dcache_lock);
1776 if (list_empty(head))
1777 spin_unlock(&dcache_lock);
1778 else {
1779 d = list_entry(head->next, struct dentry, d_alias);
1780 dget_locked(d);
1781 spin_unlock(&dcache_lock);
1782
1783 if (have_submounts(d))
1784 dput(d);
1785 else {
1786 shrink_dcache_parent(d);
1787 dput(d);
1788 d_prune_aliases(inode);
1789 }
1790 }
1791 }
1792
1793 inode->i_nlink = 0;
1794 iput(inode);
1795}
1796
1797
1798static int
1799__gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr)
1800{
1801 struct buffer_head *dibh;
1802 int error;
1803
1804 error = gfs2_meta_inode_buffer(ip, &dibh);
1805 if (!error) {
1806 error = inode_setattr(ip->i_vnode, attr);
1807 gfs2_assert_warn(ip->i_sbd, !error);
1808 gfs2_inode_attr_out(ip);
1809
Steven Whitehoused4e9c4c2006-01-18 11:19:28 +00001810 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001811 gfs2_dinode_out(&ip->i_di, dibh->b_data);
1812 brelse(dibh);
1813 }
1814 return error;
1815}
1816
1817/**
1818 * gfs2_setattr_simple -
1819 * @ip:
1820 * @attr:
1821 *
1822 * Called with a reference on the vnode.
1823 *
1824 * Returns: errno
1825 */
1826
1827int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr)
1828{
1829 int error;
1830
Steven Whitehouse5c676f62006-02-27 17:23:27 -05001831 if (current->journal_info)
David Teiglandb3b94fa2006-01-16 16:50:04 +00001832 return __gfs2_setattr_simple(ip, attr);
1833
1834 error = gfs2_trans_begin(ip->i_sbd, RES_DINODE, 0);
1835 if (error)
1836 return error;
1837
1838 error = __gfs2_setattr_simple(ip, attr);
1839
1840 gfs2_trans_end(ip->i_sbd);
1841
1842 return error;
1843}
1844
1845int gfs2_repermission(struct inode *inode, int mask, struct nameidata *nd)
1846{
1847 return permission(inode, mask, nd);
1848}
1849