~ubuntu-branches/debian/wheezy/linux-2.6/wheezy

« back to all changes in this revision

Viewing changes to fs/xfs/xfs_iget.c

  • Committer: Bazaar Package Importer
  • Author(s): Ben Hutchings, Ben Hutchings, Aurelien Jarno, Martin Michlmayr
  • Date: 2011-04-06 13:53:30 UTC
  • mfrom: (43.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20110406135330-wjufxhd0tvn3zx4z
Tags: 2.6.38-3
[ Ben Hutchings ]
* [ppc64] Add to linux-tools package architectures (Closes: #620124)
* [amd64] Save cr4 to mmu_cr4_features at boot time (Closes: #620284)
* appletalk: Fix bugs introduced when removing use of BKL
* ALSA: Fix yet another race in disconnection
* cciss: Fix lost command issue
* ath9k: Fix kernel panic in AR2427
* ses: Avoid kernel panic when lun 0 is not mapped
* PCI/ACPI: Report ASPM support to BIOS if not disabled from command line

[ Aurelien Jarno ]
* rtlwifi: fix build when PCI is not enabled.

[ Martin Michlmayr ]
* rtlwifi: Eliminate udelay calls with too large values (Closes: #620204)

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
#include "xfs_trans.h"
26
26
#include "xfs_sb.h"
27
27
#include "xfs_ag.h"
28
 
#include "xfs_dir2.h"
29
 
#include "xfs_dmapi.h"
30
28
#include "xfs_mount.h"
31
29
#include "xfs_bmap_btree.h"
32
30
#include "xfs_alloc_btree.h"
33
31
#include "xfs_ialloc_btree.h"
34
 
#include "xfs_dir2_sf.h"
35
 
#include "xfs_attr_sf.h"
36
32
#include "xfs_dinode.h"
37
33
#include "xfs_inode.h"
38
34
#include "xfs_btree.h"
43
39
#include "xfs_inode_item.h"
44
40
#include "xfs_bmap.h"
45
41
#include "xfs_btree_trace.h"
46
 
#include "xfs_dir2_trace.h"
47
 
 
 
42
#include "xfs_trace.h"
 
43
 
 
44
 
 
45
/*
 
46
 * Define xfs inode iolock lockdep classes. We need to ensure that all active
 
47
 * inodes are considered the same for lockdep purposes, including inodes that
 
48
 * are recycled through the XFS_IRECLAIMABLE state. This is the the only way to
 
49
 * guarantee the locks are considered the same when there are multiple lock
 
50
 * initialisation siteѕ. Also, define a reclaimable inode class so it is
 
51
 * obvious in lockdep reports which class the report is against.
 
52
 */
 
53
static struct lock_class_key xfs_iolock_active;
 
54
struct lock_class_key xfs_iolock_reclaimable;
48
55
 
49
56
/*
50
57
 * Allocate and initialise an xfs_inode.
73
80
        ASSERT(atomic_read(&ip->i_pincount) == 0);
74
81
        ASSERT(!spin_is_locked(&ip->i_flags_lock));
75
82
        ASSERT(completion_done(&ip->i_flush));
 
83
        ASSERT(ip->i_ino == 0);
 
84
 
 
85
        mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino);
 
86
        lockdep_set_class_and_name(&ip->i_iolock.mr_lock,
 
87
                        &xfs_iolock_active, "xfs_iolock_active");
76
88
 
77
89
        /* initialise the xfs inode */
78
90
        ip->i_ino = ino;
87
99
        ip->i_size = 0;
88
100
        ip->i_new_size = 0;
89
101
 
90
 
        /*
91
 
         * Initialize inode's trace buffers.
92
 
         */
93
 
#ifdef  XFS_INODE_TRACE
94
 
        ip->i_trace = ktrace_alloc(INODE_TRACE_SIZE, KM_NOFS);
95
 
#endif
96
 
#ifdef XFS_BMAP_TRACE
97
 
        ip->i_xtrace = ktrace_alloc(XFS_BMAP_KTRACE_SIZE, KM_NOFS);
98
 
#endif
99
 
#ifdef XFS_BTREE_TRACE
100
 
        ip->i_btrace = ktrace_alloc(XFS_BMBT_KTRACE_SIZE, KM_NOFS);
101
 
#endif
102
 
#ifdef XFS_RW_TRACE
103
 
        ip->i_rwtrace = ktrace_alloc(XFS_RW_KTRACE_SIZE, KM_NOFS);
104
 
#endif
105
 
#ifdef XFS_ILOCK_TRACE
106
 
        ip->i_lock_trace = ktrace_alloc(XFS_ILOCK_KTRACE_SIZE, KM_NOFS);
107
 
#endif
108
 
#ifdef XFS_DIR2_TRACE
109
 
        ip->i_dir_trace = ktrace_alloc(XFS_DIR2_KTRACE_SIZE, KM_NOFS);
110
 
#endif
111
 
 
112
 
        /* prevent anyone from using this yet */
113
 
        VFS_I(ip)->i_state = I_NEW|I_LOCK;
114
 
 
115
102
        return ip;
116
103
}
117
104
 
118
105
STATIC void
 
106
xfs_inode_free_callback(
 
107
        struct rcu_head         *head)
 
108
{
 
109
        struct inode            *inode = container_of(head, struct inode, i_rcu);
 
110
        struct xfs_inode        *ip = XFS_I(inode);
 
111
 
 
112
        INIT_LIST_HEAD(&inode->i_dentry);
 
113
        kmem_zone_free(xfs_inode_zone, ip);
 
114
}
 
115
 
 
116
void
119
117
xfs_inode_free(
120
118
        struct xfs_inode        *ip)
121
119
{
130
128
        if (ip->i_afp)
131
129
                xfs_idestroy_fork(ip, XFS_ATTR_FORK);
132
130
 
133
 
#ifdef XFS_INODE_TRACE
134
 
        ktrace_free(ip->i_trace);
135
 
#endif
136
 
#ifdef XFS_BMAP_TRACE
137
 
        ktrace_free(ip->i_xtrace);
138
 
#endif
139
 
#ifdef XFS_BTREE_TRACE
140
 
        ktrace_free(ip->i_btrace);
141
 
#endif
142
 
#ifdef XFS_RW_TRACE
143
 
        ktrace_free(ip->i_rwtrace);
144
 
#endif
145
 
#ifdef XFS_ILOCK_TRACE
146
 
        ktrace_free(ip->i_lock_trace);
147
 
#endif
148
 
#ifdef XFS_DIR2_TRACE
149
 
        ktrace_free(ip->i_dir_trace);
150
 
#endif
151
 
 
152
131
        if (ip->i_itemp) {
153
132
                /*
154
133
                 * Only if we are shutting down the fs will we see an
177
156
        ASSERT(!spin_is_locked(&ip->i_flags_lock));
178
157
        ASSERT(completion_done(&ip->i_flush));
179
158
 
180
 
        kmem_zone_free(xfs_inode_zone, ip);
 
159
        /*
 
160
         * Because we use RCU freeing we need to ensure the inode always
 
161
         * appears to be reclaimed with an invalid inode number when in the
 
162
         * free state. The ip->i_flags_lock provides the barrier against lookup
 
163
         * races.
 
164
         */
 
165
        spin_lock(&ip->i_flags_lock);
 
166
        ip->i_flags = XFS_IRECLAIM;
 
167
        ip->i_ino = 0;
 
168
        spin_unlock(&ip->i_flags_lock);
 
169
 
 
170
        call_rcu(&VFS_I(ip)->i_rcu, xfs_inode_free_callback);
181
171
}
182
172
 
183
173
/*
187
177
xfs_iget_cache_hit(
188
178
        struct xfs_perag        *pag,
189
179
        struct xfs_inode        *ip,
 
180
        xfs_ino_t               ino,
190
181
        int                     flags,
191
 
        int                     lock_flags) __releases(pag->pag_ici_lock)
 
182
        int                     lock_flags) __releases(RCU)
192
183
{
193
184
        struct inode            *inode = VFS_I(ip);
194
185
        struct xfs_mount        *mp = ip->i_mount;
195
186
        int                     error;
196
187
 
 
188
        /*
 
189
         * check for re-use of an inode within an RCU grace period due to the
 
190
         * radix tree nodes not being updated yet. We monitor for this by
 
191
         * setting the inode number to zero before freeing the inode structure.
 
192
         * If the inode has been reallocated and set up, then the inode number
 
193
         * will not match, so check for that, too.
 
194
         */
197
195
        spin_lock(&ip->i_flags_lock);
 
196
        if (ip->i_ino != ino) {
 
197
                trace_xfs_iget_skip(ip);
 
198
                XFS_STATS_INC(xs_ig_frecycle);
 
199
                error = EAGAIN;
 
200
                goto out_error;
 
201
        }
 
202
 
198
203
 
199
204
        /*
200
205
         * If we are racing with another cache hit that is currently
207
212
         *           instead of polling for it.
208
213
         */
209
214
        if (ip->i_flags & (XFS_INEW|XFS_IRECLAIM)) {
 
215
                trace_xfs_iget_skip(ip);
210
216
                XFS_STATS_INC(xs_ig_frecycle);
211
217
                error = EAGAIN;
212
218
                goto out_error;
225
231
         * Need to carefully get it back into useable state.
226
232
         */
227
233
        if (ip->i_flags & XFS_IRECLAIMABLE) {
228
 
                xfs_itrace_exit_tag(ip, "xfs_iget.alloc");
 
234
                trace_xfs_iget_reclaim(ip);
229
235
 
230
236
                /*
231
 
                 * We need to set XFS_INEW atomically with clearing the
232
 
                 * reclaimable tag so that we do have an indicator of the
233
 
                 * inode still being initialized.
 
237
                 * We need to set XFS_IRECLAIM to prevent xfs_reclaim_inode
 
238
                 * from stomping over us while we recycle the inode.  We can't
 
239
                 * clear the radix tree reclaimable tag yet as it requires
 
240
                 * pag_ici_lock to be held exclusive.
234
241
                 */
235
 
                ip->i_flags |= XFS_INEW;
236
 
                ip->i_flags &= ~XFS_IRECLAIMABLE;
237
 
                __xfs_inode_clear_reclaim_tag(mp, pag, ip);
 
242
                ip->i_flags |= XFS_IRECLAIM;
238
243
 
239
244
                spin_unlock(&ip->i_flags_lock);
240
 
                read_unlock(&pag->pag_ici_lock);
 
245
                rcu_read_unlock();
241
246
 
242
247
                error = -inode_init_always(mp->m_super, inode);
243
248
                if (error) {
245
250
                         * Re-initializing the inode failed, and we are in deep
246
251
                         * trouble.  Try to re-add it to the reclaim list.
247
252
                         */
248
 
                        read_lock(&pag->pag_ici_lock);
 
253
                        rcu_read_lock();
249
254
                        spin_lock(&ip->i_flags_lock);
250
255
 
251
256
                        ip->i_flags &= ~XFS_INEW;
252
257
                        ip->i_flags |= XFS_IRECLAIMABLE;
253
258
                        __xfs_inode_set_reclaim_tag(pag, ip);
 
259
                        trace_xfs_iget_reclaim_fail(ip);
254
260
                        goto out_error;
255
261
                }
256
 
                inode->i_state = I_LOCK|I_NEW;
 
262
 
 
263
                spin_lock(&pag->pag_ici_lock);
 
264
                spin_lock(&ip->i_flags_lock);
 
265
                ip->i_flags &= ~(XFS_IRECLAIMABLE | XFS_IRECLAIM);
 
266
                ip->i_flags |= XFS_INEW;
 
267
                __xfs_inode_clear_reclaim_tag(mp, pag, ip);
 
268
                inode->i_state = I_NEW;
 
269
 
 
270
                ASSERT(!rwsem_is_locked(&ip->i_iolock.mr_lock));
 
271
                mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino);
 
272
                lockdep_set_class_and_name(&ip->i_iolock.mr_lock,
 
273
                                &xfs_iolock_active, "xfs_iolock_active");
 
274
 
 
275
                spin_unlock(&ip->i_flags_lock);
 
276
                spin_unlock(&pag->pag_ici_lock);
257
277
        } else {
258
278
                /* If the VFS inode is being torn down, pause and try again. */
259
279
                if (!igrab(inode)) {
 
280
                        trace_xfs_iget_skip(ip);
260
281
                        error = EAGAIN;
261
282
                        goto out_error;
262
283
                }
263
284
 
264
285
                /* We've got a live one. */
265
286
                spin_unlock(&ip->i_flags_lock);
266
 
                read_unlock(&pag->pag_ici_lock);
 
287
                rcu_read_unlock();
 
288
                trace_xfs_iget_hit(ip);
267
289
        }
268
290
 
269
291
        if (lock_flags != 0)
270
292
                xfs_ilock(ip, lock_flags);
271
293
 
272
294
        xfs_iflags_clear(ip, XFS_ISTALE);
273
 
        xfs_itrace_exit_tag(ip, "xfs_iget.found");
274
295
        XFS_STATS_INC(xs_ig_found);
 
296
 
275
297
        return 0;
276
298
 
277
299
out_error:
278
300
        spin_unlock(&ip->i_flags_lock);
279
 
        read_unlock(&pag->pag_ici_lock);
 
301
        rcu_read_unlock();
280
302
        return error;
281
303
}
282
304
 
288
310
        xfs_trans_t             *tp,
289
311
        xfs_ino_t               ino,
290
312
        struct xfs_inode        **ipp,
291
 
        xfs_daddr_t             bno,
292
313
        int                     flags,
293
 
        int                     lock_flags) __releases(pag->pag_ici_lock)
 
314
        int                     lock_flags)
294
315
{
295
316
        struct xfs_inode        *ip;
296
317
        int                     error;
297
 
        unsigned long           first_index, mask;
298
318
        xfs_agino_t             agino = XFS_INO_TO_AGINO(mp, ino);
299
319
 
300
320
        ip = xfs_inode_alloc(mp, ino);
301
321
        if (!ip)
302
322
                return ENOMEM;
303
323
 
304
 
        error = xfs_iread(mp, tp, ip, bno, flags);
 
324
        error = xfs_iread(mp, tp, ip, flags);
305
325
        if (error)
306
326
                goto out_destroy;
307
327
 
308
 
        xfs_itrace_exit_tag(ip, "xfs_iget.alloc");
 
328
        trace_xfs_iget_miss(ip);
309
329
 
310
330
        if ((ip->i_d.di_mode == 0) && !(flags & XFS_IGET_CREATE)) {
311
331
                error = ENOENT;
331
351
                        BUG();
332
352
        }
333
353
 
334
 
        mask = ~(((XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog)) - 1);
335
 
        first_index = agino & mask;
336
 
        write_lock(&pag->pag_ici_lock);
 
354
        spin_lock(&pag->pag_ici_lock);
337
355
 
338
356
        /* insert the new inode */
339
357
        error = radix_tree_insert(&pag->pag_ici_root, agino, ip);
348
366
        ip->i_udquot = ip->i_gdquot = NULL;
349
367
        xfs_iflags_set(ip, XFS_INEW);
350
368
 
351
 
        write_unlock(&pag->pag_ici_lock);
 
369
        spin_unlock(&pag->pag_ici_lock);
352
370
        radix_tree_preload_end();
 
371
 
353
372
        *ipp = ip;
354
373
        return 0;
355
374
 
356
375
out_preload_end:
357
 
        write_unlock(&pag->pag_ici_lock);
 
376
        spin_unlock(&pag->pag_ici_lock);
358
377
        radix_tree_preload_end();
359
378
        if (lock_flags)
360
379
                xfs_iunlock(ip, lock_flags);
385
404
 *        within the file system for the inode being requested.
386
405
 * lock_flags -- flags indicating how to lock the inode.  See the comment
387
406
 *               for xfs_ilock() for a list of valid values.
388
 
 * bno -- the block number starting the buffer containing the inode,
389
 
 *        if known (as by bulkstat), else 0.
390
407
 */
391
408
int
392
409
xfs_iget(
395
412
        xfs_ino_t       ino,
396
413
        uint            flags,
397
414
        uint            lock_flags,
398
 
        xfs_inode_t     **ipp,
399
 
        xfs_daddr_t     bno)
 
415
        xfs_inode_t     **ipp)
400
416
{
401
417
        xfs_inode_t     *ip;
402
418
        int             error;
403
419
        xfs_perag_t     *pag;
404
420
        xfs_agino_t     agino;
405
421
 
406
 
        /* the radix tree exists only in inode capable AGs */
407
 
        if (XFS_INO_TO_AGNO(mp, ino) >= mp->m_maxagi)
 
422
        /* reject inode numbers outside existing AGs */
 
423
        if (!ino || XFS_INO_TO_AGNO(mp, ino) >= mp->m_sb.sb_agcount)
408
424
                return EINVAL;
409
425
 
410
426
        /* get the perag structure and ensure that it's inode capable */
411
 
        pag = xfs_get_perag(mp, ino);
412
 
        if (!pag->pagi_inodeok)
413
 
                return EINVAL;
414
 
        ASSERT(pag->pag_ici_init);
 
427
        pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ino));
