Blame view

fs/xfs/xfs_iget.c 19.2 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
  /*
7b7187698   Nathan Scott   [XFS] Update lice...
2
3
   * Copyright (c) 2000-2005 Silicon Graphics, Inc.
   * All Rights Reserved.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4
   *
7b7187698   Nathan Scott   [XFS] Update lice...
5
6
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public License as
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
7
8
   * published by the Free Software Foundation.
   *
7b7187698   Nathan Scott   [XFS] Update lice...
9
10
11
12
   * This program is distributed in the hope that it would be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
13
   *
7b7187698   Nathan Scott   [XFS] Update lice...
14
15
16
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write the Free Software Foundation,
   * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
17
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
18
  #include "xfs.h"
a844f4510   Nathan Scott   [XFS] Remove xfs_...
19
  #include "xfs_fs.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
20
  #include "xfs_types.h"
ef14f0c15   Christoph Hellwig   xfs: use generic ...
21
  #include "xfs_acl.h"
a844f4510   Nathan Scott   [XFS] Remove xfs_...
22
  #include "xfs_bit.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
23
  #include "xfs_log.h"
a844f4510   Nathan Scott   [XFS] Remove xfs_...
24
  #include "xfs_inum.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
25
26
27
  #include "xfs_trans.h"
  #include "xfs_sb.h"
  #include "xfs_ag.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
28
  #include "xfs_mount.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
29
  #include "xfs_bmap_btree.h"
a844f4510   Nathan Scott   [XFS] Remove xfs_...
30
  #include "xfs_alloc_btree.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
31
  #include "xfs_ialloc_btree.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
32
33
  #include "xfs_dinode.h"
  #include "xfs_inode.h"
a844f4510   Nathan Scott   [XFS] Remove xfs_...
34
35
  #include "xfs_btree.h"
  #include "xfs_ialloc.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
36
37
  #include "xfs_quota.h"
  #include "xfs_utils.h"
783a2f656   David Chinner   [XFS] Finish remo...
38
39
  #include "xfs_trans_priv.h"
  #include "xfs_inode_item.h"
24f211bad   Christoph Hellwig   [XFS] move inode ...
40
  #include "xfs_bmap.h"
0b1b213fc   Christoph Hellwig   xfs: event tracin...
41
  #include "xfs_trace.h"
24f211bad   Christoph Hellwig   [XFS] move inode ...
42
43
44
  
  
  /*
dcfcf2051   Dave Chinner   xfs: provide a in...
45
46
47
48
49
50
51
52
53
54
55
   * Define xfs inode iolock lockdep classes. We need to ensure that all active
   * inodes are considered the same for lockdep purposes, including inodes that
   * are recycled through the XFS_IRECLAIMABLE state. This is the the only way to
   * guarantee the locks are considered the same when there are multiple lock
   * initialisation siteѕ. Also, define a reclaimable inode class so it is
   * obvious in lockdep reports which class the report is against.
   */
  static struct lock_class_key xfs_iolock_active;
  struct lock_class_key xfs_iolock_reclaimable;
  
  /*
24f211bad   Christoph Hellwig   [XFS] move inode ...
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
   * Allocate and initialise an xfs_inode.
   */
  STATIC struct xfs_inode *
  xfs_inode_alloc(
  	struct xfs_mount	*mp,
  	xfs_ino_t		ino)
  {
  	struct xfs_inode	*ip;
  
  	/*
  	 * if this didn't occur in transactions, we could use
  	 * KM_MAYFAIL and return NULL here on ENOMEM. Set the
  	 * code up to do this anyway.
  	 */
  	ip = kmem_zone_alloc(xfs_inode_zone, KM_SLEEP);
  	if (!ip)
  		return NULL;
54e346215   Christoph Hellwig   vfs: fix inode_in...
73
74
75
76
  	if (inode_init_always(mp->m_super, VFS_I(ip))) {
  		kmem_zone_free(xfs_inode_zone, ip);
  		return NULL;
  	}
24f211bad   Christoph Hellwig   [XFS] move inode ...
77

24f211bad   Christoph Hellwig   [XFS] move inode ...
78
79
80
  	ASSERT(atomic_read(&ip->i_pincount) == 0);
  	ASSERT(!spin_is_locked(&ip->i_flags_lock));
  	ASSERT(completion_done(&ip->i_flush));
1a3e8f3da   Dave Chinner   xfs: convert inod...
81
  	ASSERT(ip->i_ino == 0);
033da48fd   Christoph Hellwig   xfs: reset the i_...
82
83
  
  	mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino);
dcfcf2051   Dave Chinner   xfs: provide a in...
84
85
  	lockdep_set_class_and_name(&ip->i_iolock.mr_lock,
  			&xfs_iolock_active, "xfs_iolock_active");
24f211bad   Christoph Hellwig   [XFS] move inode ...
86

24f211bad   Christoph Hellwig   [XFS] move inode ...
87
88
89
90
91
92
93
94
  	/* initialise the xfs inode */
  	ip->i_ino = ino;
  	ip->i_mount = mp;
  	memset(&ip->i_imap, 0, sizeof(struct xfs_imap));
  	ip->i_afp = NULL;
  	memset(&ip->i_df, 0, sizeof(xfs_ifork_t));
  	ip->i_flags = 0;
  	ip->i_update_core = 0;
