blob: 5bc9542c7fcb9cbf4ed62982f6e70b4df025b80d [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));
David Teiglandb3b94fa2006-01-16 16:50:04 +0000300 ip->i_num = *inum;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000301 atomic_set(&ip->i_count, 1);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000302 ip->i_vn = i_gl->gl_vn - 1;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000303 ip->i_gl = i_gl;
304 ip->i_sbd = sdp;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000305 spin_lock_init(&ip->i_spin);
306 init_rwsem(&ip->i_rw_mutex);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000307 ip->i_greedy = gfs2_tune_get(sdp, gt_greedy_default);
308
Steven Whitehouse36327522006-04-28 10:46:21 -0400309 if (need_lock) {
310 error = gfs2_glock_nq_init(io_gl,
311 io_state, GL_LOCAL_EXCL | GL_EXACT,
312 &ip->i_iopen_gh);
313 if (error)
314 goto fail;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000315
Steven Whitehouse64c14ea2006-05-16 13:37:11 -0400316 spin_lock(&io_gl->gl_spin);
317 gfs2_glock_hold(i_gl);
318 io_gl->gl_object = i_gl;
319 spin_unlock(&io_gl->gl_spin);
320 }
David Teiglandb3b94fa2006-01-16 16:50:04 +0000321
322 gfs2_glock_hold(i_gl);
Steven Whitehouse5c676f62006-02-27 17:23:27 -0500323 i_gl->gl_object = ip;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000324 atomic_inc(&sdp->sd_inode_count);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000325 *ipp = ip;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000326 return 0;
327
Steven Whitehouse64c14ea2006-05-16 13:37:11 -0400328fail:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000329 gfs2_meta_cache_flush(ip);
330 kmem_cache_free(gfs2_inode_cachep, ip);
331 *ipp = NULL;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000332 return error;
333}
334
335/**
336 * gfs2_inode_get - Create or get a reference on an inode
337 * @i_gl: The glock covering the inode
338 * @inum: The inode number
339 * @create:
340 * @ipp: pointer to put the returned inode in
341 *
342 * Returns: errno
343 */
344
Steven Whitehousec9fd4302006-03-01 15:31:02 -0500345int gfs2_inode_get(struct gfs2_glock *i_gl, const struct gfs2_inum *inum,
346 int create, struct gfs2_inode **ipp)
David Teiglandb3b94fa2006-01-16 16:50:04 +0000347{
348 struct gfs2_sbd *sdp = i_gl->gl_sbd;
349 struct gfs2_glock *io_gl;
350 int error = 0;
351
352 gfs2_glmutex_lock(i_gl);
353
Steven Whitehouse5c676f62006-02-27 17:23:27 -0500354 *ipp = i_gl->gl_object;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000355 if (*ipp) {
356 error = -ESTALE;
357 if ((*ipp)->i_num.no_formal_ino != inum->no_formal_ino)
358 goto out;
359 atomic_inc(&(*ipp)->i_count);
360 error = 0;
361 goto out;
362 }
363
364 if (!create)
365 goto out;
366
367 error = gfs2_glock_get(sdp, inum->no_addr, &gfs2_iopen_glops,
368 CREATE, &io_gl);
369 if (!error) {
Steven Whitehouse36327522006-04-28 10:46:21 -0400370 error = inode_create(i_gl, inum, io_gl, LM_ST_SHARED, ipp, 1);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000371 gfs2_glock_put(io_gl);
372 }
373
374 out:
375 gfs2_glmutex_unlock(i_gl);
376
377 return error;
378}
379
380void gfs2_inode_hold(struct gfs2_inode *ip)
381{
382 gfs2_assert(ip->i_sbd, atomic_read(&ip->i_count) > 0);
383 atomic_inc(&ip->i_count);
384}
385
386void gfs2_inode_put(struct gfs2_inode *ip)
387{
388 gfs2_assert(ip->i_sbd, atomic_read(&ip->i_count) > 0);
389 atomic_dec(&ip->i_count);
390}
391
Steven Whitehouse36327522006-04-28 10:46:21 -0400392void gfs2_inode_destroy(struct gfs2_inode *ip, int unlock)
David Teiglandb3b94fa2006-01-16 16:50:04 +0000393{
394 struct gfs2_sbd *sdp = ip->i_sbd;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000395 struct gfs2_glock *i_gl = ip->i_gl;
396
397 gfs2_assert_warn(sdp, !atomic_read(&ip->i_count));
Steven Whitehouse36327522006-04-28 10:46:21 -0400398 if (unlock) {
399 struct gfs2_glock *io_gl = ip->i_iopen_gh.gh_gl;
400 gfs2_assert(sdp, io_gl->gl_object == i_gl);
401
402 spin_lock(&io_gl->gl_spin);
403 io_gl->gl_object = NULL;
404 spin_unlock(&io_gl->gl_spin);
405 gfs2_glock_put(i_gl);
406
407 gfs2_glock_dq_uninit(&ip->i_iopen_gh);
408 }
David Teiglandb3b94fa2006-01-16 16:50:04 +0000409
410 gfs2_meta_cache_flush(ip);
411 kmem_cache_free(gfs2_inode_cachep, ip);
412
Steven Whitehouse5c676f62006-02-27 17:23:27 -0500413 i_gl->gl_object = NULL;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000414 gfs2_glock_put(i_gl);
415
416 atomic_dec(&sdp->sd_inode_count);
417}
418
419static int dinode_dealloc(struct gfs2_inode *ip, struct gfs2_unlinked *ul)
420{
421 struct gfs2_sbd *sdp = ip->i_sbd;
422 struct gfs2_alloc *al;
423 struct gfs2_rgrpd *rgd;
424 int error;
425
426 if (ip->i_di.di_blocks != 1) {
427 if (gfs2_consist_inode(ip))
428 gfs2_dinode_print(&ip->i_di);
429 return -EIO;
430 }
431
432 al = gfs2_alloc_get(ip);
433
434 error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
435 if (error)
436 goto out;
437
438 error = gfs2_rindex_hold(sdp, &al->al_ri_gh);
439 if (error)
440 goto out_qs;
441
442 rgd = gfs2_blk2rgrpd(sdp, ip->i_num.no_addr);
443 if (!rgd) {
444 gfs2_consist_inode(ip);
445 error = -EIO;
446 goto out_rindex_relse;
447 }
448
449 error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0,
450 &al->al_rgd_gh);
451 if (error)
452 goto out_rindex_relse;
453
454 error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_UNLINKED +
455 RES_STATFS + RES_QUOTA, 1);
456 if (error)
457 goto out_rg_gunlock;
458
459 gfs2_trans_add_gl(ip->i_gl);
460
461 gfs2_free_di(rgd, ip);
462
463 error = gfs2_unlinked_ondisk_rm(sdp, ul);
464
465 gfs2_trans_end(sdp);
466 clear_bit(GLF_STICKY, &ip->i_gl->gl_flags);
467
468 out_rg_gunlock:
469 gfs2_glock_dq_uninit(&al->al_rgd_gh);
470
471 out_rindex_relse:
472 gfs2_glock_dq_uninit(&al->al_ri_gh);
473
474 out_qs:
475 gfs2_quota_unhold(ip);
476
477 out:
478 gfs2_alloc_put(ip);
479
480 return error;
481}
482
483/**
484 * inode_dealloc - Deallocate all on-disk blocks for an inode (dinode)
485 * @sdp: the filesystem
486 * @inum: the inode number to deallocate
487 * @io_gh: a holder for the iopen glock for this inode
488 *
Steven Whitehouse36327522006-04-28 10:46:21 -0400489 * N.B. When we enter this we already hold the iopen glock and getting
490 * the glock for the inode means that we are grabbing the locks in the
491 * "wrong" order so we must only so a try lock operation and fail if we
492 * don't get the lock. Thats ok, since if we fail it means someone else
493 * is using the inode still and thus we shouldn't be deallocating it
494 * anyway.
495 *
David Teiglandb3b94fa2006-01-16 16:50:04 +0000496 * Returns: errno
497 */
498
499static int inode_dealloc(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul,
500 struct gfs2_holder *io_gh)
501{
502 struct gfs2_inode *ip;
503 struct gfs2_holder i_gh;
504 int error;
505
Steven Whitehouse36327522006-04-28 10:46:21 -0400506 error = gfs2_glock_nq_num(sdp, ul->ul_ut.ut_inum.no_addr,
507 &gfs2_inode_glops, LM_ST_EXCLUSIVE,
508 LM_FLAG_TRY_1CB, &i_gh);
509 switch(error) {
David Teiglandb3b94fa2006-01-16 16:50:04 +0000510 case 0:
511 break;
512 case GLR_TRYFAILED:
Steven Whitehouse36327522006-04-28 10:46:21 -0400513 return 1; /* or back off and relock in different order? */
David Teiglandb3b94fa2006-01-16 16:50:04 +0000514 default:
Steven Whitehouse36327522006-04-28 10:46:21 -0400515 return error;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000516 }
517
Steven Whitehouse5c676f62006-02-27 17:23:27 -0500518 gfs2_assert_warn(sdp, !i_gh.gh_gl->gl_object);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000519 error = inode_create(i_gh.gh_gl, &ul->ul_ut.ut_inum, io_gh->gh_gl,
Steven Whitehouse36327522006-04-28 10:46:21 -0400520 LM_ST_EXCLUSIVE, &ip, 0);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000521
522 if (error)
523 goto out;
524
525 error = gfs2_inode_refresh(ip);
526 if (error)
527 goto out_iput;
528
529 if (ip->i_di.di_nlink) {
530 if (gfs2_consist_inode(ip))
531 gfs2_dinode_print(&ip->i_di);
532 error = -EIO;
533 goto out_iput;
534 }
535
536 if (S_ISDIR(ip->i_di.di_mode) &&
537 (ip->i_di.di_flags & GFS2_DIF_EXHASH)) {
538 error = gfs2_dir_exhash_dealloc(ip);
539 if (error)
540 goto out_iput;
541 }
542
543 if (ip->i_di.di_eattr) {
544 error = gfs2_ea_dealloc(ip);
545 if (error)
546 goto out_iput;
547 }
548
549 if (!gfs2_is_stuffed(ip)) {
550 error = gfs2_file_dealloc(ip);
551 if (error)
552 goto out_iput;
553 }
554
555 error = dinode_dealloc(ip, ul);
556 if (error)
557 goto out_iput;
558
Steven Whitehouse36327522006-04-28 10:46:21 -0400559out_iput:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000560 gfs2_glmutex_lock(i_gh.gh_gl);
561 gfs2_inode_put(ip);
Steven Whitehouse36327522006-04-28 10:46:21 -0400562 gfs2_inode_destroy(ip, 0);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000563 gfs2_glmutex_unlock(i_gh.gh_gl);
564
Steven Whitehouse36327522006-04-28 10:46:21 -0400565out:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000566 gfs2_glock_dq_uninit(&i_gh);
567
568 return error;
569}
570
571/**
572 * try_inode_dealloc - Try to deallocate an inode and all its blocks
573 * @sdp: the filesystem
574 *
575 * Returns: 0 on success, -errno on error, 1 on busy (inode open)
576 */
577
578static int try_inode_dealloc(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
579{
David Teiglandb3b94fa2006-01-16 16:50:04 +0000580 int error = 0;
Steven Whitehouse36327522006-04-28 10:46:21 -0400581 struct gfs2_holder iogh;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000582
583 gfs2_try_toss_inode(sdp, &ul->ul_ut.ut_inum);
Steven Whitehouse36327522006-04-28 10:46:21 -0400584 error = gfs2_glock_nq_num(sdp, ul->ul_ut.ut_inum.no_addr,
585 &gfs2_iopen_glops, LM_ST_EXCLUSIVE,
586 LM_FLAG_TRY_1CB, &iogh);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000587 switch (error) {
588 case 0:
589 break;
590 case GLR_TRYFAILED:
591 return 1;
592 default:
593 return error;
594 }
595
Steven Whitehouse36327522006-04-28 10:46:21 -0400596 error = inode_dealloc(sdp, ul, &iogh);
597 gfs2_glock_dq_uninit(&iogh);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000598
599 return error;
600}
601
602static int inode_dealloc_uninit(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
603{
604 struct gfs2_rgrpd *rgd;
605 struct gfs2_holder ri_gh, rgd_gh;
606 int error;
607
608 error = gfs2_rindex_hold(sdp, &ri_gh);
609 if (error)
610 return error;
611
612 rgd = gfs2_blk2rgrpd(sdp, ul->ul_ut.ut_inum.no_addr);
613 if (!rgd) {
614 gfs2_consist(sdp);
615 error = -EIO;
616 goto out;
617 }
618
619 error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, &rgd_gh);
620 if (error)
621 goto out;
622
Steven Whitehouse36327522006-04-28 10:46:21 -0400623 error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_UNLINKED + RES_STATFS, 0);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000624 if (error)
625 goto out_gunlock;
626
627 gfs2_free_uninit_di(rgd, ul->ul_ut.ut_inum.no_addr);
628 gfs2_unlinked_ondisk_rm(sdp, ul);
629
630 gfs2_trans_end(sdp);
631
632 out_gunlock:
633 gfs2_glock_dq_uninit(&rgd_gh);
634 out:
635 gfs2_glock_dq_uninit(&ri_gh);
636
637 return error;
638}
639
640int gfs2_inode_dealloc(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
641{
642 if (ul->ul_ut.ut_flags & GFS2_UTF_UNINIT)
643 return inode_dealloc_uninit(sdp, ul);
644 else
645 return try_inode_dealloc(sdp, ul);
646}
647
648/**
649 * gfs2_change_nlink - Change nlink count on inode
650 * @ip: The GFS2 inode
651 * @diff: The change in the nlink count required
652 *
653 * Returns: errno
654 */
655
656int gfs2_change_nlink(struct gfs2_inode *ip, int diff)
657{
658 struct buffer_head *dibh;
659 uint32_t nlink;
660 int error;
661
662 nlink = ip->i_di.di_nlink + diff;
663
664 /* If we are reducing the nlink count, but the new value ends up being
665 bigger than the old one, we must have underflowed. */
666 if (diff < 0 && nlink > ip->i_di.di_nlink) {
667 if (gfs2_consist_inode(ip))
668 gfs2_dinode_print(&ip->i_di);
669 return -EIO;
670 }
671
672 error = gfs2_meta_inode_buffer(ip, &dibh);
673 if (error)
674 return error;
675
676 ip->i_di.di_nlink = nlink;
677 ip->i_di.di_ctime = get_seconds();
678
Steven Whitehoused4e9c4c2006-01-18 11:19:28 +0000679 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000680 gfs2_dinode_out(&ip->i_di, dibh->b_data);
681 brelse(dibh);
682
683 return 0;
684}
685
Steven Whitehousec7526662006-03-20 12:30:04 -0500686struct inode *gfs2_lookup_simple(struct inode *dip, const char *name)
687{
688 struct qstr qstr;
Steven Whitehouse71b86f52006-03-28 14:14:04 -0500689 gfs2_str2qstr(&qstr, name);
Steven Whitehousec7526662006-03-20 12:30:04 -0500690 return gfs2_lookupi(dip, &qstr, 1, NULL);
691}
692
693
David Teiglandb3b94fa2006-01-16 16:50:04 +0000694/**
695 * gfs2_lookupi - Look up a filename in a directory and return its inode
696 * @d_gh: An initialized holder for the directory glock
697 * @name: The name of the inode to look for
698 * @is_root: If 1, ignore the caller's permissions
699 * @i_gh: An uninitialized holder for the new inode glock
700 *
701 * There will always be a vnode (Linux VFS inode) for the d_gh inode unless
702 * @is_root is true.
703 *
704 * Returns: errno
705 */
706
Steven Whitehousec7526662006-03-20 12:30:04 -0500707struct inode *gfs2_lookupi(struct inode *dir, struct qstr *name, int is_root,
708 struct nameidata *nd)
709
David Teiglandb3b94fa2006-01-16 16:50:04 +0000710{
Steven Whitehousec9fd4302006-03-01 15:31:02 -0500711 struct super_block *sb = dir->i_sb;
Steven Whitehouse7359a192006-02-13 12:27:43 +0000712 struct gfs2_inode *ipp;
Steven Whitehouse5c676f62006-02-27 17:23:27 -0500713 struct gfs2_inode *dip = dir->u.generic_ip;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000714 struct gfs2_sbd *sdp = dip->i_sbd;
715 struct gfs2_holder d_gh;
716 struct gfs2_inum inum;
717 unsigned int type;
718 struct gfs2_glock *gl;
Steven Whitehouse7359a192006-02-13 12:27:43 +0000719 int error = 0;
Steven Whitehousec7526662006-03-20 12:30:04 -0500720 struct inode *inode = NULL;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000721
722 if (!name->len || name->len > GFS2_FNAMESIZE)
Steven Whitehousec7526662006-03-20 12:30:04 -0500723 return ERR_PTR(-ENAMETOOLONG);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000724
Steven Whitehousec7526662006-03-20 12:30:04 -0500725 if ((name->len == 1 && memcmp(name->name, ".", 1) == 0) ||
726 (name->len == 2 && memcmp(name->name, "..", 2) == 0 &&
727 dir == sb->s_root->d_inode)) {
David Teiglandb3b94fa2006-01-16 16:50:04 +0000728 gfs2_inode_hold(dip);
Steven Whitehouse7359a192006-02-13 12:27:43 +0000729 ipp = dip;
730 goto done;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000731 }
732
733 error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &d_gh);
734 if (error)
Steven Whitehousec7526662006-03-20 12:30:04 -0500735 return ERR_PTR(error);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000736
737 if (!is_root) {
738 error = gfs2_repermission(dip->i_vnode, MAY_EXEC, NULL);
739 if (error)
740 goto out;
741 }
742
Steven Whitehousec7526662006-03-20 12:30:04 -0500743 error = gfs2_dir_search(dir, name, &inum, &type);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000744 if (error)
745 goto out;
746
747 error = gfs2_glock_get(sdp, inum.no_addr, &gfs2_inode_glops,
748 CREATE, &gl);
749 if (error)
750 goto out;
751
Steven Whitehouse7359a192006-02-13 12:27:43 +0000752 error = gfs2_inode_get(gl, &inum, CREATE, &ipp);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000753 if (!error)
Steven Whitehouse7359a192006-02-13 12:27:43 +0000754 gfs2_inode_min_init(ipp, type);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000755
756 gfs2_glock_put(gl);
757
Steven Whitehouse7359a192006-02-13 12:27:43 +0000758out:
David Teiglandb3b94fa2006-01-16 16:50:04 +0000759 gfs2_glock_dq_uninit(&d_gh);
Steven Whitehouse7359a192006-02-13 12:27:43 +0000760done:
Steven Whitehousec7526662006-03-20 12:30:04 -0500761 if (error == -ENOENT)
762 return NULL;
Steven Whitehouse7359a192006-02-13 12:27:43 +0000763 if (error == 0) {
Steven Whitehousec7526662006-03-20 12:30:04 -0500764 inode = gfs2_ip2v(ipp);
Steven Whitehouse7359a192006-02-13 12:27:43 +0000765 gfs2_inode_put(ipp);
Steven Whitehousec7526662006-03-20 12:30:04 -0500766 if (!inode)
767 return ERR_PTR(-ENOMEM);
768 return inode;
Steven Whitehouse7359a192006-02-13 12:27:43 +0000769 }
Steven Whitehousec7526662006-03-20 12:30:04 -0500770 return ERR_PTR(error);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000771}
772
773static int pick_formal_ino_1(struct gfs2_sbd *sdp, uint64_t *formal_ino)
774{
Steven Whitehouse5c676f62006-02-27 17:23:27 -0500775 struct gfs2_inode *ip = sdp->sd_ir_inode->u.generic_ip;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000776 struct buffer_head *bh;
777 struct gfs2_inum_range ir;
778 int error;
779
780 error = gfs2_trans_begin(sdp, RES_DINODE, 0);
781 if (error)
782 return error;
Steven Whitehousef55ab262006-02-21 12:51:39 +0000783 mutex_lock(&sdp->sd_inum_mutex);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000784
785 error = gfs2_meta_inode_buffer(ip, &bh);
786 if (error) {
Steven Whitehousef55ab262006-02-21 12:51:39 +0000787 mutex_unlock(&sdp->sd_inum_mutex);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000788 gfs2_trans_end(sdp);
789 return error;
790 }
791
792 gfs2_inum_range_in(&ir, bh->b_data + sizeof(struct gfs2_dinode));
793
794 if (ir.ir_length) {
795 *formal_ino = ir.ir_start++;
796 ir.ir_length--;
Steven Whitehoused4e9c4c2006-01-18 11:19:28 +0000797 gfs2_trans_add_bh(ip->i_gl, bh, 1);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000798 gfs2_inum_range_out(&ir,
799 bh->b_data + sizeof(struct gfs2_dinode));
800 brelse(bh);
Steven Whitehousef55ab262006-02-21 12:51:39 +0000801 mutex_unlock(&sdp->sd_inum_mutex);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000802 gfs2_trans_end(sdp);
803 return 0;
804 }
805
806 brelse(bh);
807
Steven Whitehousef55ab262006-02-21 12:51:39 +0000808 mutex_unlock(&sdp->sd_inum_mutex);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000809 gfs2_trans_end(sdp);
810
811 return 1;
812}
813
814static int pick_formal_ino_2(struct gfs2_sbd *sdp, uint64_t *formal_ino)
815{
Steven Whitehouse5c676f62006-02-27 17:23:27 -0500816 struct gfs2_inode *ip = sdp->sd_ir_inode->u.generic_ip;
817 struct gfs2_inode *m_ip = sdp->sd_inum_inode->u.generic_ip;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000818 struct gfs2_holder gh;
819 struct buffer_head *bh;
820 struct gfs2_inum_range ir;
821 int error;
822
823 error = gfs2_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
824 if (error)
825 return error;
826
827 error = gfs2_trans_begin(sdp, 2 * RES_DINODE, 0);
828 if (error)
829 goto out;
Steven Whitehousef55ab262006-02-21 12:51:39 +0000830 mutex_lock(&sdp->sd_inum_mutex);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000831
832 error = gfs2_meta_inode_buffer(ip, &bh);
833 if (error)
834 goto out_end_trans;
835
836 gfs2_inum_range_in(&ir, bh->b_data + sizeof(struct gfs2_dinode));
837
838 if (!ir.ir_length) {
839 struct buffer_head *m_bh;
840 uint64_t x, y;
841
842 error = gfs2_meta_inode_buffer(m_ip, &m_bh);
843 if (error)
844 goto out_brelse;
845
846 x = *(uint64_t *)(m_bh->b_data + sizeof(struct gfs2_dinode));
847 x = y = be64_to_cpu(x);
848 ir.ir_start = x;
849 ir.ir_length = GFS2_INUM_QUANTUM;
850 x += GFS2_INUM_QUANTUM;
851 if (x < y)
852 gfs2_consist_inode(m_ip);
853 x = cpu_to_be64(x);
Steven Whitehoused4e9c4c2006-01-18 11:19:28 +0000854 gfs2_trans_add_bh(m_ip->i_gl, m_bh, 1);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000855 *(uint64_t *)(m_bh->b_data + sizeof(struct gfs2_dinode)) = x;
856
857 brelse(m_bh);
858 }
859
860 *formal_ino = ir.ir_start++;
861 ir.ir_length--;
862
Steven Whitehoused4e9c4c2006-01-18 11:19:28 +0000863 gfs2_trans_add_bh(ip->i_gl, bh, 1);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000864 gfs2_inum_range_out(&ir, bh->b_data + sizeof(struct gfs2_dinode));
865
866 out_brelse:
867 brelse(bh);
868
869 out_end_trans:
Steven Whitehousef55ab262006-02-21 12:51:39 +0000870 mutex_unlock(&sdp->sd_inum_mutex);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000871 gfs2_trans_end(sdp);
872
873 out:
874 gfs2_glock_dq_uninit(&gh);
875
876 return error;
877}
878
879static int pick_formal_ino(struct gfs2_sbd *sdp, uint64_t *inum)
880{
881 int error;
882
883 error = pick_formal_ino_1(sdp, inum);
884 if (error <= 0)
885 return error;
886
887 error = pick_formal_ino_2(sdp, inum);
888
889 return error;
890}
891
892/**
893 * create_ok - OK to create a new on-disk inode here?
894 * @dip: Directory in which dinode is to be created
895 * @name: Name of new dinode
896 * @mode:
897 *
898 * Returns: errno
899 */
900
901static int create_ok(struct gfs2_inode *dip, struct qstr *name,
902 unsigned int mode)
903{
904 int error;
905
906 error = gfs2_repermission(dip->i_vnode, MAY_WRITE | MAY_EXEC, NULL);
907 if (error)
908 return error;
909
910 /* Don't create entries in an unlinked directory */
911 if (!dip->i_di.di_nlink)
912 return -EPERM;
913
Steven Whitehousec7526662006-03-20 12:30:04 -0500914 error = gfs2_dir_search(dip->i_vnode, name, NULL, NULL);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000915 switch (error) {
916 case -ENOENT:
917 error = 0;
918 break;
919 case 0:
920 return -EEXIST;
921 default:
922 return error;
923 }
924
925 if (dip->i_di.di_entries == (uint32_t)-1)
926 return -EFBIG;
927 if (S_ISDIR(mode) && dip->i_di.di_nlink == (uint32_t)-1)
928 return -EMLINK;
929
930 return 0;
931}
932
933static void munge_mode_uid_gid(struct gfs2_inode *dip, unsigned int *mode,
934 unsigned int *uid, unsigned int *gid)
935{
936 if (dip->i_sbd->sd_args.ar_suiddir &&
937 (dip->i_di.di_mode & S_ISUID) &&
938 dip->i_di.di_uid) {
939 if (S_ISDIR(*mode))
940 *mode |= S_ISUID;
941 else if (dip->i_di.di_uid != current->fsuid)
942 *mode &= ~07111;
943 *uid = dip->i_di.di_uid;
944 } else
945 *uid = current->fsuid;
946
947 if (dip->i_di.di_mode & S_ISGID) {
948 if (S_ISDIR(*mode))
949 *mode |= S_ISGID;
950 *gid = dip->i_di.di_gid;
951 } else
952 *gid = current->fsgid;
953}
954
955static int alloc_dinode(struct gfs2_inode *dip, struct gfs2_unlinked *ul)
956{
957 struct gfs2_sbd *sdp = dip->i_sbd;
958 int error;
959
960 gfs2_alloc_get(dip);
961
962 dip->i_alloc.al_requested = RES_DINODE;
963 error = gfs2_inplace_reserve(dip);
964 if (error)
965 goto out;
966
967 error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_UNLINKED +
968 RES_STATFS, 0);
969 if (error)
970 goto out_ipreserv;
971
972 ul->ul_ut.ut_inum.no_addr = gfs2_alloc_di(dip);
973
974 ul->ul_ut.ut_flags = GFS2_UTF_UNINIT;
975 error = gfs2_unlinked_ondisk_add(sdp, ul);
976
977 gfs2_trans_end(sdp);
978
979 out_ipreserv:
980 gfs2_inplace_release(dip);
981
982 out:
983 gfs2_alloc_put(dip);
984
985 return error;
986}
987
988/**
989 * init_dinode - Fill in a new dinode structure
990 * @dip: the directory this inode is being created in
991 * @gl: The glock covering the new inode
992 * @inum: the inode number
993 * @mode: the file permissions
994 * @uid:
995 * @gid:
996 *
997 */
998
999static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl,
1000 struct gfs2_inum *inum, unsigned int mode,
1001 unsigned int uid, unsigned int gid)
1002{
1003 struct gfs2_sbd *sdp = dip->i_sbd;
Steven Whitehouseb96ca4f2006-01-18 10:57:10 +00001004 struct gfs2_dinode *di;
David Teiglandb3b94fa2006-01-16 16:50:04 +00001005 struct buffer_head *dibh;
1006
1007 dibh = gfs2_meta_new(gl, inum->no_addr);
Steven Whitehoused4e9c4c2006-01-18 11:19:28 +00001008 gfs2_trans_add_bh(gl, dibh, 1);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001009 gfs2_metatype_set(dibh, GFS2_METATYPE_DI, GFS2_FORMAT_DI);
1010 gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode));
Steven Whitehouseb96ca4f2006-01-18 10:57:10 +00001011 di = (struct gfs2_dinode *)dibh->b_data;
David Teiglandb3b94fa2006-01-16 16:50:04 +00001012
Steven Whitehouse2442a092006-01-30 11:49:32 +00001013 di->di_num.no_formal_ino = cpu_to_be64(inum->no_formal_ino);
1014 di->di_num.no_addr = cpu_to_be64(inum->no_addr);
Steven Whitehouseb96ca4f2006-01-18 10:57:10 +00001015 di->di_mode = cpu_to_be32(mode);
1016 di->di_uid = cpu_to_be32(uid);
1017 di->di_gid = cpu_to_be32(gid);
1018 di->di_nlink = cpu_to_be32(0);
1019 di->di_size = cpu_to_be64(0);
1020 di->di_blocks = cpu_to_be64(1);
1021 di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(get_seconds());
1022 di->di_major = di->di_minor = cpu_to_be32(0);
1023 di->di_goal_meta = di->di_goal_data = cpu_to_be64(inum->no_addr);
1024 di->__pad[0] = di->__pad[1] = 0;
1025 di->di_flags = cpu_to_be32(0);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001026
1027 if (S_ISREG(mode)) {
1028 if ((dip->i_di.di_flags & GFS2_DIF_INHERIT_JDATA) ||
1029 gfs2_tune_get(sdp, gt_new_files_jdata))
Steven Whitehouseb96ca4f2006-01-18 10:57:10 +00001030 di->di_flags |= cpu_to_be32(GFS2_DIF_JDATA);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001031 if ((dip->i_di.di_flags & GFS2_DIF_INHERIT_DIRECTIO) ||
1032 gfs2_tune_get(sdp, gt_new_files_directio))
Steven Whitehouseb96ca4f2006-01-18 10:57:10 +00001033 di->di_flags |= cpu_to_be32(GFS2_DIF_DIRECTIO);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001034 } else if (S_ISDIR(mode)) {
Steven Whitehouse568f4c92006-02-27 12:00:42 -05001035 di->di_flags |= cpu_to_be32(dip->i_di.di_flags &
1036 GFS2_DIF_INHERIT_DIRECTIO);
1037 di->di_flags |= cpu_to_be32(dip->i_di.di_flags &
1038 GFS2_DIF_INHERIT_JDATA);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001039 }
1040
Steven Whitehouseb96ca4f2006-01-18 10:57:10 +00001041 di->__pad1 = 0;
1042 di->di_height = cpu_to_be32(0);
1043 di->__pad2 = 0;
1044 di->__pad3 = 0;
1045 di->di_depth = cpu_to_be16(0);
1046 di->di_entries = cpu_to_be32(0);
1047 memset(&di->__pad4, 0, sizeof(di->__pad4));
1048 di->di_eattr = cpu_to_be64(0);
1049 memset(&di->di_reserved, 0, sizeof(di->di_reserved));
1050
David Teiglandb3b94fa2006-01-16 16:50:04 +00001051 brelse(dibh);
1052}
1053
1054static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl,
1055 unsigned int mode, struct gfs2_unlinked *ul)
1056{
1057 struct gfs2_sbd *sdp = dip->i_sbd;
1058 unsigned int uid, gid;
1059 int error;
1060
1061 munge_mode_uid_gid(dip, &mode, &uid, &gid);
1062
1063 gfs2_alloc_get(dip);
1064
1065 error = gfs2_quota_lock(dip, uid, gid);
1066 if (error)
1067 goto out;
1068
1069 error = gfs2_quota_check(dip, uid, gid);
1070 if (error)
1071 goto out_quota;
1072
1073 error = gfs2_trans_begin(sdp, RES_DINODE + RES_UNLINKED +
1074 RES_QUOTA, 0);
1075 if (error)
1076 goto out_quota;
1077
1078 ul->ul_ut.ut_flags = 0;
1079 error = gfs2_unlinked_ondisk_munge(sdp, ul);
1080
1081 init_dinode(dip, gl, &ul->ul_ut.ut_inum,
1082 mode, uid, gid);
1083
1084 gfs2_quota_change(dip, +1, uid, gid);
1085
1086 gfs2_trans_end(sdp);
1087
1088 out_quota:
1089 gfs2_quota_unlock(dip);
1090
1091 out:
1092 gfs2_alloc_put(dip);
1093
1094 return error;
1095}
1096
1097static int link_dinode(struct gfs2_inode *dip, struct qstr *name,
1098 struct gfs2_inode *ip, struct gfs2_unlinked *ul)
1099{
1100 struct gfs2_sbd *sdp = dip->i_sbd;
1101 struct gfs2_alloc *al;
1102 int alloc_required;
1103 struct buffer_head *dibh;
1104 int error;
1105
1106 al = gfs2_alloc_get(dip);
1107
1108 error = gfs2_quota_lock(dip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
1109 if (error)
1110 goto fail;
1111
Steven Whitehousec7526662006-03-20 12:30:04 -05001112 error = alloc_required = gfs2_diradd_alloc_required(dip->i_vnode, name);
1113 if (alloc_required < 0)
1114 goto fail;
David Teiglandb3b94fa2006-01-16 16:50:04 +00001115 if (alloc_required) {
1116 error = gfs2_quota_check(dip, dip->i_di.di_uid,
1117 dip->i_di.di_gid);
1118 if (error)
1119 goto fail_quota_locks;
1120
1121 al->al_requested = sdp->sd_max_dirres;
1122
1123 error = gfs2_inplace_reserve(dip);
1124 if (error)
1125 goto fail_quota_locks;
1126
1127 error = gfs2_trans_begin(sdp,
1128 sdp->sd_max_dirres +
1129 al->al_rgd->rd_ri.ri_length +
1130 2 * RES_DINODE + RES_UNLINKED +
1131 RES_STATFS + RES_QUOTA, 0);
1132 if (error)
1133 goto fail_ipreserv;
1134 } else {
1135 error = gfs2_trans_begin(sdp,
1136 RES_LEAF +
1137 2 * RES_DINODE +
1138 RES_UNLINKED, 0);
1139 if (error)
1140 goto fail_quota_locks;
1141 }
1142
Steven Whitehousec7526662006-03-20 12:30:04 -05001143 error = gfs2_dir_add(dip->i_vnode, name, &ip->i_num, IF2DT(ip->i_di.di_mode));
David Teiglandb3b94fa2006-01-16 16:50:04 +00001144 if (error)
1145 goto fail_end_trans;
1146
1147 error = gfs2_meta_inode_buffer(ip, &dibh);
1148 if (error)
1149 goto fail_end_trans;
1150 ip->i_di.di_nlink = 1;
Steven Whitehoused4e9c4c2006-01-18 11:19:28 +00001151 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001152 gfs2_dinode_out(&ip->i_di, dibh->b_data);
1153 brelse(dibh);
1154
1155 error = gfs2_unlinked_ondisk_rm(sdp, ul);
1156 if (error)
1157 goto fail_end_trans;
1158
1159 return 0;
1160
1161 fail_end_trans:
1162 gfs2_trans_end(sdp);
1163
1164 fail_ipreserv:
1165 if (dip->i_alloc.al_rgd)
1166 gfs2_inplace_release(dip);
1167
1168 fail_quota_locks:
1169 gfs2_quota_unlock(dip);
1170
1171 fail:
1172 gfs2_alloc_put(dip);
1173
1174 return error;
1175}
1176
1177/**
1178 * gfs2_createi - Create a new inode
1179 * @ghs: An array of two holders
1180 * @name: The name of the new file
1181 * @mode: the permissions on the new inode
1182 *
1183 * @ghs[0] is an initialized holder for the directory
1184 * @ghs[1] is the holder for the inode lock
1185 *
Steven Whitehouse7359a192006-02-13 12:27:43 +00001186 * If the return value is not NULL, the glocks on both the directory and the new
David Teiglandb3b94fa2006-01-16 16:50:04 +00001187 * file are held. A transaction has been started and an inplace reservation
1188 * is held, as well.
1189 *
Steven Whitehouse7359a192006-02-13 12:27:43 +00001190 * Returns: An inode
David Teiglandb3b94fa2006-01-16 16:50:04 +00001191 */
1192
Steven Whitehouse568f4c92006-02-27 12:00:42 -05001193struct inode *gfs2_createi(struct gfs2_holder *ghs, struct qstr *name,
1194 unsigned int mode)
David Teiglandb3b94fa2006-01-16 16:50:04 +00001195{
Steven Whitehouse7359a192006-02-13 12:27:43 +00001196 struct inode *inode;
Steven Whitehouse5c676f62006-02-27 17:23:27 -05001197 struct gfs2_inode *dip = ghs->gh_gl->gl_object;
David Teiglandb3b94fa2006-01-16 16:50:04 +00001198 struct gfs2_sbd *sdp = dip->i_sbd;
1199 struct gfs2_unlinked *ul;
1200 struct gfs2_inode *ip;
1201 int error;
1202
1203 if (!name->len || name->len > GFS2_FNAMESIZE)
Steven Whitehouse7359a192006-02-13 12:27:43 +00001204 return ERR_PTR(-ENAMETOOLONG);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001205
1206 error = gfs2_unlinked_get(sdp, &ul);
1207 if (error)
Steven Whitehouse7359a192006-02-13 12:27:43 +00001208 return ERR_PTR(error);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001209
1210 gfs2_holder_reinit(LM_ST_EXCLUSIVE, 0, ghs);
1211 error = gfs2_glock_nq(ghs);
1212 if (error)
1213 goto fail;
1214
1215 error = create_ok(dip, name, mode);
1216 if (error)
1217 goto fail_gunlock;
1218
1219 error = pick_formal_ino(sdp, &ul->ul_ut.ut_inum.no_formal_ino);
1220 if (error)
1221 goto fail_gunlock;
1222
1223 error = alloc_dinode(dip, ul);
1224 if (error)
1225 goto fail_gunlock;
1226
1227 if (ul->ul_ut.ut_inum.no_addr < dip->i_num.no_addr) {
1228 gfs2_glock_dq(ghs);
1229
1230 error = gfs2_glock_nq_num(sdp,
1231 ul->ul_ut.ut_inum.no_addr,
1232 &gfs2_inode_glops,
1233 LM_ST_EXCLUSIVE, GL_SKIP,
1234 ghs + 1);
1235 if (error) {
1236 gfs2_unlinked_put(sdp, ul);
Steven Whitehouse7359a192006-02-13 12:27:43 +00001237 return ERR_PTR(error);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001238 }
1239
1240 gfs2_holder_reinit(LM_ST_EXCLUSIVE, 0, ghs);
1241 error = gfs2_glock_nq(ghs);
1242 if (error) {
1243 gfs2_glock_dq_uninit(ghs + 1);
1244 gfs2_unlinked_put(sdp, ul);
Steven Whitehouse7359a192006-02-13 12:27:43 +00001245 return ERR_PTR(error);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001246 }
1247
1248 error = create_ok(dip, name, mode);
1249 if (error)
1250 goto fail_gunlock2;
1251 } else {
1252 error = gfs2_glock_nq_num(sdp,
1253 ul->ul_ut.ut_inum.no_addr,
1254 &gfs2_inode_glops,
1255 LM_ST_EXCLUSIVE, GL_SKIP,
1256 ghs + 1);
1257 if (error)
1258 goto fail_gunlock;
1259 }
1260
1261 error = make_dinode(dip, ghs[1].gh_gl, mode, ul);
1262 if (error)
1263 goto fail_gunlock2;
1264
1265 error = gfs2_inode_get(ghs[1].gh_gl, &ul->ul_ut.ut_inum, CREATE, &ip);
1266 if (error)
1267 goto fail_gunlock2;
1268
1269 error = gfs2_inode_refresh(ip);
1270 if (error)
1271 goto fail_iput;
1272
1273 error = gfs2_acl_create(dip, ip);
1274 if (error)
1275 goto fail_iput;
1276
1277 error = link_dinode(dip, name, ip, ul);
1278 if (error)
1279 goto fail_iput;
1280
1281 gfs2_unlinked_put(sdp, ul);
1282
Steven Whitehouse7359a192006-02-13 12:27:43 +00001283 inode = gfs2_ip2v(ip);
1284 gfs2_inode_put(ip);
1285 if (!inode)
1286 return ERR_PTR(-ENOMEM);
1287 return inode;
David Teiglandb3b94fa2006-01-16 16:50:04 +00001288
1289 fail_iput:
1290 gfs2_inode_put(ip);
1291
1292 fail_gunlock2:
1293 gfs2_glock_dq_uninit(ghs + 1);
1294
1295 fail_gunlock:
1296 gfs2_glock_dq(ghs);
1297
1298 fail:
1299 gfs2_unlinked_put(sdp, ul);
1300
Steven Whitehouse7359a192006-02-13 12:27:43 +00001301 return ERR_PTR(error);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001302}
1303
1304/**
1305 * gfs2_unlinki - Unlink a file
1306 * @dip: The inode of the directory
1307 * @name: The name of the file to be unlinked
1308 * @ip: The inode of the file to be removed
1309 *
1310 * Assumes Glocks on both dip and ip are held.
1311 *
1312 * Returns: errno
1313 */
1314
1315int gfs2_unlinki(struct gfs2_inode *dip, struct qstr *name,
1316 struct gfs2_inode *ip, struct gfs2_unlinked *ul)
1317{
1318 struct gfs2_sbd *sdp = dip->i_sbd;
1319 int error;
1320
1321 error = gfs2_dir_del(dip, name);
1322 if (error)
1323 return error;
1324
1325 error = gfs2_change_nlink(ip, -1);
1326 if (error)
1327 return error;
1328
1329 /* If this inode is being unlinked from the directory structure,
1330 we need to mark that in the log so that it isn't lost during
1331 a crash. */
1332
1333 if (!ip->i_di.di_nlink) {
1334 ul->ul_ut.ut_inum = ip->i_num;
1335 error = gfs2_unlinked_ondisk_add(sdp, ul);
1336 if (!error)
1337 set_bit(GLF_STICKY, &ip->i_gl->gl_flags);
1338 }
1339
1340 return error;
1341}
1342
1343/**
1344 * gfs2_rmdiri - Remove a directory
1345 * @dip: The parent directory of the directory to be removed
1346 * @name: The name of the directory to be removed
1347 * @ip: The GFS2 inode of the directory to be removed
1348 *
1349 * Assumes Glocks on dip and ip are held
1350 *
1351 * Returns: errno
1352 */
1353
1354int gfs2_rmdiri(struct gfs2_inode *dip, struct qstr *name,
1355 struct gfs2_inode *ip, struct gfs2_unlinked *ul)
1356{
1357 struct gfs2_sbd *sdp = dip->i_sbd;
1358 struct qstr dotname;
1359 int error;
1360
1361 if (ip->i_di.di_entries != 2) {
1362 if (gfs2_consist_inode(ip))
1363 gfs2_dinode_print(&ip->i_di);
1364 return -EIO;
1365 }
1366
1367 error = gfs2_dir_del(dip, name);
1368 if (error)
1369 return error;
1370
1371 error = gfs2_change_nlink(dip, -1);
1372 if (error)
1373 return error;
1374
Steven Whitehouse71b86f52006-03-28 14:14:04 -05001375 gfs2_str2qstr(&dotname, ".");
David Teiglandb3b94fa2006-01-16 16:50:04 +00001376 error = gfs2_dir_del(ip, &dotname);
1377 if (error)
1378 return error;
1379
1380 dotname.len = 2;
1381 dotname.name = "..";
Steven Whitehousec7526662006-03-20 12:30:04 -05001382 dotname.hash = gfs2_disk_hash(dotname.name, dotname.len);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001383 error = gfs2_dir_del(ip, &dotname);
1384 if (error)
1385 return error;
1386
1387 error = gfs2_change_nlink(ip, -2);
1388 if (error)
1389 return error;
1390
1391 /* This inode is being unlinked from the directory structure and
1392 we need to mark that in the log so that it isn't lost during
1393 a crash. */
1394
1395 ul->ul_ut.ut_inum = ip->i_num;
1396 error = gfs2_unlinked_ondisk_add(sdp, ul);
1397 if (!error)
1398 set_bit(GLF_STICKY, &ip->i_gl->gl_flags);
1399
1400 return error;
1401}
1402
1403/*
1404 * gfs2_unlink_ok - check to see that a inode is still in a directory
1405 * @dip: the directory
1406 * @name: the name of the file
1407 * @ip: the inode
1408 *
1409 * Assumes that the lock on (at least) @dip is held.
1410 *
1411 * Returns: 0 if the parent/child relationship is correct, errno if it isn't
1412 */
1413
1414int gfs2_unlink_ok(struct gfs2_inode *dip, struct qstr *name,
1415 struct gfs2_inode *ip)
1416{
1417 struct gfs2_inum inum;
1418 unsigned int type;
1419 int error;
1420
1421 if (IS_IMMUTABLE(ip->i_vnode) || IS_APPEND(ip->i_vnode))
1422 return -EPERM;
1423
1424 if ((dip->i_di.di_mode & S_ISVTX) &&
1425 dip->i_di.di_uid != current->fsuid &&
1426 ip->i_di.di_uid != current->fsuid &&
1427 !capable(CAP_FOWNER))
1428 return -EPERM;
1429
1430 if (IS_APPEND(dip->i_vnode))
1431 return -EPERM;
1432
1433 error = gfs2_repermission(dip->i_vnode, MAY_WRITE | MAY_EXEC, NULL);
1434 if (error)
1435 return error;
1436
Steven Whitehousec7526662006-03-20 12:30:04 -05001437 error = gfs2_dir_search(dip->i_vnode, name, &inum, &type);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001438 if (error)
1439 return error;
1440
1441 if (!gfs2_inum_equal(&inum, &ip->i_num))
1442 return -ENOENT;
1443
1444 if (IF2DT(ip->i_di.di_mode) != type) {
1445 gfs2_consist_inode(dip);
1446 return -EIO;
1447 }
1448
1449 return 0;
1450}
1451
1452/*
1453 * gfs2_ok_to_move - check if it's ok to move a directory to another directory
1454 * @this: move this
1455 * @to: to here
1456 *
1457 * Follow @to back to the root and make sure we don't encounter @this
1458 * Assumes we already hold the rename lock.
1459 *
1460 * Returns: errno
1461 */
1462
1463int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to)
1464{
Steven Whitehouse7359a192006-02-13 12:27:43 +00001465 struct inode *dir = to->i_vnode;
Steven Whitehousec9fd4302006-03-01 15:31:02 -05001466 struct super_block *sb = dir->i_sb;
Steven Whitehouse7359a192006-02-13 12:27:43 +00001467 struct inode *tmp;
David Teiglandb3b94fa2006-01-16 16:50:04 +00001468 struct qstr dotdot;
1469 int error = 0;
1470
Steven Whitehouse71b86f52006-03-28 14:14:04 -05001471 gfs2_str2qstr(&dotdot, "..");
David Teiglandb3b94fa2006-01-16 16:50:04 +00001472
Steven Whitehouse7359a192006-02-13 12:27:43 +00001473 igrab(dir);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001474
1475 for (;;) {
Steven Whitehouse7359a192006-02-13 12:27:43 +00001476 if (dir == this->i_vnode) {
David Teiglandb3b94fa2006-01-16 16:50:04 +00001477 error = -EINVAL;
1478 break;
1479 }
Steven Whitehousec9fd4302006-03-01 15:31:02 -05001480 if (dir == sb->s_root->d_inode) {
David Teiglandb3b94fa2006-01-16 16:50:04 +00001481 error = 0;
1482 break;
1483 }
1484
Steven Whitehousec7526662006-03-20 12:30:04 -05001485 tmp = gfs2_lookupi(dir, &dotdot, 1, NULL);
1486 if (IS_ERR(tmp)) {
1487 error = PTR_ERR(tmp);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001488 break;
Steven Whitehousec7526662006-03-20 12:30:04 -05001489 }
David Teiglandb3b94fa2006-01-16 16:50:04 +00001490
Steven Whitehouse7359a192006-02-13 12:27:43 +00001491 iput(dir);
1492 dir = tmp;
David Teiglandb3b94fa2006-01-16 16:50:04 +00001493 }
1494
Steven Whitehouse7359a192006-02-13 12:27:43 +00001495 iput(dir);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001496
1497 return error;
1498}
1499
1500/**
1501 * gfs2_readlinki - return the contents of a symlink
1502 * @ip: the symlink's inode
1503 * @buf: a pointer to the buffer to be filled
1504 * @len: a pointer to the length of @buf
1505 *
1506 * If @buf is too small, a piece of memory is kmalloc()ed and needs
1507 * to be freed by the caller.
1508 *
1509 * Returns: errno
1510 */
1511
1512int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len)
1513{
1514 struct gfs2_holder i_gh;
1515 struct buffer_head *dibh;
1516 unsigned int x;
1517 int error;
1518
1519 gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &i_gh);
1520 error = gfs2_glock_nq_atime(&i_gh);
1521 if (error) {
1522 gfs2_holder_uninit(&i_gh);
1523 return error;
1524 }
1525
1526 if (!ip->i_di.di_size) {
1527 gfs2_consist_inode(ip);
1528 error = -EIO;
1529 goto out;
1530 }
1531
1532 error = gfs2_meta_inode_buffer(ip, &dibh);
1533 if (error)
1534 goto out;
1535
1536 x = ip->i_di.di_size + 1;
1537 if (x > *len) {
1538 *buf = kmalloc(x, GFP_KERNEL);
1539 if (!*buf) {
1540 error = -ENOMEM;
1541 goto out_brelse;
1542 }
1543 }
1544
1545 memcpy(*buf, dibh->b_data + sizeof(struct gfs2_dinode), x);
1546 *len = x;
1547
1548 out_brelse:
1549 brelse(dibh);
1550
1551 out:
1552 gfs2_glock_dq_uninit(&i_gh);
1553
1554 return error;
1555}
1556
1557/**
1558 * gfs2_glock_nq_atime - Acquire a hold on an inode's glock, and
1559 * conditionally update the inode's atime
1560 * @gh: the holder to acquire
1561 *
1562 * Tests atime (access time) for gfs2_read, gfs2_readdir and gfs2_mmap
1563 * Update if the difference between the current time and the inode's current
1564 * atime is greater than an interval specified at mount.
1565 *
1566 * Returns: errno
1567 */
1568
1569int gfs2_glock_nq_atime(struct gfs2_holder *gh)
1570{
1571 struct gfs2_glock *gl = gh->gh_gl;
1572 struct gfs2_sbd *sdp = gl->gl_sbd;
Steven Whitehouse5c676f62006-02-27 17:23:27 -05001573 struct gfs2_inode *ip = gl->gl_object;
David Teiglandb3b94fa2006-01-16 16:50:04 +00001574 int64_t curtime, quantum = gfs2_tune_get(sdp, gt_atime_quantum);
1575 unsigned int state;
1576 int flags;
1577 int error;
1578
1579 if (gfs2_assert_warn(sdp, gh->gh_flags & GL_ATIME) ||
1580 gfs2_assert_warn(sdp, !(gh->gh_flags & GL_ASYNC)) ||
1581 gfs2_assert_warn(sdp, gl->gl_ops == &gfs2_inode_glops))
1582 return -EINVAL;
1583
1584 state = gh->gh_state;
1585 flags = gh->gh_flags;
1586
1587 error = gfs2_glock_nq(gh);
1588 if (error)
1589 return error;
1590
1591 if (test_bit(SDF_NOATIME, &sdp->sd_flags) ||
1592 (sdp->sd_vfs->s_flags & MS_RDONLY))
1593 return 0;
1594
1595 curtime = get_seconds();
1596 if (curtime - ip->i_di.di_atime >= quantum) {
1597 gfs2_glock_dq(gh);
Steven Whitehousefd88de562006-05-05 16:59:11 -04001598 gfs2_holder_reinit(LM_ST_EXCLUSIVE, gh->gh_flags & ~LM_FLAG_ANY,
1599 gh);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001600 error = gfs2_glock_nq(gh);
1601 if (error)
1602 return error;
1603
1604 /* Verify that atime hasn't been updated while we were
1605 trying to get exclusive lock. */
1606
1607 curtime = get_seconds();
1608 if (curtime - ip->i_di.di_atime >= quantum) {
1609 struct buffer_head *dibh;
1610
1611 error = gfs2_trans_begin(sdp, RES_DINODE, 0);
1612 if (error == -EROFS)
1613 return 0;
1614 if (error)
1615 goto fail;
1616
1617 error = gfs2_meta_inode_buffer(ip, &dibh);
1618 if (error)
1619 goto fail_end_trans;
1620
1621 ip->i_di.di_atime = curtime;
1622
Steven Whitehoused4e9c4c2006-01-18 11:19:28 +00001623 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001624 gfs2_dinode_out(&ip->i_di, dibh->b_data);
1625 brelse(dibh);
1626
1627 gfs2_trans_end(sdp);
1628 }
1629
1630 /* If someone else has asked for the glock,
1631 unlock and let them have it. Then reacquire
1632 in the original state. */
1633 if (gfs2_glock_is_blocking(gl)) {
1634 gfs2_glock_dq(gh);
1635 gfs2_holder_reinit(state, flags, gh);
1636 return gfs2_glock_nq(gh);
1637 }
1638 }
1639
1640 return 0;
1641
1642 fail_end_trans:
1643 gfs2_trans_end(sdp);
1644
1645 fail:
1646 gfs2_glock_dq(gh);
1647
1648 return error;
1649}
1650
1651/**
1652 * glock_compare_atime - Compare two struct gfs2_glock structures for sort
1653 * @arg_a: the first structure
1654 * @arg_b: the second structure
1655 *
1656 * Returns: 1 if A > B
1657 * -1 if A < B
1658 * 0 if A = B
1659 */
1660
1661static int glock_compare_atime(const void *arg_a, const void *arg_b)
1662{
1663 struct gfs2_holder *gh_a = *(struct gfs2_holder **)arg_a;
1664 struct gfs2_holder *gh_b = *(struct gfs2_holder **)arg_b;
1665 struct lm_lockname *a = &gh_a->gh_gl->gl_name;
1666 struct lm_lockname *b = &gh_b->gh_gl->gl_name;
1667 int ret = 0;
1668
1669 if (a->ln_number > b->ln_number)
1670 ret = 1;
1671 else if (a->ln_number < b->ln_number)
1672 ret = -1;
1673 else {
1674 if (gh_a->gh_state == LM_ST_SHARED &&
1675 gh_b->gh_state == LM_ST_EXCLUSIVE)
1676 ret = 1;
1677 else if (gh_a->gh_state == LM_ST_SHARED &&
1678 (gh_b->gh_flags & GL_ATIME))
1679 ret = 1;
1680 }
1681
1682 return ret;
1683}
1684
1685/**
1686 * gfs2_glock_nq_m_atime - acquire multiple glocks where one may need an
1687 * atime update
1688 * @num_gh: the number of structures
1689 * @ghs: an array of struct gfs2_holder structures
1690 *
1691 * Returns: 0 on success (all glocks acquired),
1692 * errno on failure (no glocks acquired)
1693 */
1694
1695int gfs2_glock_nq_m_atime(unsigned int num_gh, struct gfs2_holder *ghs)
1696{
1697 struct gfs2_holder **p;
1698 unsigned int x;
1699 int error = 0;
1700
1701 if (!num_gh)
1702 return 0;
1703
1704 if (num_gh == 1) {
1705 ghs->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC);
1706 if (ghs->gh_flags & GL_ATIME)
1707 error = gfs2_glock_nq_atime(ghs);
1708 else
1709 error = gfs2_glock_nq(ghs);
1710 return error;
1711 }
1712
1713 p = kcalloc(num_gh, sizeof(struct gfs2_holder *), GFP_KERNEL);
1714 if (!p)
1715 return -ENOMEM;
1716
1717 for (x = 0; x < num_gh; x++)
1718 p[x] = &ghs[x];
1719
1720 sort(p, num_gh, sizeof(struct gfs2_holder *), glock_compare_atime,NULL);
1721
1722 for (x = 0; x < num_gh; x++) {
1723 p[x]->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC);
1724
1725 if (p[x]->gh_flags & GL_ATIME)
1726 error = gfs2_glock_nq_atime(p[x]);
1727 else
1728 error = gfs2_glock_nq(p[x]);
1729
1730 if (error) {
1731 while (x--)
1732 gfs2_glock_dq(p[x]);
1733 break;
1734 }
1735 }
1736
1737 kfree(p);
1738
1739 return error;
1740}
1741
1742/**
1743 * gfs2_try_toss_vnode - See if we can toss a vnode from memory
1744 * @ip: the inode
1745 *
1746 * Returns: 1 if the vnode was tossed
1747 */
1748
1749void gfs2_try_toss_vnode(struct gfs2_inode *ip)
1750{
1751 struct inode *inode;
1752
1753 inode = gfs2_ip2v_lookup(ip);
1754 if (!inode)
1755 return;
1756
1757 d_prune_aliases(inode);
1758
1759 if (S_ISDIR(ip->i_di.di_mode)) {
1760 struct list_head *head = &inode->i_dentry;
1761 struct dentry *d = NULL;
1762
1763 spin_lock(&dcache_lock);
1764 if (list_empty(head))
1765 spin_unlock(&dcache_lock);
1766 else {
1767 d = list_entry(head->next, struct dentry, d_alias);
1768 dget_locked(d);
1769 spin_unlock(&dcache_lock);
1770
1771 if (have_submounts(d))
1772 dput(d);
1773 else {
1774 shrink_dcache_parent(d);
1775 dput(d);
1776 d_prune_aliases(inode);
1777 }
1778 }
1779 }
1780
1781 inode->i_nlink = 0;
1782 iput(inode);
1783}
1784
1785
1786static int
1787__gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr)
1788{
1789 struct buffer_head *dibh;
1790 int error;
1791
1792 error = gfs2_meta_inode_buffer(ip, &dibh);
1793 if (!error) {
1794 error = inode_setattr(ip->i_vnode, attr);
1795 gfs2_assert_warn(ip->i_sbd, !error);
1796 gfs2_inode_attr_out(ip);
1797
Steven Whitehoused4e9c4c2006-01-18 11:19:28 +00001798 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
David Teiglandb3b94fa2006-01-16 16:50:04 +00001799 gfs2_dinode_out(&ip->i_di, dibh->b_data);
1800 brelse(dibh);
1801 }
1802 return error;
1803}
1804
1805/**
1806 * gfs2_setattr_simple -
1807 * @ip:
1808 * @attr:
1809 *
1810 * Called with a reference on the vnode.
1811 *
1812 * Returns: errno
1813 */
1814
1815int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr)
1816{
1817 int error;
1818
Steven Whitehouse5c676f62006-02-27 17:23:27 -05001819 if (current->journal_info)
David Teiglandb3b94fa2006-01-16 16:50:04 +00001820 return __gfs2_setattr_simple(ip, attr);
1821
1822 error = gfs2_trans_begin(ip->i_sbd, RES_DINODE, 0);
1823 if (error)
1824 return error;
1825
1826 error = __gfs2_setattr_simple(ip, attr);
1827
1828 gfs2_trans_end(ip->i_sbd);
1829
1830 return error;
1831}
1832
1833int gfs2_repermission(struct inode *inode, int mask, struct nameidata *nd)
1834{
1835 return permission(inode, mask, nd);
1836}
1837