415
428
        agino = XFS_INO_TO_AGINO(mp, ino);
416
429
 
417
430
again:
418
431
        error = 0;
419
 
        read_lock(&pag->pag_ici_lock);
 
432
        rcu_read_lock();
420
433
        ip = radix_tree_lookup(&pag->pag_ici_root, agino);
421
434
 
422
435
        if (ip) {
423
 
                error = xfs_iget_cache_hit(pag, ip, flags, lock_flags);
 
436
                error = xfs_iget_cache_hit(pag, ip, ino, flags, lock_flags);
424
437
                if (error)
425
438
                        goto out_error_or_again;
426
439
        } else {
427
 
                read_unlock(&pag->pag_ici_lock);
 
440
                rcu_read_unlock();
428
441
                XFS_STATS_INC(xs_ig_missed);
429
442
 
430
 
                error = xfs_iget_cache_miss(mp, pag, tp, ino, &ip, bno,
 
443
                error = xfs_iget_cache_miss(mp, pag, tp, ino, &ip,
431
444
                                                        flags, lock_flags);
432
445
                if (error)
433
446
                        goto out_error_or_again;
434
447
        }
435
 
        xfs_put_perag(mp, pag);
 
448
        xfs_perag_put(pag);
436
449
 
437
450
        *ipp = ip;
438
451
 
451
464
                delay(1);
452
465
                goto again;
453
466
        }