24f211bad   Christoph Hellwig   [XFS] move inode ...
95
96
97
98
  	ip->i_delayed_blks = 0;
  	memset(&ip->i_d, 0, sizeof(xfs_icdinode_t));
  	ip->i_size = 0;
  	ip->i_new_size = 0;
24f211bad   Christoph Hellwig   [XFS] move inode ...
99
100
  	return ip;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
101

fa0d7e3de   Nick Piggin   fs: icache RCU fr...
102
103
104
105
106
107
  STATIC void
  xfs_inode_free_callback(
  	struct rcu_head		*head)
  {
  	struct inode		*inode = container_of(head, struct inode, i_rcu);
  	struct xfs_inode	*ip = XFS_I(inode);
fa0d7e3de   Nick Piggin   fs: icache RCU fr...
108
109
  	kmem_zone_free(xfs_inode_zone, ip);
  }
2f11feabb   Dave Chinner   xfs: simplify and...
110
  void
b36ec0428   Christoph Hellwig   xfs: fix freeing ...
111
112
113
114
115
116
117
118
119
120
121
122
123
  xfs_inode_free(
  	struct xfs_inode	*ip)
  {
  	switch (ip->i_d.di_mode & S_IFMT) {
  	case S_IFREG:
  	case S_IFDIR:
  	case S_IFLNK:
  		xfs_idestroy_fork(ip, XFS_DATA_FORK);
  		break;
  	}
  
  	if (ip->i_afp)
  		xfs_idestroy_fork(ip, XFS_ATTR_FORK);
b36ec0428   Christoph Hellwig   xfs: fix freeing ...
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
  	if (ip->i_itemp) {
  		/*
  		 * Only if we are shutting down the fs will we see an
  		 * inode still in the AIL. If it is there, we should remove
  		 * it to prevent a use-after-free from occurring.
  		 */
  		xfs_log_item_t	*lip = &ip->i_itemp->ili_item;
  		struct xfs_ail	*ailp = lip->li_ailp;
  
  		ASSERT(((lip->li_flags & XFS_LI_IN_AIL) == 0) ||
  				       XFS_FORCED_SHUTDOWN(ip->i_mount));
  		if (lip->li_flags & XFS_LI_IN_AIL) {
  			spin_lock(&ailp->xa_lock);
  			if (lip->li_flags & XFS_LI_IN_AIL)
  				xfs_trans_ail_delete(ailp, lip);
  			else
  				spin_unlock(&ailp->xa_lock);
  		}
  		xfs_inode_item_destroy(ip);
  		ip->i_itemp = NULL;
  	}
  
  	/* asserts to verify all state is correct here */
b36ec0428   Christoph Hellwig   xfs: fix freeing ...
147
148
149
  	ASSERT(atomic_read(&ip->i_pincount) == 0);
  	ASSERT(!spin_is_locked(&ip->i_flags_lock));
  	ASSERT(completion_done(&ip->i_flush));
1a3e8f3da   Dave Chinner   xfs: convert inod...
150
151
152
153
154
155
156
157
158
159
  	/*
  	 * Because we use RCU freeing we need to ensure the inode always
  	 * appears to be reclaimed with an invalid inode number when in the
  	 * free state. The ip->i_flags_lock provides the barrier against lookup
  	 * races.
  	 */
  	spin_lock(&ip->i_flags_lock);
  	ip->i_flags = XFS_IRECLAIM;
  	ip->i_ino = 0;
  	spin_unlock(&ip->i_flags_lock);
92f1c008a   Alex Elder   Merge branch 'mas...
160
161
  
  	call_rcu(&VFS_I(ip)->i_rcu, xfs_inode_free_callback);
b36ec0428   Christoph Hellwig   xfs: fix freeing ...
162
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
163
  /*
6441e5491   David Chinner   [XFS] factor xfs_...
164
   * Check the validity of the inode we just found it the cache
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
165
   */
6441e5491   David Chinner   [XFS] factor xfs_...
166
167
  static int
  xfs_iget_cache_hit(
6441e5491   David Chinner   [XFS] factor xfs_...
168
169
  	struct xfs_perag	*pag,
  	struct xfs_inode	*ip,
1a3e8f3da   Dave Chinner   xfs: convert inod...
170
  	xfs_ino_t		ino,
6441e5491   David Chinner   [XFS] factor xfs_...
171
  	int			flags,
1a3e8f3da   Dave Chinner   xfs: convert inod...
172
  	int			lock_flags) __releases(RCU)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
173
  {
bc990f5cb   Christoph Hellwig   xfs: fix locking ...
174
  	struct inode		*inode = VFS_I(ip);
6441e5491   David Chinner   [XFS] factor xfs_...
175
  	struct xfs_mount	*mp = ip->i_mount;
bc990f5cb   Christoph Hellwig   xfs: fix locking ...
176
  	int			error;
1a3e8f3da   Dave Chinner   xfs: convert inod...
177
178
179
180
181
182
183
  	/*
  	 * check for re-use of an inode within an RCU grace period due to the
  	 * radix tree nodes not being updated yet. We monitor for this by
  	 * setting the inode number to zero before freeing the inode structure.
  	 * If the inode has been reallocated and set up, then the inode number
  	 * will not match, so check for that, too.
  	 */
bc990f5cb   Christoph Hellwig   xfs: fix locking ...
184
  	spin_lock(&ip->i_flags_lock);
1a3e8f3da   Dave Chinner   xfs: convert inod...
185
186
187
188
189
190
  	if (ip->i_ino != ino) {
  		trace_xfs_iget_skip(ip);
  		XFS_STATS_INC(xs_ig_frecycle);
  		error = EAGAIN;
  		goto out_error;
  	}
da353b0d6   David Chinner   [XFS] Radix tree ...
191

6441e5491   David Chinner   [XFS] factor xfs_...
192
  	/*
bc990f5cb   Christoph Hellwig   xfs: fix locking ...
193
194
195
196
197
198
199
200
  	 * If we are racing with another cache hit that is currently
  	 * instantiating this inode or currently recycling it out of
  	 * reclaimabe state, wait for the initialisation to complete
  	 * before continuing.
  	 *
  	 * XXX(hch): eventually we should do something equivalent to
  	 *	     wait_on_inode to wait for these flags to be cleared
  	 *	     instead of polling for it.
6441e5491   David Chinner   [XFS] factor xfs_...
201
  	 */
bc990f5cb   Christoph Hellwig   xfs: fix locking ...
202
  	if (ip->i_flags & (XFS_INEW|XFS_IRECLAIM)) {
0b1b213fc   Christoph Hellwig   xfs: event tracin...
203
  		trace_xfs_iget_skip(ip);
6441e5491   David Chinner   [XFS] factor xfs_...
204
  		XFS_STATS_INC(xs_ig_frecycle);
bc990f5cb   Christoph Hellwig   xfs: fix locking ...
205
  		error = EAGAIN;
6441e5491   David Chinner   [XFS] factor xfs_...
206
207
  		goto out_error;
  	}
da353b0d6   David Chinner   [XFS] Radix tree ...
208

bc990f5cb   Christoph Hellwig   xfs: fix locking ...
209
210
211
212
213
214
215
  	/*
  	 * If lookup is racing with unlink return an error immediately.
  	 */
  	if (ip->i_d.di_mode == 0 && !(flags & XFS_IGET_CREATE)) {
  		error = ENOENT;
  		goto out_error;
  	}
bf904248a   David Chinner   [XFS] Combine the...
216

bc990f5cb   Christoph Hellwig   xfs: fix locking ...
217
218
219
220
221
  	/*
  	 * If IRECLAIMABLE is set, we've torn down the VFS inode already.
  	 * Need to carefully get it back into useable state.
  	 */
  	if (ip->i_flags & XFS_IRECLAIMABLE) {
0b1b213fc   Christoph Hellwig   xfs: event tracin...
222
  		trace_xfs_iget_reclaim(ip);
da353b0d6   David Chinner   [XFS] Radix tree ...
223

6441e5491   David Chinner   [XFS] factor xfs_...
224
  		/*
f1f724e4b   Christoph Hellwig   xfs: fix locking ...
225
226
227
228
  		 * We need to set XFS_IRECLAIM to prevent xfs_reclaim_inode
  		 * from stomping over us while we recycle the inode.  We can't
  		 * clear the radix tree reclaimable tag yet as it requires
  		 * pag_ici_lock to be held exclusive.
6441e5491   David Chinner   [XFS] factor xfs_...
229
  		 */
f1f724e4b   Christoph Hellwig   xfs: fix locking ...
230
  		ip->i_flags |= XFS_IRECLAIM;
bc990f5cb   Christoph Hellwig   xfs: fix locking ...
231
232
  
  		spin_unlock(&ip->i_flags_lock);
1a3e8f3da   Dave Chinner   xfs: convert inod...
233
  		rcu_read_unlock();
bc990f5cb   Christoph Hellwig   xfs: fix locking ...
234
235
236
237
238
239
240
  
  		error = -inode_init_always(mp->m_super, inode);
  		if (error) {
  			/*
  			 * Re-initializing the inode failed, and we are in deep
  			 * trouble.  Try to re-add it to the reclaim list.
  			 */
1a3e8f3da   Dave Chinner   xfs: convert inod...
241
  			rcu_read_lock();
bc990f5cb   Christoph Hellwig   xfs: fix locking ...
242
  			spin_lock(&ip->i_flags_lock);
778e24bb6   Dave Chinner   xfs: reset inode ...
243
244
  			ip->i_flags &= ~(XFS_INEW | XFS_IRECLAIM);
  			ASSERT(ip->i_flags & XFS_IRECLAIMABLE);
d2e078c33   Christoph Hellwig   xfs: some iget tr...
245
  			trace_xfs_iget_reclaim_fail(ip);
6441e5491   David Chinner   [XFS] factor xfs_...
246
  			goto out_error;
da353b0d6   David Chinner   [XFS] Radix tree ...
247
  		}
f1f724e4b   Christoph Hellwig   xfs: fix locking ...
248

1a427ab0c   Dave Chinner   xfs: convert pag_...
249
  		spin_lock(&pag->pag_ici_lock);
f1f724e4b   Christoph Hellwig   xfs: fix locking ...
250
  		spin_lock(&ip->i_flags_lock);
778e24bb6   Dave Chinner   xfs: reset inode ...
251
252
253
254
255
256
257
  
  		/*
  		 * Clear the per-lifetime state in the inode as we are now
  		 * effectively a new inode and need to return to the initial
  		 * state before reuse occurs.
  		 */
  		ip->i_flags &= ~XFS_IRECLAIM_RESET_FLAGS;
f1f724e4b   Christoph Hellwig   xfs: fix locking ...
258
259
  		ip->i_flags |= XFS_INEW;
  		__xfs_inode_clear_reclaim_tag(mp, pag, ip);
eaff8079d   Christoph Hellwig   kill I_LOCK
260
  		inode->i_state = I_NEW;
dcfcf2051   Dave Chinner   xfs: provide a in...
261
262
263
264
265
  
  		ASSERT(!rwsem_is_locked(&ip->i_iolock.mr_lock));
  		mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino);
  		lockdep_set_class_and_name(&ip->i_iolock.mr_lock,
  				&xfs_iolock_active, "xfs_iolock_active");
f1f724e4b   Christoph Hellwig   xfs: fix locking ...
266
  		spin_unlock(&ip->i_flags_lock);
1a427ab0c   Dave Chinner   xfs: convert pag_...
267
  		spin_unlock(&pag->pag_ici_lock);
bc990f5cb   Christoph Hellwig   xfs: fix locking ...
268
  	} else {
bf904248a   David Chinner   [XFS] Combine the...
269
  		/* If the VFS inode is being torn down, pause and try again. */
bc990f5cb   Christoph Hellwig   xfs: fix locking ...
270
  		if (!igrab(inode)) {
d2e078c33   Christoph Hellwig   xfs: some iget tr...
271
  			trace_xfs_iget_skip(ip);
bc990f5cb   Christoph Hellwig   xfs: fix locking ...
272
273
274
  			error = EAGAIN;
  			goto out_error;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
275

bc990f5cb   Christoph Hellwig   xfs: fix locking ...
276
277
  		/* We've got a live one. */
  		spin_unlock(&ip->i_flags_lock);
1a3e8f3da   Dave Chinner   xfs: convert inod...
278
  		rcu_read_unlock();
d2e078c33   Christoph Hellwig   xfs: some iget tr...
279
  		trace_xfs_iget_hit(ip);
6441e5491   David Chinner   [XFS] factor xfs_...
280
  	}
da353b0d6   David Chinner   [XFS] Radix tree ...
281

6441e5491   David Chinner   [XFS] factor xfs_...
282
283
  	if (lock_flags != 0)
  		xfs_ilock(ip, lock_flags);
da353b0d6   David Chinner   [XFS] Radix tree ...
284

6441e5491   David Chinner   [XFS] factor xfs_...
285
  	xfs_iflags_clear(ip, XFS_ISTALE);
6441e5491   David Chinner   [XFS] factor xfs_...
286
  	XFS_STATS_INC(xs_ig_found);
0b1b213fc   Christoph Hellwig   xfs: event tracin...
287

6441e5491   David Chinner   [XFS] factor xfs_...
288
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
289

6441e5491   David Chinner   [XFS] factor xfs_...
290
  out_error:
bc990f5cb   Christoph Hellwig   xfs: fix locking ...
291
  	spin_unlock(&ip->i_flags_lock);
1a3e8f3da   Dave Chinner   xfs: convert inod...
292
  	rcu_read_unlock();
6441e5491   David Chinner   [XFS] factor xfs_...
293
294
295
296
297
298
299
300
301
302
303
  	return error;
  }
  
  
  static int
  xfs_iget_cache_miss(
  	struct xfs_mount	*mp,
  	struct xfs_perag	*pag,
  	xfs_trans_t		*tp,
  	xfs_ino_t		ino,
  	struct xfs_inode	**ipp,
6441e5491   David Chinner   [XFS] factor xfs_...
304
  	int			flags,
0c3dc2b02   Christoph Hellwig   xfs: remove incor...
305
  	int			lock_flags)
6441e5491   David Chinner   [XFS] factor xfs_...
306
307
308
  {
  	struct xfs_inode	*ip;
  	int			error;
6441e5491   David Chinner   [XFS] factor xfs_...
309
  	xfs_agino_t		agino = XFS_INO_TO_AGINO(mp, ino);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
310

24f211bad   Christoph Hellwig   [XFS] move inode ...
311
312
313
  	ip = xfs_inode_alloc(mp, ino);
  	if (!ip)
  		return ENOMEM;
7b6259e7a   Dave Chinner   xfs: remove block...
314
  	error = xfs_iread(mp, tp, ip, flags);
6441e5491   David Chinner   [XFS] factor xfs_...
315
  	if (error)
24f211bad   Christoph Hellwig   [XFS] move inode ...
316
  		goto out_destroy;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
317

d2e078c33   Christoph Hellwig   xfs: some iget tr...
318
  	trace_xfs_iget_miss(ip);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
319

745b1f47f   Nathan Scott   [XFS] Remove last...
320
  	if ((ip->i_d.di_mode == 0) && !(flags & XFS_IGET_CREATE)) {
6441e5491   David Chinner   [XFS] factor xfs_...
321
322
  		error = ENOENT;
  		goto out_destroy;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
323
324
325
  	}
  
  	/*
bad558433   David Chinner   [XFS] Remove the ...
326
  	 * Preload the radix tree so we can insert safely under the
56e73ec47   David Chinner   [XFS] Can't lock ...
327
328
  	 * write spinlock. Note that we cannot sleep inside the preload
  	 * region.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
329
  	 */
da353b0d6   David Chinner   [XFS] Radix tree ...
330
  	if (radix_tree_preload(GFP_KERNEL)) {
6441e5491   David Chinner   [XFS] factor xfs_...
331
  		error = EAGAIN;
ed93ec390   Christoph Hellwig   xfs: prevent lock...
332
333
334
335
336
337
338
339
340
341
  		goto out_destroy;
  	}
  
  	/*
  	 * Because the inode hasn't been added to the radix-tree yet it can't
  	 * be found by another thread, so we can do the non-sleeping lock here.
  	 */
  	if (lock_flags) {
  		if (!xfs_ilock_nowait(ip, lock_flags))
  			BUG();
da353b0d6   David Chinner   [XFS] Radix tree ...
342
  	}
f338f9036   Lachlan McIlroy   [XFS] Unlock inod...
343

1a427ab0c   Dave Chinner   xfs: convert pag_...
344
  	spin_lock(&pag->pag_ici_lock);
6441e5491   David Chinner   [XFS] factor xfs_...
345
346
  
  	/* insert the new inode */
da353b0d6   David Chinner   [XFS] Radix tree ...
347
348
  	error = radix_tree_insert(&pag->pag_ici_root, agino, ip);
  	if (unlikely(error)) {
6441e5491   David Chinner   [XFS] factor xfs_...
349
  		WARN_ON(error != -EEXIST);
da353b0d6   David Chinner   [XFS] Radix tree ...
350
  		XFS_STATS_INC(xs_ig_dup);
6441e5491   David Chinner   [XFS] factor xfs_...
351
  		error = EAGAIN;
56e73ec47   David Chinner   [XFS] Can't lock ...
352
  		goto out_preload_end;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
353
  	}
6441e5491   David Chinner   [XFS] factor xfs_...
354
  	/* These values _must_ be set before releasing the radix tree lock! */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
355
  	ip->i_udquot = ip->i_gdquot = NULL;
7a18c3860   David Chinner   [XFS] Clean up i_...
356
  	xfs_iflags_set(ip, XFS_INEW);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
357

1a427ab0c   Dave Chinner   xfs: convert pag_...
358
  	spin_unlock(&pag->pag_ici_lock);
da353b0d6   David Chinner   [XFS] Radix tree ...
359
  	radix_tree_preload_end();
0b1b213fc   Christoph Hellwig   xfs: event tracin...
360

6441e5491   David Chinner   [XFS] factor xfs_...
361
362
  	*ipp = ip;
  	return 0;
56e73ec47   David Chinner   [XFS] Can't lock ...
363
  out_preload_end:
1a427ab0c   Dave Chinner   xfs: convert pag_...
364
  	spin_unlock(&pag->pag_ici_lock);
6441e5491   David Chinner   [XFS] factor xfs_...
365
  	radix_tree_preload_end();
56e73ec47   David Chinner   [XFS] Can't lock ...
366
367
  	if (lock_flags)
  		xfs_iunlock(ip, lock_flags);
6441e5491   David Chinner   [XFS] factor xfs_...
368
  out_destroy:
b36ec0428   Christoph Hellwig   xfs: fix freeing ...
369
370
  	__destroy_inode(VFS_I(ip));
  	xfs_inode_free(ip);
6441e5491   David Chinner   [XFS] factor xfs_...
371
372
373
374
375
376
  	return error;
  }
  
  /*
   * Look up an inode by number in the given file system.
   * The inode is looked up in the cache held in each AG.
bf904248a   David Chinner   [XFS] Combine the...
377
378
   * If the inode is found in the cache, initialise the vfs inode
   * if necessary.
6441e5491   David Chinner   [XFS] factor xfs_...
379
380
   *
   * If it is not in core, read it in from the file system's device,
bf904248a   David Chinner   [XFS] Combine the...
381
   * add it to the cache and initialise the vfs inode.
6441e5491   David Chinner   [XFS] factor xfs_...
382
383
384
385
386
387
388
389
390
391
392
393
394
   *
   * The inode is locked according to the value of the lock_flags parameter.
   * This flag parameter indicates how and if the inode's IO lock and inode lock
   * should be taken.
   *
   * mp -- the mount point structure for the current file system.  It points
   *       to the inode hash table.
   * tp -- a pointer to the current transaction if there is one.  This is
   *       simply passed through to the xfs_iread() call.
   * ino -- the number of the inode desired.  This is the unique identifier
   *        within the file system for the inode being requested.
   * lock_flags -- flags indicating how to lock the inode.  See the comment
   *		 for xfs_ilock() for a list of valid values.
6441e5491   David Chinner   [XFS] factor xfs_...
395
   */
bf904248a   David Chinner   [XFS] Combine the...
396
397
  int
  xfs_iget(
6441e5491   David Chinner   [XFS] factor xfs_...
398
399
400
401
402
  	xfs_mount_t	*mp,
  	xfs_trans_t	*tp,
  	xfs_ino_t	ino,
  	uint		flags,
  	uint		lock_flags,
7b6259e7a   Dave Chinner   xfs: remove block...
403
  	xfs_inode_t	**ipp)
6441e5491   David Chinner   [XFS] factor xfs_...
404
405
406
407
408
  {
  	xfs_inode_t	*ip;
  	int		error;
  	xfs_perag_t	*pag;
  	xfs_agino_t	agino;
d276734d9   Christoph Hellwig   xfs: fix bogus m_...
409
  	/* reject inode numbers outside existing AGs */
1a3e8f3da   Dave Chinner   xfs: convert inod...
410
  	if (!ino || XFS_INO_TO_AGNO(mp, ino) >= mp->m_sb.sb_agcount)
6441e5491   David Chinner   [XFS] factor xfs_...
411
412
413
  		return EINVAL;
  
  	/* get the perag structure and ensure that it's inode capable */
5017e97d5   Dave Chinner   xfs: rename xfs_g...
414
  	pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ino));
