[XFS] kill deleted inodes list
[linux-2.6] / fs / xfs / xfs_iget.c
1 /*
2  * Copyright (c) 2000-2005 Silicon Graphics, Inc.
3  * All Rights Reserved.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it would be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write the Free Software Foundation,
16  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18 #include "xfs.h"
19 #include "xfs_fs.h"
20 #include "xfs_types.h"
21 #include "xfs_bit.h"
22 #include "xfs_log.h"
23 #include "xfs_inum.h"
24 #include "xfs_trans.h"
25 #include "xfs_sb.h"
26 #include "xfs_ag.h"
27 #include "xfs_dir2.h"
28 #include "xfs_dmapi.h"
29 #include "xfs_mount.h"
30 #include "xfs_bmap_btree.h"
31 #include "xfs_alloc_btree.h"
32 #include "xfs_ialloc_btree.h"
33 #include "xfs_dir2_sf.h"
34 #include "xfs_attr_sf.h"
35 #include "xfs_dinode.h"
36 #include "xfs_inode.h"
37 #include "xfs_btree.h"
38 #include "xfs_ialloc.h"
39 #include "xfs_quota.h"
40 #include "xfs_utils.h"
41
42 /*
43  * Check the validity of the inode we just found it the cache
44  */
45 static int
46 xfs_iget_cache_hit(
47         struct xfs_perag        *pag,
48         struct xfs_inode        *ip,
49         int                     flags,
50         int                     lock_flags) __releases(pag->pag_ici_lock)
51 {
52         struct xfs_mount        *mp = ip->i_mount;
53         int                     error = 0;
54
55         /*
56          * If INEW is set this inode is being set up
57          * If IRECLAIM is set this inode is being torn down
58          * Pause and try again.
59          */
60         if (xfs_iflags_test(ip, (XFS_INEW|XFS_IRECLAIM))) {
61                 error = EAGAIN;
62                 XFS_STATS_INC(xs_ig_frecycle);
63                 goto out_error;
64         }
65
66         /* If IRECLAIMABLE is set, we've torn down the vfs inode part */
67         if (xfs_iflags_test(ip, XFS_IRECLAIMABLE)) {
68
69                 /*
70                  * If lookup is racing with unlink, then we should return an
71                  * error immediately so we don't remove it from the reclaim
72                  * list and potentially leak the inode.
73                  */
74
75                 if ((ip->i_d.di_mode == 0) && !(flags & XFS_IGET_CREATE)) {
76                         error = ENOENT;
77                         goto out_error;
78                 }
79
80                 xfs_itrace_exit_tag(ip, "xfs_iget.alloc");
81
82                 /*
83                  * We need to re-initialise the VFS inode as it has been
84                  * 'freed' by the VFS. Do this here so we can deal with
85                  * errors cleanly, then tag it so it can be set up correctly
86                  * later.
87                  */
88                 if (!inode_init_always(mp->m_super, VFS_I(ip))) {
89                         error = ENOMEM;
90                         goto out_error;
91                 }
92                 xfs_iflags_set(ip, XFS_INEW);
93                 xfs_iflags_clear(ip, XFS_IRECLAIMABLE);
94
95                 /* clear the radix tree reclaim flag as well. */
96                 __xfs_inode_clear_reclaim_tag(mp, pag, ip);
97                 read_unlock(&pag->pag_ici_lock);
98         } else if (!igrab(VFS_I(ip))) {
99                 /* If the VFS inode is being torn down, pause and try again. */
100                 error = EAGAIN;
101                 XFS_STATS_INC(xs_ig_frecycle);
102                 goto out_error;
103         } else {
104                 /* we've got a live one */
105                 read_unlock(&pag->pag_ici_lock);
106         }
107
108         if (ip->i_d.di_mode == 0 && !(flags & XFS_IGET_CREATE)) {
109                 error = ENOENT;
110                 goto out;
111         }
112
113         if (lock_flags != 0)
114                 xfs_ilock(ip, lock_flags);
115
116         xfs_iflags_clear(ip, XFS_ISTALE);
117         xfs_itrace_exit_tag(ip, "xfs_iget.found");
118         XFS_STATS_INC(xs_ig_found);
119         return 0;
120
121 out_error:
122         read_unlock(&pag->pag_ici_lock);
123 out:
124         return error;
125 }
126
127
128 static int
129 xfs_iget_cache_miss(
130         struct xfs_mount        *mp,
131         struct xfs_perag        *pag,
132         xfs_trans_t             *tp,
133         xfs_ino_t               ino,
134         struct xfs_inode        **ipp,
135         xfs_daddr_t             bno,
136         int                     flags,
137         int                     lock_flags) __releases(pag->pag_ici_lock)
138 {
139         struct xfs_inode        *ip;
140         int                     error;
141         unsigned long           first_index, mask;
142         xfs_agino_t             agino = XFS_INO_TO_AGINO(mp, ino);
143
144         /*
145          * Read the disk inode attributes into a new inode structure and get
146          * a new vnode for it. This should also initialize i_ino and i_mount.
147          */
148         error = xfs_iread(mp, tp, ino, &ip, bno,
149                           (flags & XFS_IGET_BULKSTAT) ? XFS_IMAP_BULKSTAT : 0);
150         if (error)
151                 return error;
152
153         xfs_itrace_exit_tag(ip, "xfs_iget.alloc");
154
155         if ((ip->i_d.di_mode == 0) && !(flags & XFS_IGET_CREATE)) {
156                 error = ENOENT;
157                 goto out_destroy;
158         }
159
160         /*
161          * Preload the radix tree so we can insert safely under the
162          * write spinlock.
163          */
164         if (radix_tree_preload(GFP_KERNEL)) {
165                 error = EAGAIN;
166                 goto out_destroy;
167         }
168
169         if (lock_flags)
170                 xfs_ilock(ip, lock_flags);
171
172         mask = ~(((XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog)) - 1);
173         first_index = agino & mask;
174         write_lock(&pag->pag_ici_lock);
175
176         /* insert the new inode */
177         error = radix_tree_insert(&pag->pag_ici_root, agino, ip);
178         if (unlikely(error)) {
179                 WARN_ON(error != -EEXIST);
180                 XFS_STATS_INC(xs_ig_dup);
181                 error = EAGAIN;
182                 goto out_unlock;
183         }
184
185         /* These values _must_ be set before releasing the radix tree lock! */
186         ip->i_udquot = ip->i_gdquot = NULL;
187         xfs_iflags_set(ip, XFS_INEW);
188
189         write_unlock(&pag->pag_ici_lock);
190         radix_tree_preload_end();
191         *ipp = ip;
192         return 0;
193
194 out_unlock:
195         write_unlock(&pag->pag_ici_lock);
196         radix_tree_preload_end();
197 out_destroy:
198         xfs_idestroy(ip);
199         return error;
200 }
201
202 /*
203  * Look up an inode by number in the given file system.
204  * The inode is looked up in the cache held in each AG.
205  * If the inode is found in the cache, initialise the vfs inode
206  * if necessary.
207  *
208  * If it is not in core, read it in from the file system's device,
209  * add it to the cache and initialise the vfs inode.
210  *
211  * The inode is locked according to the value of the lock_flags parameter.
212  * This flag parameter indicates how and if the inode's IO lock and inode lock
213  * should be taken.
214  *
215  * mp -- the mount point structure for the current file system.  It points
216  *       to the inode hash table.
217  * tp -- a pointer to the current transaction if there is one.  This is
218  *       simply passed through to the xfs_iread() call.
219  * ino -- the number of the inode desired.  This is the unique identifier
220  *        within the file system for the inode being requested.
221  * lock_flags -- flags indicating how to lock the inode.  See the comment
222  *               for xfs_ilock() for a list of valid values.
223  * bno -- the block number starting the buffer containing the inode,
224  *        if known (as by bulkstat), else 0.
225  */
226 int
227 xfs_iget(
228         xfs_mount_t     *mp,
229         xfs_trans_t     *tp,
230         xfs_ino_t       ino,
231         uint            flags,
232         uint            lock_flags,
233         xfs_inode_t     **ipp,
234         xfs_daddr_t     bno)
235 {
236         xfs_inode_t     *ip;
237         int             error;
238         xfs_perag_t     *pag;
239         xfs_agino_t     agino;
240
241         /* the radix tree exists only in inode capable AGs */
242         if (XFS_INO_TO_AGNO(mp, ino) >= mp->m_maxagi)
243                 return EINVAL;
244
245         /* get the perag structure and ensure that it's inode capable */
246         pag = xfs_get_perag(mp, ino);
247         if (!pag->pagi_inodeok)
248                 return EINVAL;
249         ASSERT(pag->pag_ici_init);
250         agino = XFS_INO_TO_AGINO(mp, ino);
251
252 again:
253         error = 0;
254         read_lock(&pag->pag_ici_lock);
255         ip = radix_tree_lookup(&pag->pag_ici_root, agino);
256
257         if (ip) {
258                 error = xfs_iget_cache_hit(pag, ip, flags, lock_flags);
259                 if (error)
260                         goto out_error_or_again;
261         } else {
262                 read_unlock(&pag->pag_ici_lock);
263                 XFS_STATS_INC(xs_ig_missed);
264
265                 error = xfs_iget_cache_miss(mp, pag, tp, ino, &ip, bno,
266                                                         flags, lock_flags);
267                 if (error)
268                         goto out_error_or_again;
269         }
270         xfs_put_perag(mp, pag);
271
272         xfs_iflags_set(ip, XFS_IMODIFIED);
273         *ipp = ip;
274
275         ASSERT(ip->i_df.if_ext_max ==
276                XFS_IFORK_DSIZE(ip) / sizeof(xfs_bmbt_rec_t));
277         /*
278          * If we have a real type for an on-disk inode, we can set ops(&unlock)
279          * now.  If it's a new inode being created, xfs_ialloc will handle it.
280          */
281         if (xfs_iflags_test(ip, XFS_INEW) && ip->i_d.di_mode != 0)
282                 xfs_setup_inode(ip);
283         return 0;
284
285 out_error_or_again:
286         if (error == EAGAIN) {
287                 delay(1);
288                 goto again;
289         }
290         xfs_put_perag(mp, pag);
291         return error;
292 }
293
294
295 /*
296  * Look for the inode corresponding to the given ino in the hash table.
297  * If it is there and its i_transp pointer matches tp, return it.
298  * Otherwise, return NULL.
299  */
300 xfs_inode_t *
301 xfs_inode_incore(xfs_mount_t    *mp,
302                  xfs_ino_t      ino,
303                  xfs_trans_t    *tp)
304 {
305         xfs_inode_t     *ip;
306         xfs_perag_t     *pag;
307
308         pag = xfs_get_perag(mp, ino);
309         read_lock(&pag->pag_ici_lock);
310         ip = radix_tree_lookup(&pag->pag_ici_root, XFS_INO_TO_AGINO(mp, ino));
311         read_unlock(&pag->pag_ici_lock);
312         xfs_put_perag(mp, pag);
313
314         /* the returned inode must match the transaction */
315         if (ip && (ip->i_transp != tp))
316                 return NULL;
317         return ip;
318 }
319
320 /*
321  * Decrement reference count of an inode structure and unlock it.
322  *
323  * ip -- the inode being released
324  * lock_flags -- this parameter indicates the inode's locks to be
325  *       to be released.  See the comment on xfs_iunlock() for a list
326  *       of valid values.
327  */
328 void
329 xfs_iput(xfs_inode_t    *ip,
330          uint           lock_flags)
331 {
332         xfs_itrace_entry(ip);
333         xfs_iunlock(ip, lock_flags);
334         IRELE(ip);
335 }
336
337 /*
338  * Special iput for brand-new inodes that are still locked
339  */
340 void
341 xfs_iput_new(
342         xfs_inode_t     *ip,
343         uint            lock_flags)
344 {
345         struct inode    *inode = VFS_I(ip);
346
347         xfs_itrace_entry(ip);
348
349         if ((ip->i_d.di_mode == 0)) {
350                 ASSERT(!xfs_iflags_test(ip, XFS_IRECLAIMABLE));
351                 make_bad_inode(inode);
352         }
353         if (inode->i_state & I_NEW)
354                 unlock_new_inode(inode);
355         if (lock_flags)
356                 xfs_iunlock(ip, lock_flags);
357         IRELE(ip);
358 }
359
360
361 /*
362  * This routine embodies the part of the reclaim code that pulls
363  * the inode from the inode hash table and the mount structure's
364  * inode list.
365  * This should only be called from xfs_reclaim().
366  */
367 void
368 xfs_ireclaim(xfs_inode_t *ip)
369 {
370         /*
371          * Remove from old hash list and mount list.
372          */
373         XFS_STATS_INC(xs_ig_reclaims);
374
375         xfs_iextract(ip);
376
377         /*
378          * Here we do a spurious inode lock in order to coordinate with inode
379          * cache radix tree lookups.  This is because the lookup can reference
380          * the inodes in the cache without taking references.  We make that OK
381          * here by ensuring that we wait until the inode is unlocked after the
382          * lookup before we go ahead and free it.  We get both the ilock and
383          * the iolock because the code may need to drop the ilock one but will
384          * still hold the iolock.
385          */
386         xfs_ilock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
387
388         /*
389          * Release dquots (and their references) if any. An inode may escape
390          * xfs_inactive and get here via vn_alloc->vn_reclaim path.
391          */
392         XFS_QM_DQDETACH(ip->i_mount, ip);
393
394         /*
395          * Free all memory associated with the inode.
396          */
397         xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
398         xfs_idestroy(ip);
399 }
400
401 /*
402  * This routine removes an about-to-be-destroyed inode from
403  * all of the lists in which it is located with the exception
404  * of the behavior chain.
405  */
406 void
407 xfs_iextract(
408         xfs_inode_t     *ip)
409 {
410         xfs_mount_t     *mp = ip->i_mount;
411         xfs_perag_t     *pag = xfs_get_perag(mp, ip->i_ino);
412
413         write_lock(&pag->pag_ici_lock);
414         radix_tree_delete(&pag->pag_ici_root, XFS_INO_TO_AGINO(mp, ip->i_ino));
415         write_unlock(&pag->pag_ici_lock);
416         xfs_put_perag(mp, pag);
417
418         mp->m_ireclaims++;
419 }
420
421 /*
422  * This is a wrapper routine around the xfs_ilock() routine
423  * used to centralize some grungy code.  It is used in places
424  * that wish to lock the inode solely for reading the extents.
425  * The reason these places can't just call xfs_ilock(SHARED)
426  * is that the inode lock also guards to bringing in of the
427  * extents from disk for a file in b-tree format.  If the inode
428  * is in b-tree format, then we need to lock the inode exclusively
429  * until the extents are read in.  Locking it exclusively all
430  * the time would limit our parallelism unnecessarily, though.
431  * What we do instead is check to see if the extents have been
432  * read in yet, and only lock the inode exclusively if they
433  * have not.
434  *
435  * The function returns a value which should be given to the
436  * corresponding xfs_iunlock_map_shared().  This value is
437  * the mode in which the lock was actually taken.
438  */
439 uint
440 xfs_ilock_map_shared(
441         xfs_inode_t     *ip)
442 {
443         uint    lock_mode;
444
445         if ((ip->i_d.di_format == XFS_DINODE_FMT_BTREE) &&
446             ((ip->i_df.if_flags & XFS_IFEXTENTS) == 0)) {
447                 lock_mode = XFS_ILOCK_EXCL;
448         } else {
449                 lock_mode = XFS_ILOCK_SHARED;
450         }
451
452         xfs_ilock(ip, lock_mode);
453
454         return lock_mode;
455 }
456
457 /*
458  * This is simply the unlock routine to go with xfs_ilock_map_shared().
459  * All it does is call xfs_iunlock() with the given lock_mode.
460  */
461 void
462 xfs_iunlock_map_shared(
463         xfs_inode_t     *ip,
464         unsigned int    lock_mode)
465 {
466         xfs_iunlock(ip, lock_mode);
467 }
468
469 /*
470  * The xfs inode contains 2 locks: a multi-reader lock called the
471  * i_iolock and a multi-reader lock called the i_lock.  This routine
472  * allows either or both of the locks to be obtained.
473  *
474  * The 2 locks should always be ordered so that the IO lock is
475  * obtained first in order to prevent deadlock.
476  *
477  * ip -- the inode being locked
478  * lock_flags -- this parameter indicates the inode's locks
479  *       to be locked.  It can be:
480  *              XFS_IOLOCK_SHARED,
481  *              XFS_IOLOCK_EXCL,
482  *              XFS_ILOCK_SHARED,
483  *              XFS_ILOCK_EXCL,
484  *              XFS_IOLOCK_SHARED | XFS_ILOCK_SHARED,
485  *              XFS_IOLOCK_SHARED | XFS_ILOCK_EXCL,
486  *              XFS_IOLOCK_EXCL | XFS_ILOCK_SHARED,
487  *              XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL
488  */
489 void
490 xfs_ilock(
491         xfs_inode_t             *ip,
492         uint                    lock_flags)
493 {
494         /*
495          * You can't set both SHARED and EXCL for the same lock,
496          * and only XFS_IOLOCK_SHARED, XFS_IOLOCK_EXCL, XFS_ILOCK_SHARED,
497          * and XFS_ILOCK_EXCL are valid values to set in lock_flags.
498          */
499         ASSERT((lock_flags & (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)) !=
500                (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL));
501         ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) !=
502                (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
503         ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_LOCK_DEP_MASK)) == 0);
504
505         if (lock_flags & XFS_IOLOCK_EXCL)
506                 mrupdate_nested(&ip->i_iolock, XFS_IOLOCK_DEP(lock_flags));
507         else if (lock_flags & XFS_IOLOCK_SHARED)
508                 mraccess_nested(&ip->i_iolock, XFS_IOLOCK_DEP(lock_flags));
509
510         if (lock_flags & XFS_ILOCK_EXCL)
511                 mrupdate_nested(&ip->i_lock, XFS_ILOCK_DEP(lock_flags));
512         else if (lock_flags & XFS_ILOCK_SHARED)
513                 mraccess_nested(&ip->i_lock, XFS_ILOCK_DEP(lock_flags));
514
515         xfs_ilock_trace(ip, 1, lock_flags, (inst_t *)__return_address);
516 }
517
518 /*
519  * This is just like xfs_ilock(), except that the caller
520  * is guaranteed not to sleep.  It returns 1 if it gets
521  * the requested locks and 0 otherwise.  If the IO lock is
522  * obtained but the inode lock cannot be, then the IO lock
523  * is dropped before returning.
524  *
525  * ip -- the inode being locked
526  * lock_flags -- this parameter indicates the inode's locks to be
527  *       to be locked.  See the comment for xfs_ilock() for a list
528  *       of valid values.
529  */
530 int
531 xfs_ilock_nowait(
532         xfs_inode_t             *ip,
533         uint                    lock_flags)
534 {
535         /*
536          * You can't set both SHARED and EXCL for the same lock,
537          * and only XFS_IOLOCK_SHARED, XFS_IOLOCK_EXCL, XFS_ILOCK_SHARED,
538          * and XFS_ILOCK_EXCL are valid values to set in lock_flags.
539          */
540         ASSERT((lock_flags & (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)) !=
541                (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL));
542         ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) !=
543                (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
544         ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_LOCK_DEP_MASK)) == 0);
545
546         if (lock_flags & XFS_IOLOCK_EXCL) {
547                 if (!mrtryupdate(&ip->i_iolock))
548                         goto out;
549         } else if (lock_flags & XFS_IOLOCK_SHARED) {
550                 if (!mrtryaccess(&ip->i_iolock))
551                         goto out;
552         }
553         if (lock_flags & XFS_ILOCK_EXCL) {
554                 if (!mrtryupdate(&ip->i_lock))
555                         goto out_undo_iolock;
556         } else if (lock_flags & XFS_ILOCK_SHARED) {
557                 if (!mrtryaccess(&ip->i_lock))
558                         goto out_undo_iolock;
559         }
560         xfs_ilock_trace(ip, 2, lock_flags, (inst_t *)__return_address);
561         return 1;
562
563  out_undo_iolock:
564         if (lock_flags & XFS_IOLOCK_EXCL)
565                 mrunlock_excl(&ip->i_iolock);
566         else if (lock_flags & XFS_IOLOCK_SHARED)
567                 mrunlock_shared(&ip->i_iolock);
568  out:
569         return 0;
570 }
571
572 /*
573  * xfs_iunlock() is used to drop the inode locks acquired with
574  * xfs_ilock() and xfs_ilock_nowait().  The caller must pass
575  * in the flags given to xfs_ilock() or xfs_ilock_nowait() so
576  * that we know which locks to drop.
577  *
578  * ip -- the inode being unlocked
579  * lock_flags -- this parameter indicates the inode's locks to be
580  *       to be unlocked.  See the comment for xfs_ilock() for a list
581  *       of valid values for this parameter.
582  *
583  */
584 void
585 xfs_iunlock(
586         xfs_inode_t             *ip,
587         uint                    lock_flags)
588 {
589         /*
590          * You can't set both SHARED and EXCL for the same lock,
591          * and only XFS_IOLOCK_SHARED, XFS_IOLOCK_EXCL, XFS_ILOCK_SHARED,
592          * and XFS_ILOCK_EXCL are valid values to set in lock_flags.
593          */
594         ASSERT((lock_flags & (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)) !=
595                (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL));
596         ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) !=
597                (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
598         ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_IUNLOCK_NONOTIFY |
599                         XFS_LOCK_DEP_MASK)) == 0);
600         ASSERT(lock_flags != 0);
601
602         if (lock_flags & XFS_IOLOCK_EXCL)
603                 mrunlock_excl(&ip->i_iolock);
604         else if (lock_flags & XFS_IOLOCK_SHARED)
605                 mrunlock_shared(&ip->i_iolock);
606
607         if (lock_flags & XFS_ILOCK_EXCL)
608                 mrunlock_excl(&ip->i_lock);
609         else if (lock_flags & XFS_ILOCK_SHARED)
610                 mrunlock_shared(&ip->i_lock);
611
612         if ((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) &&
613             !(lock_flags & XFS_IUNLOCK_NONOTIFY) && ip->i_itemp) {
614                 /*
615                  * Let the AIL know that this item has been unlocked in case
616                  * it is in the AIL and anyone is waiting on it.  Don't do
617                  * this if the caller has asked us not to.
618                  */
619                 xfs_trans_unlocked_item(ip->i_mount,
620                                         (xfs_log_item_t*)(ip->i_itemp));
621         }
622         xfs_ilock_trace(ip, 3, lock_flags, (inst_t *)__return_address);
623 }
624
625 /*
626  * give up write locks.  the i/o lock cannot be held nested
627  * if it is being demoted.
628  */
629 void
630 xfs_ilock_demote(
631         xfs_inode_t             *ip,
632         uint                    lock_flags)
633 {
634         ASSERT(lock_flags & (XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL));
635         ASSERT((lock_flags & ~(XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL)) == 0);
636
637         if (lock_flags & XFS_ILOCK_EXCL)
638                 mrdemote(&ip->i_lock);
639         if (lock_flags & XFS_IOLOCK_EXCL)
640                 mrdemote(&ip->i_iolock);
641 }
642
643 #ifdef DEBUG
644 /*
645  * Debug-only routine, without additional rw_semaphore APIs, we can
646  * now only answer requests regarding whether we hold the lock for write
647  * (reader state is outside our visibility, we only track writer state).
648  *
649  * Note: this means !xfs_isilocked would give false positives, so don't do that.
650  */
651 int
652 xfs_isilocked(
653         xfs_inode_t             *ip,
654         uint                    lock_flags)
655 {
656         if ((lock_flags & (XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)) ==
657                         XFS_ILOCK_EXCL) {
658                 if (!ip->i_lock.mr_writer)
659                         return 0;
660         }
661
662         if ((lock_flags & (XFS_IOLOCK_EXCL|XFS_IOLOCK_SHARED)) ==
663                         XFS_IOLOCK_EXCL) {
664                 if (!ip->i_iolock.mr_writer)
665                         return 0;
666         }
667
668         return 1;
669 }
670 #endif
671