454
 
        xfs_put_perag(mp, pag);
 
467
        xfs_perag_put(pag);
455
468
        return error;
456
469
}
457
470
 
458
471
/*
459
 
 * Decrement reference count of an inode structure and unlock it.
460
 
 *
461
 
 * ip -- the inode being released
462
 
 * lock_flags -- this parameter indicates the inode's locks to be
463
 
 *       to be released.  See the comment on xfs_iunlock() for a list
464
 
 *       of valid values.
465
 
 */
466
 
void
467
 
xfs_iput(xfs_inode_t    *ip,
468
 
         uint           lock_flags)
469
 
{
470
 
        xfs_itrace_entry(ip);
471
 
        xfs_iunlock(ip, lock_flags);
472
 
        IRELE(ip);
473
 
}
474
 
 
475
 
/*
476
 
 * Special iput for brand-new inodes that are still locked
477
 
 */
478
 
void
479
 
xfs_iput_new(
480
 
        xfs_inode_t     *ip,
481
 
        uint            lock_flags)
482
 
{
483
 
        struct inode    *inode = VFS_I(ip);
484
 
 
485
 
        xfs_itrace_entry(ip);
486
 
 
487
 
        if ((ip->i_d.di_mode == 0)) {
488
 
                ASSERT(!xfs_iflags_test(ip, XFS_IRECLAIMABLE));
489
 
                make_bad_inode(inode);
490
 
        }
491
 
        if (inode->i_state & I_NEW)
492
 
                unlock_new_inode(inode);
493
 
        if (lock_flags)
494
 
                xfs_iunlock(ip, lock_flags);
495
 
        IRELE(ip);
496
 
}
497
 
 
498
 