6441e5491   David Chinner   [XFS] factor xfs_...
415
416
417
418
  	agino = XFS_INO_TO_AGINO(mp, ino);
  
  again:
  	error = 0;
1a3e8f3da   Dave Chinner   xfs: convert inod...
419
  	rcu_read_lock();
6441e5491   David Chinner   [XFS] factor xfs_...
420
421
422
  	ip = radix_tree_lookup(&pag->pag_ici_root, agino);
  
  	if (ip) {
1a3e8f3da   Dave Chinner   xfs: convert inod...
423
  		error = xfs_iget_cache_hit(pag, ip, ino, flags, lock_flags);
6441e5491   David Chinner   [XFS] factor xfs_...
424
425
426
  		if (error)
  			goto out_error_or_again;
  	} else {
1a3e8f3da   Dave Chinner   xfs: convert inod...
427
  		rcu_read_unlock();
6441e5491   David Chinner   [XFS] factor xfs_...
428
  		XFS_STATS_INC(xs_ig_missed);
7b6259e7a   Dave Chinner   xfs: remove block...
429
  		error = xfs_iget_cache_miss(mp, pag, tp, ino, &ip,
6441e5491   David Chinner   [XFS] factor xfs_...
430
431
432
433
  							flags, lock_flags);
  		if (error)
  			goto out_error_or_again;
  	}