/*
499
 
 * This is called free all the memory associated with an inode.
500
 
 * It must free the inode itself and any buffers allocated for
501
 
 * if_extents/if_data and if_broot.  It must also free the lock
502
 
 * associated with the inode.
503
 
 *
504
 
 * Note: because we don't initialise everything on reallocation out
505
 
 * of the zone, we must ensure we nullify everything correctly before
506
 
 * freeing the structure.
507
 
 */
508
 
void
509
 
xfs_ireclaim(
510
 
        struct xfs_inode        *ip)
511
 
{
512
 
        struct xfs_mount        *mp = ip->i_mount;
513
 
        struct xfs_perag        *pag;
514
 
 
515
 
        XFS_STATS_INC(xs_ig_reclaims);
516
 
 
517
 
        /*
518
 
         * Remove the inode from the per-AG radix tree.  It doesn't matter
519
 
         * if it was never added to it because radix_tree_delete can deal
520
 
         * with that case just fine.
521
 
         */
522
 
        pag = xfs_get_perag(mp, ip->i_ino);
523
 
        write_lock(&pag->pag_ici_lock);
524
 
        radix_tree_delete(&pag->pag_ici_root, XFS_INO_TO_AGINO(mp, ip->i_ino));
525
 
        write_unlock(&pag->pag_ici_lock);
526
 
        xfs_put_perag(mp, pag);
527
 
 
528
 
        /*
529
 
         * Here we do an (almost) spurious inode lock in order to coordinate
530
 
         * with inode cache radix tree lookups.  This is because the lookup
531
 
         * can reference the inodes in the cache without taking references.
532
 
         *
533
 
         * We make that OK here by ensuring that we wait until the inode is
534
 
         * unlocked after the lookup before we go ahead and free it.  We get
535
 
         * both the ilock and the iolock because the code may need to drop the
536
 
         * ilock one but will still hold the iolock.
537
 
         */
538
 
        xfs_ilock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
539
 
        xfs_qm_dqdetach(ip);
540
 
        xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
541
 
 
542
 
        xfs_inode_free(ip);
543
 
}
544
 
 
545
 