5017e97d5   Dave Chinner   xfs: rename xfs_g...
434
  	xfs_perag_put(pag);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
435

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
436
  	*ipp = ip;
bf904248a   David Chinner   [XFS] Combine the...
437
438
  	ASSERT(ip->i_df.if_ext_max ==
  	       XFS_IFORK_DSIZE(ip) / sizeof(xfs_bmbt_rec_t));
41be8bed1   Christoph Hellwig   [XFS] sanitize xf...
439
  	/*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
440
441
442
  	 * If we have a real type for an on-disk inode, we can set ops(&unlock)
  	 * now.	 If it's a new inode being created, xfs_ialloc will handle it.
  	 */
bf904248a   David Chinner   [XFS] Combine the...
443
  	if (xfs_iflags_test(ip, XFS_INEW) && ip->i_d.di_mode != 0)
41be8bed1   Christoph Hellwig   [XFS] sanitize xf...
444
  		xfs_setup_inode(ip);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
445
  	return 0;
6441e5491   David Chinner   [XFS] factor xfs_...
446
447
448
449
450
451
  
  out_error_or_again:
  	if (error == EAGAIN) {
  		delay(1);
  		goto again;
  	}
5017e97d5   Dave Chinner   xfs: rename xfs_g...
452
  	xfs_perag_put(pag);