/*
546
472
 * This is a wrapper routine around the xfs_ilock() routine
547
473
 * used to centralize some grungy code.  It is used in places
548
474
 * that wish to lock the inode solely for reading the extents.
636
562
        else if (lock_flags & XFS_ILOCK_SHARED)
637
563
                mraccess_nested(&ip->i_lock, XFS_ILOCK_DEP(lock_flags));
638
564
 
639
 
        xfs_ilock_trace(ip, 1, lock_flags, (inst_t *)__return_address);
 
565
        trace_xfs_ilock(ip, lock_flags, _RET_IP_);
640
566
}
641
567
 
642
568
/*
681
607
                if (!mrtryaccess(&ip->i_lock))
682
608
                        goto out_undo_iolock;
683
609
        }
684
 
        xfs_ilock_trace(ip, 2, lock_flags, (inst_t *)__return_address);
 
610
        trace_xfs_ilock_nowait(ip, lock_flags, _RET_IP_);
685
611
        return 1;
686
612
 
687
613
 out_undo_iolock:
743
669
                xfs_trans_unlocked_item(ip->i_itemp->ili_item.li_ailp,
744
670
                                        (xfs_log_item_t*)(ip->i_itemp));
745
671
        }
746
 
        xfs_ilock_trace(ip, 3, lock_flags, (inst_t *)__return_address);
 
672
        trace_xfs_iunlock(ip, lock_flags, _RET_IP_);
747
673
}
748
674
 
749
675
/*
762
688
                mrdemote(&ip->i_lock);
763
689
        if (lock_flags & XFS_IOLOCK_EXCL)
764
690
                mrdemote(&ip->i_iolock);
 
691
 
 
692
        trace_xfs_ilock_demote(ip, lock_flags, _RET_IP_);
765
693
}
766
694
 
767
695
#ifdef DEBUG
768
 
/*
769
 
 * Debug-only routine, without additional rw_semaphore APIs, we can
770
 
 * now only answer requests regarding whether we hold the lock for write
771
 
 * (reader state is outside our visibility, we only track writer state).
772
 
 *
773
 
 * Note: this means !xfs_isilocked would give false positives, so don't do that.
774
 
 */
775
696
int
776
697
xfs_isilocked(
777
698
        xfs_inode_t             *ip,
778
699
        uint                    lock_flags)
779
700
{
780
 
        if ((lock_flags & (XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)) ==
781
 
                        XFS_ILOCK_EXCL) {
782
 
                if (!ip->i_lock.mr_writer)
783
 
                        return 0;
784
 
        }
785
 
 
786
 
        if ((lock_flags & (XFS_IOLOCK_EXCL|XFS_IOLOCK_SHARED)) ==
787
 
                        XFS_IOLOCK_EXCL) {
788
 
                if (!ip->i_iolock.mr_writer)
789
 
                        return 0;
790
 
        }
791
 
 
792
 
        return 1;
 
701
        if (lock_flags & (XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)) {
 
702
                if (!(lock_flags & XFS_ILOCK_SHARED))
 
703
                        return !!ip->i_lock.mr_writer;
 
704
                return rwsem_is_locked(&ip->i_lock.mr_lock);
 
705
        }
 
706
 
 
707
        if (lock_flags & (XFS_IOLOCK_EXCL|XFS_IOLOCK_SHARED)) {
 
708
                if (!(lock_flags & XFS_IOLOCK_SHARED))
 
709
                        return !!ip->i_iolock.mr_writer;
 
710
                return rwsem_is_locked(&ip->i_iolock.mr_lock);
 
711
        }
 
712
 
 
713
        ASSERT(0);
 
714
        return 0;
793
715
}
794
716
#endif
795
 
 
796
 