6441e5491   David Chinner   [XFS] factor xfs_...
453
  	return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
454
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
455
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
   * This is a wrapper routine around the xfs_ilock() routine
   * used to centralize some grungy code.  It is used in places
   * that wish to lock the inode solely for reading the extents.
   * The reason these places can't just call xfs_ilock(SHARED)
   * is that the inode lock also guards to bringing in of the
   * extents from disk for a file in b-tree format.  If the inode
   * is in b-tree format, then we need to lock the inode exclusively
   * until the extents are read in.  Locking it exclusively all
   * the time would limit our parallelism unnecessarily, though.
   * What we do instead is check to see if the extents have been
   * read in yet, and only lock the inode exclusively if they
   * have not.
   *
   * The function returns a value which should be given to the
   * corresponding xfs_iunlock_map_shared().  This value is
   * the mode in which the lock was actually taken.
   */
  uint
  xfs_ilock_map_shared(
  	xfs_inode_t	*ip)
  {
  	uint	lock_mode;
  
  	if ((ip->i_d.di_format == XFS_DINODE_FMT_BTREE) &&
  	    ((ip->i_df.if_flags & XFS_IFEXTENTS) == 0)) {
  		lock_mode = XFS_ILOCK_EXCL;
  	} else {
  		lock_mode = XFS_ILOCK_SHARED;
  	}
  
  	xfs_ilock(ip, lock_mode);
  
  	return lock_mode;
  }
  
  /*
   * This is simply the unlock routine to go with xfs_ilock_map_shared().
   * All it does is call xfs_iunlock() with the given lock_mode.
   */
  void
  xfs_iunlock_map_shared(
  	xfs_inode_t	*ip,
  	unsigned int	lock_mode)
  {
  	xfs_iunlock(ip, lock_mode);
  }
  
  /*
   * The xfs inode contains 2 locks: a multi-reader lock called the
   * i_iolock and a multi-reader lock called the i_lock.  This routine
   * allows either or both of the locks to be obtained.
   *
   * The 2 locks should always be ordered so that the IO lock is
   * obtained first in order to prevent deadlock.
   *
   * ip -- the inode being locked
   * lock_flags -- this parameter indicates the inode's locks
   *       to be locked.  It can be:
   *		XFS_IOLOCK_SHARED,
   *		XFS_IOLOCK_EXCL,
   *		XFS_ILOCK_SHARED,
   *		XFS_ILOCK_EXCL,
   *		XFS_IOLOCK_SHARED | XFS_ILOCK_SHARED,
   *		XFS_IOLOCK_SHARED | XFS_ILOCK_EXCL,
   *		XFS_IOLOCK_EXCL | XFS_ILOCK_SHARED,
   *		XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL
   */
  void