#ifdef  XFS_INODE_TRACE
797
 
 
798
 
#define KTRACE_ENTER(ip, vk, s, line, ra)                       \
799
 
        ktrace_enter((ip)->i_trace,                             \
800
 
/*  0 */                (void *)(__psint_t)(vk),                \
801
 
/*  1 */                (void *)(s),                            \
802
 
/*  2 */                (void *)(__psint_t) line,               \
803
 
/*  3 */                (void *)(__psint_t)atomic_read(&VFS_I(ip)->i_count), \
804
 
/*  4 */                (void *)(ra),                           \
805
 
/*  5 */                NULL,                                   \
806
 
/*  6 */                (void *)(__psint_t)current_cpu(),       \
807
 
/*  7 */                (void *)(__psint_t)current_pid(),       \
808
 
/*  8 */                (void *)__return_address,               \
809
 
/*  9 */                NULL, NULL, NULL, NULL, NULL, NULL, NULL)
810
 
 
811
 
/*
812
 
 * Vnode tracing code.
813
 
 */
814
 
void
815
 
_xfs_itrace_entry(xfs_inode_t *ip, const char *func, inst_t *ra)
816
 
{
817
 
        KTRACE_ENTER(ip, INODE_KTRACE_ENTRY, func, 0, ra);
818
 
}
819
 
 
820
 
void
821
 
_xfs_itrace_exit(xfs_inode_t *ip, const char *func, inst_t *ra)
822
 
{
823
 
        KTRACE_ENTER(ip, INODE_KTRACE_EXIT, func, 0, ra);
824
 
}
825
 
 
826
 
void
827
 
xfs_itrace_hold(xfs_inode_t *ip, char *file, int line, inst_t *ra)
828
 
{
829
 
        KTRACE_ENTER(ip, INODE_KTRACE_HOLD, file, line, ra);
830
 
}
831
 
 
832
 
void
833
 
_xfs_itrace_ref(xfs_inode_t *ip, char *file, int line, inst_t *ra)
834
 
{
835
 
        KTRACE_ENTER(ip, INODE_KTRACE_REF, file, line, ra);
836
 
}
837
 
 
838
 
void
839
 
xfs_itrace_rele(xfs_inode_t *ip, char *file, int line, inst_t *ra)
840
 
{
841
 
        KTRACE_ENTER(ip, INODE_KTRACE_RELE, file, line, ra);
842
 
}
843
 
#endif  /* XFS_INODE_TRACE */