579aa9caf   Christoph Hellwig   [XFS] shrink mrlo...
524
525
526
  xfs_ilock(
  	xfs_inode_t		*ip,
  	uint			lock_flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
527
528
529
530
531
532
533
534
535
536
  {
  	/*
  	 * You can't set both SHARED and EXCL for the same lock,
  	 * and only XFS_IOLOCK_SHARED, XFS_IOLOCK_EXCL, XFS_ILOCK_SHARED,
  	 * and XFS_ILOCK_EXCL are valid values to set in lock_flags.
  	 */
  	ASSERT((lock_flags & (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)) !=
  	       (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL));
  	ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) !=
  	       (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
f7c66ce3f   Lachlan McIlroy   [XFS] Add lockdep...
537
  	ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_LOCK_DEP_MASK)) == 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
538

579aa9caf   Christoph Hellwig   [XFS] shrink mrlo...
539
  	if (lock_flags & XFS_IOLOCK_EXCL)
f7c66ce3f   Lachlan McIlroy   [XFS] Add lockdep...
540
  		mrupdate_nested(&ip->i_iolock, XFS_IOLOCK_DEP(lock_flags));
579aa9caf   Christoph Hellwig   [XFS] shrink mrlo...
541
  	else if (lock_flags & XFS_IOLOCK_SHARED)
f7c66ce3f   Lachlan McIlroy   [XFS] Add lockdep...
542
  		mraccess_nested(&ip->i_iolock, XFS_IOLOCK_DEP(lock_flags));
579aa9caf   Christoph Hellwig   [XFS] shrink mrlo...
543
544
  
  	if (lock_flags & XFS_ILOCK_EXCL)
f7c66ce3f   Lachlan McIlroy   [XFS] Add lockdep...
545
  		mrupdate_nested(&ip->i_lock, XFS_ILOCK_DEP(lock_flags));
579aa9caf   Christoph Hellwig   [XFS] shrink mrlo...
546
  	else if (lock_flags & XFS_ILOCK_SHARED)
f7c66ce3f   Lachlan McIlroy   [XFS] Add lockdep...
547
  		mraccess_nested(&ip->i_lock, XFS_ILOCK_DEP(lock_flags));
579aa9caf   Christoph Hellwig   [XFS] shrink mrlo...
548

0b1b213fc   Christoph Hellwig   xfs: event tracin...
549
  	trace_xfs_ilock(ip, lock_flags, _RET_IP_);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
550
551
552
553
554
555
556
557
558
559
560
561
562
  }
  
  /*
   * This is just like xfs_ilock(), except that the caller
   * is guaranteed not to sleep.  It returns 1 if it gets
   * the requested locks and 0 otherwise.  If the IO lock is
   * obtained but the inode lock cannot be, then the IO lock
   * is dropped before returning.
   *
   * ip -- the inode being locked
   * lock_flags -- this parameter indicates the inode's locks to be
   *       to be locked.  See the comment for xfs_ilock() for a list
   *	 of valid values.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
563
564
   */
  int
579aa9caf   Christoph Hellwig   [XFS] shrink mrlo...
565
566
567
  xfs_ilock_nowait(
  	xfs_inode_t		*ip,
  	uint			lock_flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
568
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
569
570
571
572
573
574
575
576
577
  	/*
  	 * You can't set both SHARED and EXCL for the same lock,
  	 * and only XFS_IOLOCK_SHARED, XFS_IOLOCK_EXCL, XFS_ILOCK_SHARED,
  	 * and XFS_ILOCK_EXCL are valid values to set in lock_flags.
  	 */
  	ASSERT((lock_flags & (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)) !=
  	       (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL));
  	ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) !=
  	       (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
f7c66ce3f   Lachlan McIlroy   [XFS] Add lockdep...
578
  	ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_LOCK_DEP_MASK)) == 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
579

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
580
  	if (lock_flags & XFS_IOLOCK_EXCL) {
579aa9caf   Christoph Hellwig   [XFS] shrink mrlo...
581
582
  		if (!mrtryupdate(&ip->i_iolock))
  			goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
583
  	} else if (lock_flags & XFS_IOLOCK_SHARED) {
579aa9caf   Christoph Hellwig   [XFS] shrink mrlo...
584
585
  		if (!mrtryaccess(&ip->i_iolock))
  			goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
586
587
  	}
  	if (lock_flags & XFS_ILOCK_EXCL) {
579aa9caf   Christoph Hellwig   [XFS] shrink mrlo...
588
589
  		if (!mrtryupdate(&ip->i_lock))
  			goto out_undo_iolock;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
590
  	} else if (lock_flags & XFS_ILOCK_SHARED) {
579aa9caf   Christoph Hellwig   [XFS] shrink mrlo...
591
592
  		if (!mrtryaccess(&ip->i_lock))
  			goto out_undo_iolock;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
593
  	}
0b1b213fc   Christoph Hellwig   xfs: event tracin...
594
  	trace_xfs_ilock_nowait(ip, lock_flags, _RET_IP_);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
595
  	return 1;
579aa9caf   Christoph Hellwig   [XFS] shrink mrlo...
596
597
598
599
600
601
602
603
  
   out_undo_iolock:
  	if (lock_flags & XFS_IOLOCK_EXCL)
  		mrunlock_excl(&ip->i_iolock);
  	else if (lock_flags & XFS_IOLOCK_SHARED)
  		mrunlock_shared(&ip->i_iolock);
   out:
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
  }
  
  /*
   * xfs_iunlock() is used to drop the inode locks acquired with
   * xfs_ilock() and xfs_ilock_nowait().  The caller must pass
   * in the flags given to xfs_ilock() or xfs_ilock_nowait() so
   * that we know which locks to drop.
   *
   * ip -- the inode being unlocked
   * lock_flags -- this parameter indicates the inode's locks to be
   *       to be unlocked.  See the comment for xfs_ilock() for a list
   *	 of valid values for this parameter.
   *
   */
  void
579aa9caf   Christoph Hellwig   [XFS] shrink mrlo...
619
620
621
  xfs_iunlock(
  	xfs_inode_t		*ip,
  	uint			lock_flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
622
623
624
625
626
627
628
629
630
631
  {
  	/*
  	 * You can't set both SHARED and EXCL for the same lock,
  	 * and only XFS_IOLOCK_SHARED, XFS_IOLOCK_EXCL, XFS_ILOCK_SHARED,
  	 * and XFS_ILOCK_EXCL are valid values to set in lock_flags.
  	 */
  	ASSERT((lock_flags & (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)) !=
  	       (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL));
  	ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) !=
  	       (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
f7c66ce3f   Lachlan McIlroy   [XFS] Add lockdep...
632
633
  	ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_IUNLOCK_NONOTIFY |
  			XFS_LOCK_DEP_MASK)) == 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
634
  	ASSERT(lock_flags != 0);
579aa9caf   Christoph Hellwig   [XFS] shrink mrlo...
635
636
637
638
  	if (lock_flags & XFS_IOLOCK_EXCL)
  		mrunlock_excl(&ip->i_iolock);
  	else if (lock_flags & XFS_IOLOCK_SHARED)
  		mrunlock_shared(&ip->i_iolock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
639

579aa9caf   Christoph Hellwig   [XFS] shrink mrlo...
640
641
642
643
  	if (lock_flags & XFS_ILOCK_EXCL)
  		mrunlock_excl(&ip->i_lock);
  	else if (lock_flags & XFS_ILOCK_SHARED)
  		mrunlock_shared(&ip->i_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
644

579aa9caf   Christoph Hellwig   [XFS] shrink mrlo...
645
646
  	if ((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) &&
  	    !(lock_flags & XFS_IUNLOCK_NONOTIFY) && ip->i_itemp) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
647
648
649
650
651
  		/*
  		 * Let the AIL know that this item has been unlocked in case
  		 * it is in the AIL and anyone is waiting on it.  Don't do
  		 * this if the caller has asked us not to.
  		 */
783a2f656   David Chinner   [XFS] Finish remo...
652
  		xfs_trans_unlocked_item(ip->i_itemp->ili_item.li_ailp,
579aa9caf   Christoph Hellwig   [XFS] shrink mrlo...
653
  					(xfs_log_item_t*)(ip->i_itemp));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
654
  	}
0b1b213fc   Christoph Hellwig   xfs: event tracin...
655
  	trace_xfs_iunlock(ip, lock_flags, _RET_IP_);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
656
657
658
659
660
661
662
  }
  
  /*
   * give up write locks.  the i/o lock cannot be held nested
   * if it is being demoted.
   */
  void
579aa9caf   Christoph Hellwig   [XFS] shrink mrlo...
663
664
665
  xfs_ilock_demote(
  	xfs_inode_t		*ip,
  	uint			lock_flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
666
667
668
  {
  	ASSERT(lock_flags & (XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL));
  	ASSERT((lock_flags & ~(XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL)) == 0);
579aa9caf   Christoph Hellwig   [XFS] shrink mrlo...
669
  	if (lock_flags & XFS_ILOCK_EXCL)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
670
  		mrdemote(&ip->i_lock);
579aa9caf   Christoph Hellwig   [XFS] shrink mrlo...
671
  	if (lock_flags & XFS_IOLOCK_EXCL)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
672
  		mrdemote(&ip->i_iolock);
0b1b213fc   Christoph Hellwig   xfs: event tracin...
673
674
  
  	trace_xfs_ilock_demote(ip, lock_flags, _RET_IP_);
579aa9caf   Christoph Hellwig   [XFS] shrink mrlo...
675
676
677
  }
  
  #ifdef DEBUG
579aa9caf   Christoph Hellwig   [XFS] shrink mrlo...
678
679
680
681
682
  int
  xfs_isilocked(
  	xfs_inode_t		*ip,
  	uint			lock_flags)
  {
f93697294   Christoph Hellwig   xfs: improve xfs_...
683
684
685
686
  	if (lock_flags & (XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)) {
  		if (!(lock_flags & XFS_ILOCK_SHARED))
  			return !!ip->i_lock.mr_writer;
  		return rwsem_is_locked(&ip->i_lock.mr_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
687
  	}
579aa9caf   Christoph Hellwig   [XFS] shrink mrlo...
688

f93697294   Christoph Hellwig   xfs: improve xfs_...
689
690
691
692
  	if (lock_flags & (XFS_IOLOCK_EXCL|XFS_IOLOCK_SHARED)) {
  		if (!(lock_flags & XFS_IOLOCK_SHARED))
  			return !!ip->i_iolock.mr_writer;
  		return rwsem_is_locked(&ip->i_iolock.mr_lock);
579aa9caf   Christoph Hellwig   [XFS] shrink mrlo...
693
  	}
f93697294   Christoph Hellwig   xfs: improve xfs_...
694
695
  	ASSERT(0);
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
696
  }
579aa9caf   Christoph Hellwig   [XFS] shrink mrlo...
697
  #endif