1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include <linux/log2.h>
19
20#include "xfs.h"
21#include "xfs_fs.h"
22#include "xfs_shared.h"
23#include "xfs_format.h"
24#include "xfs_log_format.h"
25#include "xfs_trans_resv.h"
26#include "xfs_inum.h"
27#include "xfs_sb.h"
28#include "xfs_ag.h"
29#include "xfs_mount.h"
30#include "xfs_inode.h"
31#include "xfs_da_format.h"
32#include "xfs_da_btree.h"
33#include "xfs_dir2.h"
34#include "xfs_attr_sf.h"
35#include "xfs_attr.h"
36#include "xfs_trans_space.h"
37#include "xfs_trans.h"
38#include "xfs_buf_item.h"
39#include "xfs_inode_item.h"
40#include "xfs_ialloc.h"
41#include "xfs_bmap.h"
42#include "xfs_bmap_util.h"
43#include "xfs_error.h"
44#include "xfs_quota.h"
45#include "xfs_filestream.h"
46#include "xfs_cksum.h"
47#include "xfs_trace.h"
48#include "xfs_icache.h"
49#include "xfs_symlink.h"
50#include "xfs_trans_priv.h"
51#include "xfs_log.h"
52#include "xfs_bmap_btree.h"
53
54kmem_zone_t *xfs_inode_zone;
55
56
57
58
59
60#define XFS_ITRUNC_MAX_EXTENTS 2
61
62STATIC int xfs_iflush_int(xfs_inode_t *, xfs_buf_t *);
63
64STATIC int xfs_iunlink_remove(xfs_trans_t *, xfs_inode_t *);
65
66
67
68
69xfs_extlen_t
70xfs_get_extsz_hint(
71 struct xfs_inode *ip)
72{
73 if ((ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE) && ip->i_d.di_extsize)
74 return ip->i_d.di_extsize;
75 if (XFS_IS_REALTIME_INODE(ip))
76 return ip->i_mount->m_sb.sb_rextsize;
77 return 0;
78}
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95uint
96xfs_ilock_data_map_shared(
97 struct xfs_inode *ip)
98{
99 uint lock_mode = XFS_ILOCK_SHARED;
100
101 if (ip->i_d.di_format == XFS_DINODE_FMT_BTREE &&
102 (ip->i_df.if_flags & XFS_IFEXTENTS) == 0)
103 lock_mode = XFS_ILOCK_EXCL;
104 xfs_ilock(ip, lock_mode);
105 return lock_mode;
106}
107
108uint
109xfs_ilock_attr_map_shared(
110 struct xfs_inode *ip)
111{
112 uint lock_mode = XFS_ILOCK_SHARED;
113
114 if (ip->i_d.di_aformat == XFS_DINODE_FMT_BTREE &&
115 (ip->i_afp->if_flags & XFS_IFEXTENTS) == 0)
116 lock_mode = XFS_ILOCK_EXCL;
117 xfs_ilock(ip, lock_mode);
118 return lock_mode;
119}
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141void
142xfs_ilock(
143 xfs_inode_t *ip,
144 uint lock_flags)
145{
146 trace_xfs_ilock(ip, lock_flags, _RET_IP_);
147
148
149
150
151
152
153 ASSERT((lock_flags & (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)) !=
154 (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL));
155 ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) !=
156 (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
157 ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_LOCK_DEP_MASK)) == 0);
158
159 if (lock_flags & XFS_IOLOCK_EXCL)
160 mrupdate_nested(&ip->i_iolock, XFS_IOLOCK_DEP(lock_flags));
161 else if (lock_flags & XFS_IOLOCK_SHARED)
162 mraccess_nested(&ip->i_iolock, XFS_IOLOCK_DEP(lock_flags));
163
164 if (lock_flags & XFS_ILOCK_EXCL)
165 mrupdate_nested(&ip->i_lock, XFS_ILOCK_DEP(lock_flags));
166 else if (lock_flags & XFS_ILOCK_SHARED)
167 mraccess_nested(&ip->i_lock, XFS_ILOCK_DEP(lock_flags));
168}
169
170
171
172
173
174
175
176
177
178
179
180
181
182int
183xfs_ilock_nowait(
184 xfs_inode_t *ip,
185 uint lock_flags)
186{
187 trace_xfs_ilock_nowait(ip, lock_flags, _RET_IP_);
188
189
190
191
192
193
194 ASSERT((lock_flags & (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)) !=
195 (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL));
196 ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) !=
197 (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
198 ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_LOCK_DEP_MASK)) == 0);
199
200 if (lock_flags & XFS_IOLOCK_EXCL) {
201 if (!mrtryupdate(&ip->i_iolock))
202 goto out;
203 } else if (lock_flags & XFS_IOLOCK_SHARED) {
204 if (!mrtryaccess(&ip->i_iolock))
205 goto out;
206 }
207 if (lock_flags & XFS_ILOCK_EXCL) {
208 if (!mrtryupdate(&ip->i_lock))
209 goto out_undo_iolock;
210 } else if (lock_flags & XFS_ILOCK_SHARED) {
211 if (!mrtryaccess(&ip->i_lock))
212 goto out_undo_iolock;
213 }
214 return 1;
215
216 out_undo_iolock:
217 if (lock_flags & XFS_IOLOCK_EXCL)
218 mrunlock_excl(&ip->i_iolock);
219 else if (lock_flags & XFS_IOLOCK_SHARED)
220 mrunlock_shared(&ip->i_iolock);
221 out:
222 return 0;
223}
224
225
226
227
228
229
230
231
232
233
234
235
236
237void
238xfs_iunlock(
239 xfs_inode_t *ip,
240 uint lock_flags)
241{
242
243
244
245
246
247 ASSERT((lock_flags & (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)) !=
248 (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL));
249 ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) !=
250 (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
251 ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_LOCK_DEP_MASK)) == 0);
252 ASSERT(lock_flags != 0);
253
254 if (lock_flags & XFS_IOLOCK_EXCL)
255 mrunlock_excl(&ip->i_iolock);
256 else if (lock_flags & XFS_IOLOCK_SHARED)
257 mrunlock_shared(&ip->i_iolock);
258
259 if (lock_flags & XFS_ILOCK_EXCL)
260 mrunlock_excl(&ip->i_lock);
261 else if (lock_flags & XFS_ILOCK_SHARED)
262 mrunlock_shared(&ip->i_lock);
263
264 trace_xfs_iunlock(ip, lock_flags, _RET_IP_);
265}
266
267
268
269
270
271void
272xfs_ilock_demote(
273 xfs_inode_t *ip,
274 uint lock_flags)
275{
276 ASSERT(lock_flags & (XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL));
277 ASSERT((lock_flags & ~(XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL)) == 0);
278
279 if (lock_flags & XFS_ILOCK_EXCL)
280 mrdemote(&ip->i_lock);
281 if (lock_flags & XFS_IOLOCK_EXCL)
282 mrdemote(&ip->i_iolock);
283
284 trace_xfs_ilock_demote(ip, lock_flags, _RET_IP_);
285}
286
287#if defined(DEBUG) || defined(XFS_WARN)
288int
289xfs_isilocked(
290 xfs_inode_t *ip,
291 uint lock_flags)
292{
293 if (lock_flags & (XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)) {
294 if (!(lock_flags & XFS_ILOCK_SHARED))
295 return !!ip->i_lock.mr_writer;
296 return rwsem_is_locked(&ip->i_lock.mr_lock);
297 }
298
299 if (lock_flags & (XFS_IOLOCK_EXCL|XFS_IOLOCK_SHARED)) {
300 if (!(lock_flags & XFS_IOLOCK_SHARED))
301 return !!ip->i_iolock.mr_writer;
302 return rwsem_is_locked(&ip->i_iolock.mr_lock);
303 }
304
305 ASSERT(0);
306 return 0;
307}
308#endif
309
310#ifdef DEBUG
311int xfs_locked_n;
312int xfs_small_retries;
313int xfs_middle_retries;
314int xfs_lots_retries;
315int xfs_lock_delays;
316#endif
317
318
319
320
321
322static inline int
323xfs_lock_inumorder(int lock_mode, int subclass)
324{
325 if (lock_mode & (XFS_IOLOCK_SHARED|XFS_IOLOCK_EXCL))
326 lock_mode |= (subclass + XFS_LOCK_INUMORDER) << XFS_IOLOCK_SHIFT;
327 if (lock_mode & (XFS_ILOCK_SHARED|XFS_ILOCK_EXCL))
328 lock_mode |= (subclass + XFS_LOCK_INUMORDER) << XFS_ILOCK_SHIFT;
329
330 return lock_mode;
331}
332
333
334
335
336
337
338
339
340
341
342
343
344void
345xfs_lock_inodes(
346 xfs_inode_t **ips,
347 int inodes,
348 uint lock_mode)
349{
350 int attempts = 0, i, j, try_lock;
351 xfs_log_item_t *lp;
352
353 ASSERT(ips && (inodes >= 2));
354
355 try_lock = 0;
356 i = 0;
357
358again:
359 for (; i < inodes; i++) {
360 ASSERT(ips[i]);
361
362 if (i && (ips[i] == ips[i-1]))
363 continue;
364
365
366
367
368
369
370
371 if (!try_lock) {
372 for (j = (i - 1); j >= 0 && !try_lock; j--) {
373 lp = (xfs_log_item_t *)ips[j]->i_itemp;
374 if (lp && (lp->li_flags & XFS_LI_IN_AIL)) {
375 try_lock++;
376 }
377 }
378 }
379
380
381
382
383
384
385
386
387 if (try_lock) {
388
389
390
391
392
393 ASSERT(i != 0);
394 if (!xfs_ilock_nowait(ips[i], xfs_lock_inumorder(lock_mode, i))) {
395 attempts++;
396
397
398
399
400
401
402
403 for(j = i - 1; j >= 0; j--) {
404
405
406
407
408
409
410
411 if ((j != (i - 1)) && ips[j] ==
412 ips[j+1])
413 continue;
414
415 xfs_iunlock(ips[j], lock_mode);
416 }
417
418 if ((attempts % 5) == 0) {
419 delay(1);
420#ifdef DEBUG
421 xfs_lock_delays++;
422#endif
423 }
424 i = 0;
425 try_lock = 0;
426 goto again;
427 }
428 } else {
429 xfs_ilock(ips[i], xfs_lock_inumorder(lock_mode, i));
430 }
431 }
432
433#ifdef DEBUG
434 if (attempts) {
435 if (attempts < 5) xfs_small_retries++;
436 else if (attempts < 100) xfs_middle_retries++;
437 else xfs_lots_retries++;
438 } else {
439 xfs_locked_n++;
440 }
441#endif
442}
443
444
445
446
447
448
449
450void
451xfs_lock_two_inodes(
452 xfs_inode_t *ip0,
453 xfs_inode_t *ip1,
454 uint lock_mode)
455{
456 xfs_inode_t *temp;
457 int attempts = 0;
458 xfs_log_item_t *lp;
459
460 if (lock_mode & (XFS_IOLOCK_SHARED|XFS_IOLOCK_EXCL))
461 ASSERT((lock_mode & (XFS_ILOCK_SHARED|XFS_ILOCK_EXCL)) == 0);
462 ASSERT(ip0->i_ino != ip1->i_ino);
463
464 if (ip0->i_ino > ip1->i_ino) {
465 temp = ip0;
466 ip0 = ip1;
467 ip1 = temp;
468 }
469
470 again:
471 xfs_ilock(ip0, xfs_lock_inumorder(lock_mode, 0));
472
473
474
475
476
477
478 lp = (xfs_log_item_t *)ip0->i_itemp;
479 if (lp && (lp->li_flags & XFS_LI_IN_AIL)) {
480 if (!xfs_ilock_nowait(ip1, xfs_lock_inumorder(lock_mode, 1))) {
481 xfs_iunlock(ip0, lock_mode);
482 if ((++attempts % 5) == 0)
483 delay(1);
484 goto again;
485 }
486 } else {
487 xfs_ilock(ip1, xfs_lock_inumorder(lock_mode, 1));
488 }
489}
490
491
492void
493__xfs_iflock(
494 struct xfs_inode *ip)
495{
496 wait_queue_head_t *wq = bit_waitqueue(&ip->i_flags, __XFS_IFLOCK_BIT);
497 DEFINE_WAIT_BIT(wait, &ip->i_flags, __XFS_IFLOCK_BIT);
498
499 do {
500 prepare_to_wait_exclusive(wq, &wait.wait, TASK_UNINTERRUPTIBLE);
501 if (xfs_isiflocked(ip))
502 io_schedule();
503 } while (!xfs_iflock_nowait(ip));
504
505 finish_wait(wq, &wait.wait);
506}
507
508STATIC uint
509_xfs_dic2xflags(
510 __uint16_t di_flags)
511{
512 uint flags = 0;
513
514 if (di_flags & XFS_DIFLAG_ANY) {
515 if (di_flags & XFS_DIFLAG_REALTIME)
516 flags |= XFS_XFLAG_REALTIME;
517 if (di_flags & XFS_DIFLAG_PREALLOC)
518 flags |= XFS_XFLAG_PREALLOC;
519 if (di_flags & XFS_DIFLAG_IMMUTABLE)
520 flags |= XFS_XFLAG_IMMUTABLE;
521 if (di_flags & XFS_DIFLAG_APPEND)
522 flags |= XFS_XFLAG_APPEND;
523 if (di_flags & XFS_DIFLAG_SYNC)
524 flags |= XFS_XFLAG_SYNC;
525 if (di_flags & XFS_DIFLAG_NOATIME)
526 flags |= XFS_XFLAG_NOATIME;
527 if (di_flags & XFS_DIFLAG_NODUMP)
528 flags |= XFS_XFLAG_NODUMP;
529 if (di_flags & XFS_DIFLAG_RTINHERIT)
530 flags |= XFS_XFLAG_RTINHERIT;
531 if (di_flags & XFS_DIFLAG_PROJINHERIT)
532 flags |= XFS_XFLAG_PROJINHERIT;
533 if (di_flags & XFS_DIFLAG_NOSYMLINKS)
534 flags |= XFS_XFLAG_NOSYMLINKS;
535 if (di_flags & XFS_DIFLAG_EXTSIZE)
536 flags |= XFS_XFLAG_EXTSIZE;
537 if (di_flags & XFS_DIFLAG_EXTSZINHERIT)
538 flags |= XFS_XFLAG_EXTSZINHERIT;
539 if (di_flags & XFS_DIFLAG_NODEFRAG)
540 flags |= XFS_XFLAG_NODEFRAG;
541 if (di_flags & XFS_DIFLAG_FILESTREAM)
542 flags |= XFS_XFLAG_FILESTREAM;
543 }
544
545 return flags;
546}
547
548uint
549xfs_ip2xflags(
550 xfs_inode_t *ip)
551{
552 xfs_icdinode_t *dic = &ip->i_d;
553
554 return _xfs_dic2xflags(dic->di_flags) |
555 (XFS_IFORK_Q(ip) ? XFS_XFLAG_HASATTR : 0);
556}
557
558uint
559xfs_dic2xflags(
560 xfs_dinode_t *dip)
561{
562 return _xfs_dic2xflags(be16_to_cpu(dip->di_flags)) |
563 (XFS_DFORK_Q(dip) ? XFS_XFLAG_HASATTR : 0);
564}
565
566
567
568
569
570
571
572int
573xfs_lookup(
574 xfs_inode_t *dp,
575 struct xfs_name *name,
576 xfs_inode_t **ipp,
577 struct xfs_name *ci_name)
578{
579 xfs_ino_t inum;
580 int error;
581 uint lock_mode;
582
583 trace_xfs_lookup(dp, name);
584
585 if (XFS_FORCED_SHUTDOWN(dp->i_mount))
586 return -EIO;
587
588 lock_mode = xfs_ilock_data_map_shared(dp);
589 error = xfs_dir_lookup(NULL, dp, name, &inum, ci_name);
590 xfs_iunlock(dp, lock_mode);
591
592 if (error)
593 goto out;
594
595 error = xfs_iget(dp->i_mount, NULL, inum, 0, 0, ipp);
596 if (error)
597 goto out_free_name;
598
599 return 0;
600
601out_free_name:
602 if (ci_name)
603 kmem_free(ci_name->name);
604out:
605 *ipp = NULL;
606 return error;
607}
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640int
641xfs_ialloc(
642 xfs_trans_t *tp,
643 xfs_inode_t *pip,
644 umode_t mode,
645 xfs_nlink_t nlink,
646 xfs_dev_t rdev,
647 prid_t prid,
648 int okalloc,
649 xfs_buf_t **ialloc_context,
650 xfs_inode_t **ipp)
651{
652 struct xfs_mount *mp = tp->t_mountp;
653 xfs_ino_t ino;
654 xfs_inode_t *ip;
655 uint flags;
656 int error;
657 timespec_t tv;
658
659
660
661
662
663 error = xfs_dialloc(tp, pip ? pip->i_ino : 0, mode, okalloc,
664 ialloc_context, &ino);
665 if (error)
666 return error;
667 if (*ialloc_context || ino == NULLFSINO) {
668 *ipp = NULL;
669 return 0;
670 }
671 ASSERT(*ialloc_context == NULL);
672
673
674
675
676
677
678 error = xfs_iget(mp, tp, ino, XFS_IGET_CREATE,
679 XFS_ILOCK_EXCL, &ip);
680 if (error)
681 return error;
682 ASSERT(ip != NULL);
683
684
685
686
687
688
689 if (ip->i_d.di_version == 1)
690 ip->i_d.di_version = 2;
691
692 ip->i_d.di_mode = mode;
693 ip->i_d.di_onlink = 0;
694 ip->i_d.di_nlink = nlink;
695 ASSERT(ip->i_d.di_nlink == nlink);
696 ip->i_d.di_uid = xfs_kuid_to_uid(current_fsuid());
697 ip->i_d.di_gid = xfs_kgid_to_gid(current_fsgid());
698 xfs_set_projid(ip, prid);
699 memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
700
701 if (pip && XFS_INHERIT_GID(pip)) {
702 ip->i_d.di_gid = pip->i_d.di_gid;
703 if ((pip->i_d.di_mode & S_ISGID) && S_ISDIR(mode)) {
704 ip->i_d.di_mode |= S_ISGID;
705 }
706 }
707
708
709
710
711
712
713 if ((irix_sgid_inherit) &&
714 (ip->i_d.di_mode & S_ISGID) &&
715 (!in_group_p(xfs_gid_to_kgid(ip->i_d.di_gid)))) {
716 ip->i_d.di_mode &= ~S_ISGID;
717 }
718
719 ip->i_d.di_size = 0;
720 ip->i_d.di_nextents = 0;
721 ASSERT(ip->i_d.di_nblocks == 0);
722
723 nanotime(&tv);
724 ip->i_d.di_mtime.t_sec = (__int32_t)tv.tv_sec;
725 ip->i_d.di_mtime.t_nsec = (__int32_t)tv.tv_nsec;
726 ip->i_d.di_atime = ip->i_d.di_mtime;
727 ip->i_d.di_ctime = ip->i_d.di_mtime;
728
729
730
731
732 ip->i_d.di_extsize = 0;
733 ip->i_d.di_dmevmask = 0;
734 ip->i_d.di_dmstate = 0;
735 ip->i_d.di_flags = 0;
736
737 if (ip->i_d.di_version == 3) {
738 ASSERT(ip->i_d.di_ino == ino);
739 ASSERT(uuid_equal(&ip->i_d.di_uuid, &mp->m_sb.sb_uuid));
740 ip->i_d.di_crc = 0;
741 ip->i_d.di_changecount = 1;
742 ip->i_d.di_lsn = 0;
743 ip->i_d.di_flags2 = 0;
744 memset(&(ip->i_d.di_pad2[0]), 0, sizeof(ip->i_d.di_pad2));
745 ip->i_d.di_crtime = ip->i_d.di_mtime;
746 }
747
748
749 flags = XFS_ILOG_CORE;
750 switch (mode & S_IFMT) {
751 case S_IFIFO:
752 case S_IFCHR:
753 case S_IFBLK:
754 case S_IFSOCK:
755 ip->i_d.di_format = XFS_DINODE_FMT_DEV;
756 ip->i_df.if_u2.if_rdev = rdev;
757 ip->i_df.if_flags = 0;
758 flags |= XFS_ILOG_DEV;
759 break;
760 case S_IFREG:
761 case S_IFDIR:
762 if (pip && (pip->i_d.di_flags & XFS_DIFLAG_ANY)) {
763 uint di_flags = 0;
764
765 if (S_ISDIR(mode)) {
766 if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT)
767 di_flags |= XFS_DIFLAG_RTINHERIT;
768 if (pip->i_d.di_flags & XFS_DIFLAG_EXTSZINHERIT) {
769 di_flags |= XFS_DIFLAG_EXTSZINHERIT;
770 ip->i_d.di_extsize = pip->i_d.di_extsize;
771 }
772 } else if (S_ISREG(mode)) {
773 if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT)
774 di_flags |= XFS_DIFLAG_REALTIME;
775 if (pip->i_d.di_flags & XFS_DIFLAG_EXTSZINHERIT) {
776 di_flags |= XFS_DIFLAG_EXTSIZE;
777 ip->i_d.di_extsize = pip->i_d.di_extsize;
778 }
779 }
780 if ((pip->i_d.di_flags & XFS_DIFLAG_NOATIME) &&
781 xfs_inherit_noatime)
782 di_flags |= XFS_DIFLAG_NOATIME;
783 if ((pip->i_d.di_flags & XFS_DIFLAG_NODUMP) &&
784 xfs_inherit_nodump)
785 di_flags |= XFS_DIFLAG_NODUMP;
786 if ((pip->i_d.di_flags & XFS_DIFLAG_SYNC) &&
787 xfs_inherit_sync)
788 di_flags |= XFS_DIFLAG_SYNC;
789 if ((pip->i_d.di_flags & XFS_DIFLAG_NOSYMLINKS) &&
790 xfs_inherit_nosymlinks)
791 di_flags |= XFS_DIFLAG_NOSYMLINKS;
792 if (pip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
793 di_flags |= XFS_DIFLAG_PROJINHERIT;
794 if ((pip->i_d.di_flags & XFS_DIFLAG_NODEFRAG) &&
795 xfs_inherit_nodefrag)
796 di_flags |= XFS_DIFLAG_NODEFRAG;
797 if (pip->i_d.di_flags & XFS_DIFLAG_FILESTREAM)
798 di_flags |= XFS_DIFLAG_FILESTREAM;
799 ip->i_d.di_flags |= di_flags;
800 }
801
802 case S_IFLNK:
803 ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS;
804 ip->i_df.if_flags = XFS_IFEXTENTS;
805 ip->i_df.if_bytes = ip->i_df.if_real_bytes = 0;
806 ip->i_df.if_u1.if_extents = NULL;
807 break;
808 default:
809 ASSERT(0);
810 }
811
812
813
814 ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
815 ip->i_d.di_anextents = 0;
816
817
818
819
820 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
821 xfs_trans_log_inode(tp, ip, flags);
822
823
824 xfs_setup_inode(ip);
825
826 *ipp = ip;
827 return 0;
828}
829
830
831
832
833
834
835
836
837
838
839
840int
841xfs_dir_ialloc(
842 xfs_trans_t **tpp,
843
844 xfs_inode_t *dp,
845
846 umode_t mode,
847 xfs_nlink_t nlink,
848 xfs_dev_t rdev,
849 prid_t prid,
850 int okalloc,
851 xfs_inode_t **ipp,
852
853 int *committed)
854
855{
856 xfs_trans_t *tp;
857 xfs_trans_t *ntp;
858 xfs_inode_t *ip;
859 xfs_buf_t *ialloc_context = NULL;
860 int code;
861 void *dqinfo;
862 uint tflags;
863
864 tp = *tpp;
865 ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES);
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882 code = xfs_ialloc(tp, dp, mode, nlink, rdev, prid, okalloc,
883 &ialloc_context, &ip);
884
885
886
887
888
889
890 if (code) {
891 *ipp = NULL;
892 return code;
893 }
894 if (!ialloc_context && !ip) {
895 *ipp = NULL;
896 return -ENOSPC;
897 }
898
899
900
901
902
903
904
905 if (ialloc_context) {
906 struct xfs_trans_res tres;
907
908
909
910
911
912
913
914
915 xfs_trans_bhold(tp, ialloc_context);
916
917
918
919
920 tres.tr_logres = xfs_trans_get_log_res(tp);
921 tres.tr_logcount = xfs_trans_get_log_count(tp);
922
923
924
925
926
927
928 dqinfo = NULL;
929 tflags = 0;
930 if (tp->t_dqinfo) {
931 dqinfo = (void *)tp->t_dqinfo;
932 tp->t_dqinfo = NULL;
933 tflags = tp->t_flags & XFS_TRANS_DQ_DIRTY;
934 tp->t_flags &= ~(XFS_TRANS_DQ_DIRTY);
935 }
936
937 ntp = xfs_trans_dup(tp);
938 code = xfs_trans_commit(tp, 0);
939 tp = ntp;
940 if (committed != NULL) {
941 *committed = 1;
942 }
943
944
945
946
947
948 if (code) {
949 xfs_buf_relse(ialloc_context);
950 if (dqinfo) {
951 tp->t_dqinfo = dqinfo;
952 xfs_trans_free_dqinfo(tp);
953 }
954 *tpp = ntp;
955 *ipp = NULL;
956 return code;
957 }
958
959
960
961
962
963 xfs_log_ticket_put(tp->t_ticket);
964 tres.tr_logflags = XFS_TRANS_PERM_LOG_RES;
965 code = xfs_trans_reserve(tp, &tres, 0, 0);
966
967
968
969
970 if (dqinfo) {
971 tp->t_dqinfo = dqinfo;
972 tp->t_flags |= tflags;
973 }
974
975 if (code) {
976 xfs_buf_relse(ialloc_context);
977 *tpp = ntp;
978 *ipp = NULL;
979 return code;
980 }
981 xfs_trans_bjoin(tp, ialloc_context);
982
983
984
985
986
987
988 code = xfs_ialloc(tp, dp, mode, nlink, rdev, prid,
989 okalloc, &ialloc_context, &ip);
990
991
992
993
994
995 if (code) {
996 *tpp = tp;
997 *ipp = NULL;
998 return code;
999 }
1000 ASSERT(!ialloc_context && ip);
1001
1002 } else {
1003 if (committed != NULL)
1004 *committed = 0;
1005 }
1006
1007 *ipp = ip;
1008 *tpp = tp;
1009
1010 return 0;
1011}
1012
1013
1014
1015
1016
1017
1018int
1019xfs_droplink(
1020 xfs_trans_t *tp,
1021 xfs_inode_t *ip)
1022{
1023 int error;
1024
1025 xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG);
1026
1027 ASSERT (ip->i_d.di_nlink > 0);
1028 ip->i_d.di_nlink--;
1029 drop_nlink(VFS_I(ip));
1030 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
1031
1032 error = 0;
1033 if (ip->i_d.di_nlink == 0) {
1034
1035
1036
1037
1038
1039
1040 error = xfs_iunlink(tp, ip);
1041 }
1042 return error;
1043}
1044
1045
1046
1047
1048int
1049xfs_bumplink(
1050 xfs_trans_t *tp,
1051 xfs_inode_t *ip)
1052{
1053 xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG);
1054
1055 ASSERT(ip->i_d.di_version > 1);
1056 ASSERT(ip->i_d.di_nlink > 0 || (VFS_I(ip)->i_state & I_LINKABLE));
1057 ip->i_d.di_nlink++;
1058 inc_nlink(VFS_I(ip));
1059 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
1060 return 0;
1061}
1062
1063int
1064xfs_create(
1065 xfs_inode_t *dp,
1066 struct xfs_name *name,
1067 umode_t mode,
1068 xfs_dev_t rdev,
1069 xfs_inode_t **ipp)
1070{
1071 int is_dir = S_ISDIR(mode);
1072 struct xfs_mount *mp = dp->i_mount;
1073 struct xfs_inode *ip = NULL;
1074 struct xfs_trans *tp = NULL;
1075 int error;
1076 xfs_bmap_free_t free_list;
1077 xfs_fsblock_t first_block;
1078 bool unlock_dp_on_error = false;
1079 uint cancel_flags;
1080 int committed;
1081 prid_t prid;
1082 struct xfs_dquot *udqp = NULL;
1083 struct xfs_dquot *gdqp = NULL;
1084 struct xfs_dquot *pdqp = NULL;
1085 struct xfs_trans_res tres;
1086 uint resblks;
1087
1088 trace_xfs_create(dp, name);
1089
1090 if (XFS_FORCED_SHUTDOWN(mp))
1091 return -EIO;
1092
1093 prid = xfs_get_initial_prid(dp);
1094
1095
1096
1097
1098 error = xfs_qm_vop_dqalloc(dp, xfs_kuid_to_uid(current_fsuid()),
1099 xfs_kgid_to_gid(current_fsgid()), prid,
1100 XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT,
1101 &udqp, &gdqp, &pdqp);
1102 if (error)
1103 return error;
1104
1105 if (is_dir) {
1106 rdev = 0;
1107 resblks = XFS_MKDIR_SPACE_RES(mp, name->len);
1108 tres.tr_logres = M_RES(mp)->tr_mkdir.tr_logres;
1109 tres.tr_logcount = XFS_MKDIR_LOG_COUNT;
1110 tp = xfs_trans_alloc(mp, XFS_TRANS_MKDIR);
1111 } else {
1112 resblks = XFS_CREATE_SPACE_RES(mp, name->len);
1113 tres.tr_logres = M_RES(mp)->tr_create.tr_logres;
1114 tres.tr_logcount = XFS_CREATE_LOG_COUNT;
1115 tp = xfs_trans_alloc(mp, XFS_TRANS_CREATE);
1116 }
1117
1118 cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
1119
1120
1121
1122
1123
1124
1125
1126 tres.tr_logflags = XFS_TRANS_PERM_LOG_RES;
1127 error = xfs_trans_reserve(tp, &tres, resblks, 0);
1128 if (error == -ENOSPC) {
1129
1130 xfs_flush_inodes(mp);
1131 error = xfs_trans_reserve(tp, &tres, resblks, 0);
1132 }
1133 if (error == -ENOSPC) {
1134
1135 resblks = 0;
1136 error = xfs_trans_reserve(tp, &tres, 0, 0);
1137 }
1138 if (error) {
1139 cancel_flags = 0;
1140 goto out_trans_cancel;
1141 }
1142
1143 xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
1144 unlock_dp_on_error = true;
1145
1146 xfs_bmap_init(&free_list, &first_block);
1147
1148
1149
1150
1151 error = xfs_trans_reserve_quota(tp, mp, udqp, gdqp,
1152 pdqp, resblks, 1, 0);
1153 if (error)
1154 goto out_trans_cancel;
1155
1156 error = xfs_dir_canenter(tp, dp, name, resblks);
1157 if (error)
1158 goto out_trans_cancel;
1159
1160
1161
1162
1163
1164
1165 error = xfs_dir_ialloc(&tp, dp, mode, is_dir ? 2 : 1, rdev,
1166 prid, resblks > 0, &ip, &committed);
1167 if (error) {
1168 if (error == -ENOSPC)
1169 goto out_trans_cancel;
1170 goto out_trans_abort;
1171 }
1172
1173
1174
1175
1176
1177
1178
1179
1180 xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
1181 unlock_dp_on_error = false;
1182
1183 error = xfs_dir_createname(tp, dp, name, ip->i_ino,
1184 &first_block, &free_list, resblks ?
1185 resblks - XFS_IALLOC_SPACE_RES(mp) : 0);
1186 if (error) {
1187 ASSERT(error != -ENOSPC);
1188 goto out_trans_abort;
1189 }
1190 xfs_trans_ichgtime(tp, dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
1191 xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
1192
1193 if (is_dir) {
1194 error = xfs_dir_init(tp, ip, dp);
1195 if (error)
1196 goto out_bmap_cancel;
1197
1198 error = xfs_bumplink(tp, dp);
1199 if (error)
1200 goto out_bmap_cancel;
1201 }
1202
1203
1204
1205
1206
1207
1208 if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC))
1209 xfs_trans_set_sync(tp);
1210
1211
1212
1213
1214
1215
1216 xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp, pdqp);
1217
1218 error = xfs_bmap_finish(&tp, &free_list, &committed);
1219 if (error)
1220 goto out_bmap_cancel;
1221
1222 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
1223 if (error)
1224 goto out_release_inode;
1225
1226 xfs_qm_dqrele(udqp);
1227 xfs_qm_dqrele(gdqp);
1228 xfs_qm_dqrele(pdqp);
1229
1230 *ipp = ip;
1231 return 0;
1232
1233 out_bmap_cancel:
1234 xfs_bmap_cancel(&free_list);
1235 out_trans_abort:
1236 cancel_flags |= XFS_TRANS_ABORT;
1237 out_trans_cancel:
1238 xfs_trans_cancel(tp, cancel_flags);
1239 out_release_inode:
1240
1241
1242
1243
1244
1245 if (ip)
1246 IRELE(ip);
1247
1248 xfs_qm_dqrele(udqp);
1249 xfs_qm_dqrele(gdqp);
1250 xfs_qm_dqrele(pdqp);
1251
1252 if (unlock_dp_on_error)
1253 xfs_iunlock(dp, XFS_ILOCK_EXCL);
1254 return error;
1255}
1256
1257int
1258xfs_create_tmpfile(
1259 struct xfs_inode *dp,
1260 struct dentry *dentry,
1261 umode_t mode,
1262 struct xfs_inode **ipp)
1263{
1264 struct xfs_mount *mp = dp->i_mount;
1265 struct xfs_inode *ip = NULL;
1266 struct xfs_trans *tp = NULL;
1267 int error;
1268 uint cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
1269 prid_t prid;
1270 struct xfs_dquot *udqp = NULL;
1271 struct xfs_dquot *gdqp = NULL;
1272 struct xfs_dquot *pdqp = NULL;
1273 struct xfs_trans_res *tres;
1274 uint resblks;
1275
1276 if (XFS_FORCED_SHUTDOWN(mp))
1277 return -EIO;
1278
1279 prid = xfs_get_initial_prid(dp);
1280
1281
1282
1283
1284 error = xfs_qm_vop_dqalloc(dp, xfs_kuid_to_uid(current_fsuid()),
1285 xfs_kgid_to_gid(current_fsgid()), prid,
1286 XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT,
1287 &udqp, &gdqp, &pdqp);
1288 if (error)
1289 return error;
1290
1291 resblks = XFS_IALLOC_SPACE_RES(mp);
1292 tp = xfs_trans_alloc(mp, XFS_TRANS_CREATE_TMPFILE);
1293
1294 tres = &M_RES(mp)->tr_create_tmpfile;
1295 error = xfs_trans_reserve(tp, tres, resblks, 0);
1296 if (error == -ENOSPC) {
1297
1298 resblks = 0;
1299 error = xfs_trans_reserve(tp, tres, 0, 0);
1300 }
1301 if (error) {
1302 cancel_flags = 0;
1303 goto out_trans_cancel;
1304 }
1305
1306 error = xfs_trans_reserve_quota(tp, mp, udqp, gdqp,
1307 pdqp, resblks, 1, 0);
1308 if (error)
1309 goto out_trans_cancel;
1310
1311 error = xfs_dir_ialloc(&tp, dp, mode, 1, 0,
1312 prid, resblks > 0, &ip, NULL);
1313 if (error) {
1314 if (error == -ENOSPC)
1315 goto out_trans_cancel;
1316 goto out_trans_abort;
1317 }
1318
1319 if (mp->m_flags & XFS_MOUNT_WSYNC)
1320 xfs_trans_set_sync(tp);
1321
1322
1323
1324
1325
1326
1327 xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp, pdqp);
1328
1329 ip->i_d.di_nlink--;
1330 error = xfs_iunlink(tp, ip);
1331 if (error)
1332 goto out_trans_abort;
1333
1334 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
1335 if (error)
1336 goto out_release_inode;
1337
1338 xfs_qm_dqrele(udqp);
1339 xfs_qm_dqrele(gdqp);
1340 xfs_qm_dqrele(pdqp);
1341
1342 *ipp = ip;
1343 return 0;
1344
1345 out_trans_abort:
1346 cancel_flags |= XFS_TRANS_ABORT;
1347 out_trans_cancel:
1348 xfs_trans_cancel(tp, cancel_flags);
1349 out_release_inode:
1350
1351
1352
1353
1354
1355 if (ip)
1356 IRELE(ip);
1357
1358 xfs_qm_dqrele(udqp);
1359 xfs_qm_dqrele(gdqp);
1360 xfs_qm_dqrele(pdqp);
1361
1362 return error;
1363}
1364
1365int
1366xfs_link(
1367 xfs_inode_t *tdp,
1368 xfs_inode_t *sip,
1369 struct xfs_name *target_name)
1370{
1371 xfs_mount_t *mp = tdp->i_mount;
1372 xfs_trans_t *tp;
1373 int error;
1374 xfs_bmap_free_t free_list;
1375 xfs_fsblock_t first_block;
1376 int cancel_flags;
1377 int committed;
1378 int resblks;
1379
1380 trace_xfs_link(tdp, target_name);
1381
1382 ASSERT(!S_ISDIR(sip->i_d.di_mode));
1383
1384 if (XFS_FORCED_SHUTDOWN(mp))
1385 return -EIO;
1386
1387 error = xfs_qm_dqattach(sip, 0);
1388 if (error)
1389 goto std_return;
1390
1391 error = xfs_qm_dqattach(tdp, 0);
1392 if (error)
1393 goto std_return;
1394
1395 tp = xfs_trans_alloc(mp, XFS_TRANS_LINK);
1396 cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
1397 resblks = XFS_LINK_SPACE_RES(mp, target_name->len);
1398 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_link, resblks, 0);
1399 if (error == -ENOSPC) {
1400 resblks = 0;
1401 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_link, 0, 0);
1402 }
1403 if (error) {
1404 cancel_flags = 0;
1405 goto error_return;
1406 }
1407
1408 xfs_lock_two_inodes(sip, tdp, XFS_ILOCK_EXCL);
1409
1410 xfs_trans_ijoin(tp, sip, XFS_ILOCK_EXCL);
1411 xfs_trans_ijoin(tp, tdp, XFS_ILOCK_EXCL);
1412
1413
1414
1415
1416
1417
1418 if (unlikely((tdp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) &&
1419 (xfs_get_projid(tdp) != xfs_get_projid(sip)))) {
1420 error = -EXDEV;
1421 goto error_return;
1422 }
1423
1424 error = xfs_dir_canenter(tp, tdp, target_name, resblks);
1425 if (error)
1426 goto error_return;
1427
1428 xfs_bmap_init(&free_list, &first_block);
1429
1430 if (sip->i_d.di_nlink == 0) {
1431 error = xfs_iunlink_remove(tp, sip);
1432 if (error)
1433 goto abort_return;
1434 }
1435
1436 error = xfs_dir_createname(tp, tdp, target_name, sip->i_ino,
1437 &first_block, &free_list, resblks);
1438 if (error)
1439 goto abort_return;
1440 xfs_trans_ichgtime(tp, tdp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
1441 xfs_trans_log_inode(tp, tdp, XFS_ILOG_CORE);
1442
1443 error = xfs_bumplink(tp, sip);
1444 if (error)
1445 goto abort_return;
1446
1447
1448
1449
1450
1451
1452 if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) {
1453 xfs_trans_set_sync(tp);
1454 }
1455
1456 error = xfs_bmap_finish (&tp, &free_list, &committed);
1457 if (error) {
1458 xfs_bmap_cancel(&free_list);
1459 goto abort_return;
1460 }
1461
1462 return xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
1463
1464 abort_return:
1465 cancel_flags |= XFS_TRANS_ABORT;
1466 error_return:
1467 xfs_trans_cancel(tp, cancel_flags);
1468 std_return:
1469 return error;
1470}
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493int
1494xfs_itruncate_extents(
1495 struct xfs_trans **tpp,
1496 struct xfs_inode *ip,
1497 int whichfork,
1498 xfs_fsize_t new_size)
1499{
1500 struct xfs_mount *mp = ip->i_mount;
1501 struct xfs_trans *tp = *tpp;
1502 struct xfs_trans *ntp;
1503 xfs_bmap_free_t free_list;
1504 xfs_fsblock_t first_block;
1505 xfs_fileoff_t first_unmap_block;
1506 xfs_fileoff_t last_block;
1507 xfs_filblks_t unmap_len;
1508 int committed;
1509 int error = 0;
1510 int done = 0;
1511
1512 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
1513 ASSERT(!atomic_read(&VFS_I(ip)->i_count) ||
1514 xfs_isilocked(ip, XFS_IOLOCK_EXCL));
1515 ASSERT(new_size <= XFS_ISIZE(ip));
1516 ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES);
1517 ASSERT(ip->i_itemp != NULL);
1518 ASSERT(ip->i_itemp->ili_lock_flags == 0);
1519 ASSERT(!XFS_NOT_DQATTACHED(mp, ip));
1520
1521 trace_xfs_itruncate_extents_start(ip, new_size);
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532 first_unmap_block = XFS_B_TO_FSB(mp, (xfs_ufsize_t)new_size);
1533 last_block = XFS_B_TO_FSB(mp, mp->m_super->s_maxbytes);
1534 if (first_unmap_block == last_block)
1535 return 0;
1536
1537 ASSERT(first_unmap_block < last_block);
1538 unmap_len = last_block - first_unmap_block + 1;
1539 while (!done) {
1540 xfs_bmap_init(&free_list, &first_block);
1541 error = xfs_bunmapi(tp, ip,
1542 first_unmap_block, unmap_len,
1543 xfs_bmapi_aflag(whichfork),
1544 XFS_ITRUNC_MAX_EXTENTS,
1545 &first_block, &free_list,
1546 &done);
1547 if (error)
1548 goto out_bmap_cancel;
1549
1550
1551
1552
1553
1554 error = xfs_bmap_finish(&tp, &free_list, &committed);
1555 if (committed)
1556 xfs_trans_ijoin(tp, ip, 0);
1557 if (error)
1558 goto out_bmap_cancel;
1559
1560 if (committed) {
1561
1562
1563
1564
1565 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
1566 }
1567
1568 ntp = xfs_trans_dup(tp);
1569 error = xfs_trans_commit(tp, 0);
1570 tp = ntp;
1571
1572 xfs_trans_ijoin(tp, ip, 0);
1573
1574 if (error)
1575 goto out;
1576
1577
1578
1579
1580
1581 xfs_log_ticket_put(tp->t_ticket);
1582 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_itruncate, 0, 0);
1583 if (error)
1584 goto out;
1585 }
1586
1587
1588
1589
1590
1591 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
1592
1593 trace_xfs_itruncate_extents_end(ip, new_size);
1594
1595out:
1596 *tpp = tp;
1597 return error;
1598out_bmap_cancel:
1599
1600
1601
1602
1603
1604 xfs_bmap_cancel(&free_list);
1605 goto out;
1606}
1607
1608int
1609xfs_release(
1610 xfs_inode_t *ip)
1611{
1612 xfs_mount_t *mp = ip->i_mount;
1613 int error;
1614
1615 if (!S_ISREG(ip->i_d.di_mode) || (ip->i_d.di_mode == 0))
1616 return 0;
1617
1618
1619 if (mp->m_flags & XFS_MOUNT_RDONLY)
1620 return 0;
1621
1622 if (!XFS_FORCED_SHUTDOWN(mp)) {
1623 int truncated;
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635 truncated = xfs_iflags_test_and_clear(ip, XFS_ITRUNCATED);
1636 if (truncated) {
1637 xfs_iflags_clear(ip, XFS_IDIRTY_RELEASE);
1638 if (ip->i_delayed_blks > 0) {
1639 error = filemap_flush(VFS_I(ip)->i_mapping);
1640 if (error)
1641 return error;
1642 }
1643 }
1644 }
1645
1646 if (ip->i_d.di_nlink == 0)
1647 return 0;
1648
1649 if (xfs_can_free_eofblocks(ip, false)) {
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672 if (xfs_iflags_test(ip, XFS_IDIRTY_RELEASE))
1673 return 0;
1674
1675 error = xfs_free_eofblocks(mp, ip, true);
1676 if (error && error != -EAGAIN)
1677 return error;
1678
1679
1680 if (ip->i_delayed_blks)
1681 xfs_iflags_set(ip, XFS_IDIRTY_RELEASE);
1682 }
1683 return 0;
1684}
1685
1686
1687
1688
1689
1690
1691STATIC int
1692xfs_inactive_truncate(
1693 struct xfs_inode *ip)
1694{
1695 struct xfs_mount *mp = ip->i_mount;
1696 struct xfs_trans *tp;
1697 int error;
1698
1699 tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE);
1700 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_itruncate, 0, 0);
1701 if (error) {
1702 ASSERT(XFS_FORCED_SHUTDOWN(mp));
1703 xfs_trans_cancel(tp, 0);
1704 return error;
1705 }
1706
1707 xfs_ilock(ip, XFS_ILOCK_EXCL);
1708 xfs_trans_ijoin(tp, ip, 0);
1709
1710
1711
1712
1713
1714
1715 ip->i_d.di_size = 0;
1716 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
1717
1718 error = xfs_itruncate_extents(&tp, ip, XFS_DATA_FORK, 0);
1719 if (error)
1720 goto error_trans_cancel;
1721
1722 ASSERT(ip->i_d.di_nextents == 0);
1723
1724 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
1725 if (error)
1726 goto error_unlock;
1727
1728 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1729 return 0;
1730
1731error_trans_cancel:
1732 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT);
1733error_unlock:
1734 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1735 return error;
1736}
1737
1738
1739
1740
1741
1742
1743STATIC int
1744xfs_inactive_ifree(
1745 struct xfs_inode *ip)
1746{
1747 xfs_bmap_free_t free_list;
1748 xfs_fsblock_t first_block;
1749 int committed;
1750 struct xfs_mount *mp = ip->i_mount;
1751 struct xfs_trans *tp;
1752 int error;
1753
1754 tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE);
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771 tp->t_flags |= XFS_TRANS_RESERVE;
1772 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_ifree,
1773 XFS_IFREE_SPACE_RES(mp), 0);
1774 if (error) {
1775 if (error == -ENOSPC) {
1776 xfs_warn_ratelimited(mp,
1777 "Failed to remove inode(s) from unlinked list. "
1778 "Please free space, unmount and run xfs_repair.");
1779 } else {
1780 ASSERT(XFS_FORCED_SHUTDOWN(mp));
1781 }
1782 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES);
1783 return error;
1784 }
1785
1786 xfs_ilock(ip, XFS_ILOCK_EXCL);
1787 xfs_trans_ijoin(tp, ip, 0);
1788
1789 xfs_bmap_init(&free_list, &first_block);
1790 error = xfs_ifree(tp, ip, &free_list);
1791 if (error) {
1792
1793
1794
1795
1796
1797 if (!XFS_FORCED_SHUTDOWN(mp)) {
1798 xfs_notice(mp, "%s: xfs_ifree returned error %d",
1799 __func__, error);
1800 xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR);
1801 }
1802 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT);
1803 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1804 return error;
1805 }
1806
1807
1808
1809
1810 xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_ICOUNT, -1);
1811
1812
1813
1814
1815
1816
1817 error = xfs_bmap_finish(&tp, &free_list, &committed);
1818 if (error)
1819 xfs_notice(mp, "%s: xfs_bmap_finish returned error %d",
1820 __func__, error);
1821 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
1822 if (error)
1823 xfs_notice(mp, "%s: xfs_trans_commit returned error %d",
1824 __func__, error);
1825
1826 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1827 return 0;
1828}
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838void
1839xfs_inactive(
1840 xfs_inode_t *ip)
1841{
1842 struct xfs_mount *mp;
1843 int error;
1844 int truncate = 0;
1845
1846
1847
1848
1849
1850 if (ip->i_d.di_mode == 0) {
1851 ASSERT(ip->i_df.if_real_bytes == 0);
1852 ASSERT(ip->i_df.if_broot_bytes == 0);
1853 return;
1854 }
1855
1856 mp = ip->i_mount;
1857
1858
1859 if (mp->m_flags & XFS_MOUNT_RDONLY)
1860 return;
1861
1862 if (ip->i_d.di_nlink != 0) {
1863
1864
1865
1866
1867
1868 if (xfs_can_free_eofblocks(ip, true))
1869 xfs_free_eofblocks(mp, ip, false);
1870
1871 return;
1872 }
1873
1874 if (S_ISREG(ip->i_d.di_mode) &&
1875 (ip->i_d.di_size != 0 || XFS_ISIZE(ip) != 0 ||
1876 ip->i_d.di_nextents > 0 || ip->i_delayed_blks > 0))
1877 truncate = 1;
1878
1879 error = xfs_qm_dqattach(ip, 0);
1880 if (error)
1881 return;
1882
1883 if (S_ISLNK(ip->i_d.di_mode))
1884 error = xfs_inactive_symlink(ip);
1885 else if (truncate)
1886 error = xfs_inactive_truncate(ip);
1887 if (error)
1888 return;
1889
1890
1891
1892
1893
1894
1895
1896 if (ip->i_d.di_anextents > 0) {
1897 ASSERT(ip->i_d.di_forkoff != 0);
1898
1899 error = xfs_attr_inactive(ip);
1900 if (error)
1901 return;
1902 }
1903
1904 if (ip->i_afp)
1905 xfs_idestroy_fork(ip, XFS_ATTR_FORK);
1906
1907 ASSERT(ip->i_d.di_anextents == 0);
1908
1909
1910
1911
1912 error = xfs_inactive_ifree(ip);
1913 if (error)
1914 return;
1915
1916
1917
1918
1919 xfs_qm_dqdetach(ip);
1920}
1921
1922
1923
1924
1925
1926
1927int
1928xfs_iunlink(
1929 xfs_trans_t *tp,
1930 xfs_inode_t *ip)
1931{
1932 xfs_mount_t *mp;
1933 xfs_agi_t *agi;
1934 xfs_dinode_t *dip;
1935 xfs_buf_t *agibp;
1936 xfs_buf_t *ibp;
1937 xfs_agino_t agino;
1938 short bucket_index;
1939 int offset;
1940 int error;
1941
1942 ASSERT(ip->i_d.di_nlink == 0);
1943 ASSERT(ip->i_d.di_mode != 0);
1944
1945 mp = tp->t_mountp;
1946
1947
1948
1949
1950
1951 error = xfs_read_agi(mp, tp, XFS_INO_TO_AGNO(mp, ip->i_ino), &agibp);
1952 if (error)
1953 return error;
1954 agi = XFS_BUF_TO_AGI(agibp);
1955
1956
1957
1958
1959
1960 agino = XFS_INO_TO_AGINO(mp, ip->i_ino);
1961 ASSERT(agino != 0);
1962 bucket_index = agino % XFS_AGI_UNLINKED_BUCKETS;
1963 ASSERT(agi->agi_unlinked[bucket_index]);
1964 ASSERT(be32_to_cpu(agi->agi_unlinked[bucket_index]) != agino);
1965
1966 if (agi->agi_unlinked[bucket_index] != cpu_to_be32(NULLAGINO)) {
1967
1968
1969
1970
1971
1972
1973 error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &dip, &ibp,
1974 0, 0);
1975 if (error)
1976 return error;
1977
1978 ASSERT(dip->di_next_unlinked == cpu_to_be32(NULLAGINO));
1979 dip->di_next_unlinked = agi->agi_unlinked[bucket_index];
1980 offset = ip->i_imap.im_boffset +
1981 offsetof(xfs_dinode_t, di_next_unlinked);
1982
1983
1984 xfs_dinode_calc_crc(mp, dip);
1985
1986 xfs_trans_inode_buf(tp, ibp);
1987 xfs_trans_log_buf(tp, ibp, offset,
1988 (offset + sizeof(xfs_agino_t) - 1));
1989 xfs_inobp_check(mp, ibp);
1990 }
1991
1992
1993
1994
1995 ASSERT(agino != 0);
1996 agi->agi_unlinked[bucket_index] = cpu_to_be32(agino);
1997 offset = offsetof(xfs_agi_t, agi_unlinked) +
1998 (sizeof(xfs_agino_t) * bucket_index);
1999 xfs_trans_log_buf(tp, agibp, offset,
2000 (offset + sizeof(xfs_agino_t) - 1));
2001 return 0;
2002}
2003
2004
2005
2006
2007STATIC int
2008xfs_iunlink_remove(
2009 xfs_trans_t *tp,
2010 xfs_inode_t *ip)
2011{
2012 xfs_ino_t next_ino;
2013 xfs_mount_t *mp;
2014 xfs_agi_t *agi;
2015 xfs_dinode_t *dip;
2016 xfs_buf_t *agibp;
2017 xfs_buf_t *ibp;
2018 xfs_agnumber_t agno;
2019 xfs_agino_t agino;
2020 xfs_agino_t next_agino;
2021 xfs_buf_t *last_ibp;
2022 xfs_dinode_t *last_dip = NULL;
2023 short bucket_index;
2024 int offset, last_offset = 0;
2025 int error;
2026
2027 mp = tp->t_mountp;
2028 agno = XFS_INO_TO_AGNO(mp, ip->i_ino);
2029
2030
2031
2032
2033
2034 error = xfs_read_agi(mp, tp, agno, &agibp);
2035 if (error)
2036 return error;
2037
2038 agi = XFS_BUF_TO_AGI(agibp);
2039
2040
2041
2042
2043
2044 agino = XFS_INO_TO_AGINO(mp, ip->i_ino);
2045 ASSERT(agino != 0);
2046 bucket_index = agino % XFS_AGI_UNLINKED_BUCKETS;
2047 ASSERT(agi->agi_unlinked[bucket_index] != cpu_to_be32(NULLAGINO));
2048 ASSERT(agi->agi_unlinked[bucket_index]);
2049
2050 if (be32_to_cpu(agi->agi_unlinked[bucket_index]) == agino) {
2051
2052
2053
2054
2055
2056
2057
2058 error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &dip, &ibp,
2059 0, 0);
2060 if (error) {
2061 xfs_warn(mp, "%s: xfs_imap_to_bp returned error %d.",
2062 __func__, error);
2063 return error;
2064 }
2065 next_agino = be32_to_cpu(dip->di_next_unlinked);
2066 ASSERT(next_agino != 0);
2067 if (next_agino != NULLAGINO) {
2068 dip->di_next_unlinked = cpu_to_be32(NULLAGINO);
2069 offset = ip->i_imap.im_boffset +
2070 offsetof(xfs_dinode_t, di_next_unlinked);
2071
2072
2073 xfs_dinode_calc_crc(mp, dip);
2074
2075 xfs_trans_inode_buf(tp, ibp);
2076 xfs_trans_log_buf(tp, ibp, offset,
2077 (offset + sizeof(xfs_agino_t) - 1));
2078 xfs_inobp_check(mp, ibp);
2079 } else {
2080 xfs_trans_brelse(tp, ibp);
2081 }
2082
2083
2084
2085 ASSERT(next_agino != 0);
2086 ASSERT(next_agino != agino);
2087 agi->agi_unlinked[bucket_index] = cpu_to_be32(next_agino);
2088 offset = offsetof(xfs_agi_t, agi_unlinked) +
2089 (sizeof(xfs_agino_t) * bucket_index);
2090 xfs_trans_log_buf(tp, agibp, offset,
2091 (offset + sizeof(xfs_agino_t) - 1));
2092 } else {
2093
2094
2095
2096 next_agino = be32_to_cpu(agi->agi_unlinked[bucket_index]);
2097 last_ibp = NULL;
2098 while (next_agino != agino) {
2099 struct xfs_imap imap;
2100
2101 if (last_ibp)
2102 xfs_trans_brelse(tp, last_ibp);
2103
2104 imap.im_blkno = 0;
2105 next_ino = XFS_AGINO_TO_INO(mp, agno, next_agino);
2106
2107 error = xfs_imap(mp, tp, next_ino, &imap, 0);
2108 if (error) {
2109 xfs_warn(mp,
2110 "%s: xfs_imap returned error %d.",
2111 __func__, error);
2112 return error;
2113 }
2114
2115 error = xfs_imap_to_bp(mp, tp, &imap, &last_dip,
2116 &last_ibp, 0, 0);
2117 if (error) {
2118 xfs_warn(mp,
2119 "%s: xfs_imap_to_bp returned error %d.",
2120 __func__, error);
2121 return error;
2122 }
2123
2124 last_offset = imap.im_boffset;
2125 next_agino = be32_to_cpu(last_dip->di_next_unlinked);
2126 ASSERT(next_agino != NULLAGINO);
2127 ASSERT(next_agino != 0);
2128 }
2129
2130
2131
2132
2133
2134 error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &dip, &ibp,
2135 0, 0);
2136 if (error) {
2137 xfs_warn(mp, "%s: xfs_imap_to_bp(2) returned error %d.",
2138 __func__, error);
2139 return error;
2140 }
2141 next_agino = be32_to_cpu(dip->di_next_unlinked);
2142 ASSERT(next_agino != 0);
2143 ASSERT(next_agino != agino);
2144 if (next_agino != NULLAGINO) {
2145 dip->di_next_unlinked = cpu_to_be32(NULLAGINO);
2146 offset = ip->i_imap.im_boffset +
2147 offsetof(xfs_dinode_t, di_next_unlinked);
2148
2149
2150 xfs_dinode_calc_crc(mp, dip);
2151
2152 xfs_trans_inode_buf(tp, ibp);
2153 xfs_trans_log_buf(tp, ibp, offset,
2154 (offset + sizeof(xfs_agino_t) - 1));
2155 xfs_inobp_check(mp, ibp);
2156 } else {
2157 xfs_trans_brelse(tp, ibp);
2158 }
2159
2160
2161
2162 last_dip->di_next_unlinked = cpu_to_be32(next_agino);
2163 ASSERT(next_agino != 0);
2164 offset = last_offset + offsetof(xfs_dinode_t, di_next_unlinked);
2165
2166
2167 xfs_dinode_calc_crc(mp, last_dip);
2168
2169 xfs_trans_inode_buf(tp, last_ibp);
2170 xfs_trans_log_buf(tp, last_ibp, offset,
2171 (offset + sizeof(xfs_agino_t) - 1));
2172 xfs_inobp_check(mp, last_ibp);
2173 }
2174 return 0;
2175}
2176
2177
2178
2179
2180
2181
2182STATIC int
2183xfs_ifree_cluster(
2184 xfs_inode_t *free_ip,
2185 xfs_trans_t *tp,
2186 xfs_ino_t inum)
2187{
2188 xfs_mount_t *mp = free_ip->i_mount;
2189 int blks_per_cluster;
2190 int inodes_per_cluster;
2191 int nbufs;
2192 int i, j;
2193 xfs_daddr_t blkno;
2194 xfs_buf_t *bp;
2195 xfs_inode_t *ip;
2196 xfs_inode_log_item_t *iip;
2197 xfs_log_item_t *lip;
2198 struct xfs_perag *pag;
2199
2200 pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, inum));
2201 blks_per_cluster = xfs_icluster_size_fsb(mp);
2202 inodes_per_cluster = blks_per_cluster << mp->m_sb.sb_inopblog;
2203 nbufs = mp->m_ialloc_blks / blks_per_cluster;
2204
2205 for (j = 0; j < nbufs; j++, inum += inodes_per_cluster) {
2206 blkno = XFS_AGB_TO_DADDR(mp, XFS_INO_TO_AGNO(mp, inum),
2207 XFS_INO_TO_AGBNO(mp, inum));
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217 bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, blkno,
2218 mp->m_bsize * blks_per_cluster,
2219 XBF_UNMAPPED);
2220
2221 if (!bp)
2222 return -ENOMEM;
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233 bp->b_ops = &xfs_inode_buf_ops;
2234
2235
2236
2237
2238
2239
2240
2241
2242 lip = bp->b_fspriv;
2243 while (lip) {
2244 if (lip->li_type == XFS_LI_INODE) {
2245 iip = (xfs_inode_log_item_t *)lip;
2246 ASSERT(iip->ili_logged == 1);
2247 lip->li_cb = xfs_istale_done;
2248 xfs_trans_ail_copy_lsn(mp->m_ail,
2249 &iip->ili_flush_lsn,
2250 &iip->ili_item.li_lsn);
2251 xfs_iflags_set(iip->ili_inode, XFS_ISTALE);
2252 }
2253 lip = lip->li_bio_list;
2254 }
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267 for (i = 0; i < inodes_per_cluster; i++) {
2268retry:
2269 rcu_read_lock();
2270 ip = radix_tree_lookup(&pag->pag_ici_root,
2271 XFS_INO_TO_AGINO(mp, (inum + i)));
2272
2273
2274 if (!ip) {
2275 rcu_read_unlock();
2276 continue;
2277 }
2278
2279
2280
2281
2282
2283
2284
2285
2286 spin_lock(&ip->i_flags_lock);
2287 if (ip->i_ino != inum + i ||
2288 __xfs_iflags_test(ip, XFS_ISTALE)) {
2289 spin_unlock(&ip->i_flags_lock);
2290 rcu_read_unlock();
2291 continue;
2292 }
2293 spin_unlock(&ip->i_flags_lock);
2294
2295
2296
2297
2298
2299
2300
2301
2302 if (ip != free_ip &&
2303 !xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) {
2304 rcu_read_unlock();
2305 delay(1);
2306 goto retry;
2307 }
2308 rcu_read_unlock();
2309
2310 xfs_iflock(ip);
2311 xfs_iflags_set(ip, XFS_ISTALE);
2312
2313
2314
2315
2316
2317 iip = ip->i_itemp;
2318 if (!iip || xfs_inode_clean(ip)) {
2319 ASSERT(ip != free_ip);
2320 xfs_ifunlock(ip);
2321 xfs_iunlock(ip, XFS_ILOCK_EXCL);
2322 continue;
2323 }
2324
2325 iip->ili_last_fields = iip->ili_fields;
2326 iip->ili_fields = 0;
2327 iip->ili_logged = 1;
2328 xfs_trans_ail_copy_lsn(mp->m_ail, &iip->ili_flush_lsn,
2329 &iip->ili_item.li_lsn);
2330
2331 xfs_buf_attach_iodone(bp, xfs_istale_done,
2332 &iip->ili_item);
2333
2334 if (ip != free_ip)
2335 xfs_iunlock(ip, XFS_ILOCK_EXCL);
2336 }
2337
2338 xfs_trans_stale_inode_buf(tp, bp);
2339 xfs_trans_binval(tp, bp);
2340 }
2341
2342 xfs_perag_put(pag);
2343 return 0;
2344}
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356int
2357xfs_ifree(
2358 xfs_trans_t *tp,
2359 xfs_inode_t *ip,
2360 xfs_bmap_free_t *flist)
2361{
2362 int error;
2363 int delete;
2364 xfs_ino_t first_ino;
2365
2366 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
2367 ASSERT(ip->i_d.di_nlink == 0);
2368 ASSERT(ip->i_d.di_nextents == 0);
2369 ASSERT(ip->i_d.di_anextents == 0);
2370 ASSERT(ip->i_d.di_size == 0 || !S_ISREG(ip->i_d.di_mode));
2371 ASSERT(ip->i_d.di_nblocks == 0);
2372
2373
2374
2375
2376 error = xfs_iunlink_remove(tp, ip);
2377 if (error)
2378 return error;
2379
2380 error = xfs_difree(tp, ip->i_ino, flist, &delete, &first_ino);
2381 if (error)
2382 return error;
2383
2384 ip->i_d.di_mode = 0;
2385 ip->i_d.di_flags = 0;
2386 ip->i_d.di_dmevmask = 0;
2387 ip->i_d.di_forkoff = 0;
2388 ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS;
2389 ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
2390
2391
2392
2393
2394 ip->i_d.di_gen++;
2395 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
2396
2397 if (delete)
2398 error = xfs_ifree_cluster(ip, tp, first_ino);
2399
2400 return error;
2401}
2402
2403
2404
2405
2406
2407
2408static void
2409xfs_iunpin(
2410 struct xfs_inode *ip)
2411{
2412 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED));
2413
2414 trace_xfs_inode_unpin_nowait(ip, _RET_IP_);
2415
2416
2417 xfs_log_force_lsn(ip->i_mount, ip->i_itemp->ili_last_lsn, 0);
2418
2419}
2420
2421static void
2422__xfs_iunpin_wait(
2423 struct xfs_inode *ip)
2424{
2425 wait_queue_head_t *wq = bit_waitqueue(&ip->i_flags, __XFS_IPINNED_BIT);
2426 DEFINE_WAIT_BIT(wait, &ip->i_flags, __XFS_IPINNED_BIT);
2427
2428 xfs_iunpin(ip);
2429
2430 do {
2431 prepare_to_wait(wq, &wait.wait, TASK_UNINTERRUPTIBLE);
2432 if (xfs_ipincount(ip))
2433 io_schedule();
2434 } while (xfs_ipincount(ip));
2435 finish_wait(wq, &wait.wait);
2436}
2437
2438void
2439xfs_iunpin_wait(
2440 struct xfs_inode *ip)
2441{
2442 if (xfs_ipincount(ip))
2443 __xfs_iunpin_wait(ip);
2444}
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473int
2474xfs_remove(
2475 xfs_inode_t *dp,
2476 struct xfs_name *name,
2477 xfs_inode_t *ip)
2478{
2479 xfs_mount_t *mp = dp->i_mount;
2480 xfs_trans_t *tp = NULL;
2481 int is_dir = S_ISDIR(ip->i_d.di_mode);
2482 int error = 0;
2483 xfs_bmap_free_t free_list;
2484 xfs_fsblock_t first_block;
2485 int cancel_flags;
2486 int committed;
2487 int link_zero;
2488 uint resblks;
2489 uint log_count;
2490
2491 trace_xfs_remove(dp, name);
2492
2493 if (XFS_FORCED_SHUTDOWN(mp))
2494 return -EIO;
2495
2496 error = xfs_qm_dqattach(dp, 0);
2497 if (error)
2498 goto std_return;
2499
2500 error = xfs_qm_dqattach(ip, 0);
2501 if (error)
2502 goto std_return;
2503
2504 if (is_dir) {
2505 tp = xfs_trans_alloc(mp, XFS_TRANS_RMDIR);
2506 log_count = XFS_DEFAULT_LOG_COUNT;
2507 } else {
2508 tp = xfs_trans_alloc(mp, XFS_TRANS_REMOVE);
2509 log_count = XFS_REMOVE_LOG_COUNT;
2510 }
2511 cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522 resblks = XFS_REMOVE_SPACE_RES(mp);
2523 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_remove, resblks, 0);
2524 if (error == -ENOSPC) {
2525 resblks = 0;
2526 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_remove, 0, 0);
2527 }
2528 if (error) {
2529 ASSERT(error != -ENOSPC);
2530 cancel_flags = 0;
2531 goto out_trans_cancel;
2532 }
2533
2534 xfs_lock_two_inodes(dp, ip, XFS_ILOCK_EXCL);
2535
2536 xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
2537 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
2538
2539
2540
2541
2542 cancel_flags |= XFS_TRANS_ABORT;
2543 if (is_dir) {
2544 ASSERT(ip->i_d.di_nlink >= 2);
2545 if (ip->i_d.di_nlink != 2) {
2546 error = -ENOTEMPTY;
2547 goto out_trans_cancel;
2548 }
2549 if (!xfs_dir_isempty(ip)) {
2550 error = -ENOTEMPTY;
2551 goto out_trans_cancel;
2552 }
2553
2554
2555 error = xfs_droplink(tp, dp);
2556 if (error)
2557 goto out_trans_cancel;
2558
2559
2560 error = xfs_droplink(tp, ip);
2561 if (error)
2562 goto out_trans_cancel;
2563 } else {
2564
2565
2566
2567
2568
2569 xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
2570 }
2571 xfs_trans_ichgtime(tp, dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
2572
2573
2574 error = xfs_droplink(tp, ip);
2575 if (error)
2576 goto out_trans_cancel;
2577
2578
2579 link_zero = (ip->i_d.di_nlink == 0);
2580
2581 xfs_bmap_init(&free_list, &first_block);
2582 error = xfs_dir_removename(tp, dp, name, ip->i_ino,
2583 &first_block, &free_list, resblks);
2584 if (error) {
2585 ASSERT(error != -ENOENT);
2586 goto out_bmap_cancel;
2587 }
2588
2589
2590
2591
2592
2593
2594 if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC))
2595 xfs_trans_set_sync(tp);
2596
2597 error = xfs_bmap_finish(&tp, &free_list, &committed);
2598 if (error)
2599 goto out_bmap_cancel;
2600
2601 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
2602 if (error)
2603 goto std_return;
2604
2605 if (is_dir && xfs_inode_is_filestream(ip))
2606 xfs_filestream_deassociate(ip);
2607
2608 return 0;
2609
2610 out_bmap_cancel:
2611 xfs_bmap_cancel(&free_list);
2612 out_trans_cancel:
2613 xfs_trans_cancel(tp, cancel_flags);
2614 std_return:
2615 return error;
2616}
2617
2618
2619
2620
2621STATIC void
2622xfs_sort_for_rename(
2623 xfs_inode_t *dp1,
2624 xfs_inode_t *dp2,
2625 xfs_inode_t *ip1,
2626 xfs_inode_t *ip2,
2627
2628 xfs_inode_t **i_tab,
2629 int *num_inodes)
2630{
2631 xfs_inode_t *temp;
2632 int i, j;
2633
2634
2635
2636
2637
2638
2639
2640
2641 i_tab[0] = dp1;
2642 i_tab[1] = dp2;
2643 i_tab[2] = ip1;
2644 if (ip2) {
2645 *num_inodes = 4;
2646 i_tab[3] = ip2;
2647 } else {
2648 *num_inodes = 3;
2649 i_tab[3] = NULL;
2650 }
2651
2652
2653
2654
2655
2656 for (i = 0; i < *num_inodes; i++) {
2657 for (j = 1; j < *num_inodes; j++) {
2658 if (i_tab[j]->i_ino < i_tab[j-1]->i_ino) {
2659 temp = i_tab[j];
2660 i_tab[j] = i_tab[j-1];
2661 i_tab[j-1] = temp;
2662 }
2663 }
2664 }
2665}
2666
2667
2668
2669
2670int
2671xfs_rename(
2672 xfs_inode_t *src_dp,
2673 struct xfs_name *src_name,
2674 xfs_inode_t *src_ip,
2675 xfs_inode_t *target_dp,
2676 struct xfs_name *target_name,
2677 xfs_inode_t *target_ip)
2678{
2679 xfs_trans_t *tp = NULL;
2680 xfs_mount_t *mp = src_dp->i_mount;
2681 int new_parent;
2682 int src_is_directory;
2683 int error;
2684 xfs_bmap_free_t free_list;
2685 xfs_fsblock_t first_block;
2686 int cancel_flags;
2687 int committed;
2688 xfs_inode_t *inodes[4];
2689 int spaceres;
2690 int num_inodes;
2691
2692 trace_xfs_rename(src_dp, target_dp, src_name, target_name);
2693
2694 new_parent = (src_dp != target_dp);
2695 src_is_directory = S_ISDIR(src_ip->i_d.di_mode);
2696
2697 xfs_sort_for_rename(src_dp, target_dp, src_ip, target_ip,
2698 inodes, &num_inodes);
2699
2700 xfs_bmap_init(&free_list, &first_block);
2701 tp = xfs_trans_alloc(mp, XFS_TRANS_RENAME);
2702 cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
2703 spaceres = XFS_RENAME_SPACE_RES(mp, target_name->len);
2704 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_rename, spaceres, 0);
2705 if (error == -ENOSPC) {
2706 spaceres = 0;
2707 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_rename, 0, 0);
2708 }
2709 if (error) {
2710 xfs_trans_cancel(tp, 0);
2711 goto std_return;
2712 }
2713
2714
2715
2716
2717 error = xfs_qm_vop_rename_dqattach(inodes);
2718 if (error) {
2719 xfs_trans_cancel(tp, cancel_flags);
2720 goto std_return;
2721 }
2722
2723
2724
2725
2726
2727
2728
2729 xfs_lock_inodes(inodes, num_inodes, XFS_ILOCK_EXCL);
2730
2731
2732
2733
2734
2735
2736 xfs_trans_ijoin(tp, src_dp, XFS_ILOCK_EXCL);
2737 if (new_parent)
2738 xfs_trans_ijoin(tp, target_dp, XFS_ILOCK_EXCL);
2739 xfs_trans_ijoin(tp, src_ip, XFS_ILOCK_EXCL);
2740 if (target_ip)
2741 xfs_trans_ijoin(tp, target_ip, XFS_ILOCK_EXCL);
2742
2743
2744
2745
2746
2747
2748 if (unlikely((target_dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) &&
2749 (xfs_get_projid(target_dp) != xfs_get_projid(src_ip)))) {
2750 error = -EXDEV;
2751 goto error_return;
2752 }
2753
2754
2755
2756
2757 if (target_ip == NULL) {
2758
2759
2760
2761
2762 error = xfs_dir_canenter(tp, target_dp, target_name, spaceres);
2763 if (error)
2764 goto error_return;
2765
2766
2767
2768
2769
2770 error = xfs_dir_createname(tp, target_dp, target_name,
2771 src_ip->i_ino, &first_block,
2772 &free_list, spaceres);
2773 if (error == -ENOSPC)
2774 goto error_return;
2775 if (error)
2776 goto abort_return;
2777
2778 xfs_trans_ichgtime(tp, target_dp,
2779 XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
2780
2781 if (new_parent && src_is_directory) {
2782 error = xfs_bumplink(tp, target_dp);
2783 if (error)
2784 goto abort_return;
2785 }
2786 } else {
2787
2788
2789
2790
2791
2792 if (S_ISDIR(target_ip->i_d.di_mode)) {
2793
2794
2795
2796 if (!(xfs_dir_isempty(target_ip)) ||
2797 (target_ip->i_d.di_nlink > 2)) {
2798 error = -EEXIST;
2799 goto error_return;
2800 }
2801 }
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812 error = xfs_dir_replace(tp, target_dp, target_name,
2813 src_ip->i_ino,
2814 &first_block, &free_list, spaceres);
2815 if (error)
2816 goto abort_return;
2817
2818 xfs_trans_ichgtime(tp, target_dp,
2819 XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
2820
2821
2822
2823
2824
2825 error = xfs_droplink(tp, target_ip);
2826 if (error)
2827 goto abort_return;
2828
2829 if (src_is_directory) {
2830
2831
2832
2833 error = xfs_droplink(tp, target_ip);
2834 if (error)
2835 goto abort_return;
2836 }
2837 }
2838
2839
2840
2841
2842 if (new_parent && src_is_directory) {
2843
2844
2845
2846
2847 error = xfs_dir_replace(tp, src_ip, &xfs_name_dotdot,
2848 target_dp->i_ino,
2849 &first_block, &free_list, spaceres);
2850 ASSERT(error != -EEXIST);
2851 if (error)
2852 goto abort_return;
2853 }
2854
2855
2856
2857
2858
2859
2860
2861
2862 xfs_trans_ichgtime(tp, src_ip, XFS_ICHGTIME_CHG);
2863 xfs_trans_log_inode(tp, src_ip, XFS_ILOG_CORE);
2864
2865
2866
2867
2868
2869
2870 if (src_is_directory && (new_parent || target_ip != NULL)) {
2871
2872
2873
2874
2875
2876 error = xfs_droplink(tp, src_dp);
2877 if (error)
2878 goto abort_return;
2879 }
2880
2881 error = xfs_dir_removename(tp, src_dp, src_name, src_ip->i_ino,
2882 &first_block, &free_list, spaceres);
2883 if (error)
2884 goto abort_return;
2885
2886 xfs_trans_ichgtime(tp, src_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
2887 xfs_trans_log_inode(tp, src_dp, XFS_ILOG_CORE);
2888 if (new_parent)
2889 xfs_trans_log_inode(tp, target_dp, XFS_ILOG_CORE);
2890
2891
2892
2893
2894
2895
2896 if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) {
2897 xfs_trans_set_sync(tp);
2898 }
2899
2900 error = xfs_bmap_finish(&tp, &free_list, &committed);
2901 if (error) {
2902 xfs_bmap_cancel(&free_list);
2903 xfs_trans_cancel(tp, (XFS_TRANS_RELEASE_LOG_RES |
2904 XFS_TRANS_ABORT));
2905 goto std_return;
2906 }
2907
2908
2909
2910
2911
2912 return xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
2913
2914 abort_return:
2915 cancel_flags |= XFS_TRANS_ABORT;
2916 error_return:
2917 xfs_bmap_cancel(&free_list);
2918 xfs_trans_cancel(tp, cancel_flags);
2919 std_return:
2920 return error;
2921}
2922
2923STATIC int
2924xfs_iflush_cluster(
2925 xfs_inode_t *ip,
2926 xfs_buf_t *bp)
2927{
2928 xfs_mount_t *mp = ip->i_mount;
2929 struct xfs_perag *pag;
2930 unsigned long first_index, mask;
2931 unsigned long inodes_per_cluster;
2932 int ilist_size;
2933 xfs_inode_t **ilist;
2934 xfs_inode_t *iq;
2935 int nr_found;
2936 int clcount = 0;
2937 int bufwasdelwri;
2938 int i;
2939
2940 pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino));
2941
2942 inodes_per_cluster = mp->m_inode_cluster_size >> mp->m_sb.sb_inodelog;
2943 ilist_size = inodes_per_cluster * sizeof(xfs_inode_t *);
2944 ilist = kmem_alloc(ilist_size, KM_MAYFAIL|KM_NOFS);
2945 if (!ilist)
2946 goto out_put;
2947
2948 mask = ~(((mp->m_inode_cluster_size >> mp->m_sb.sb_inodelog)) - 1);
2949 first_index = XFS_INO_TO_AGINO(mp, ip->i_ino) & mask;
2950 rcu_read_lock();
2951
2952 nr_found = radix_tree_gang_lookup(&pag->pag_ici_root, (void**)ilist,
2953 first_index, inodes_per_cluster);
2954 if (nr_found == 0)
2955 goto out_free;
2956
2957 for (i = 0; i < nr_found; i++) {
2958 iq = ilist[i];
2959 if (iq == ip)
2960 continue;
2961
2962
2963
2964
2965
2966
2967
2968 spin_lock(&ip->i_flags_lock);
2969 if (!ip->i_ino ||
2970 (XFS_INO_TO_AGINO(mp, iq->i_ino) & mask) != first_index) {
2971 spin_unlock(&ip->i_flags_lock);
2972 continue;
2973 }
2974 spin_unlock(&ip->i_flags_lock);
2975
2976
2977
2978
2979
2980
2981 if (xfs_inode_clean(iq) && xfs_ipincount(iq) == 0)
2982 continue;
2983
2984
2985
2986
2987
2988
2989 if (!xfs_ilock_nowait(iq, XFS_ILOCK_SHARED))
2990 continue;
2991 if (!xfs_iflock_nowait(iq)) {
2992 xfs_iunlock(iq, XFS_ILOCK_SHARED);
2993 continue;
2994 }
2995 if (xfs_ipincount(iq)) {
2996 xfs_ifunlock(iq);
2997 xfs_iunlock(iq, XFS_ILOCK_SHARED);
2998 continue;
2999 }
3000
3001
3002
3003
3004
3005 if (!xfs_inode_clean(iq)) {
3006 int error;
3007 error = xfs_iflush_int(iq, bp);
3008 if (error) {
3009 xfs_iunlock(iq, XFS_ILOCK_SHARED);
3010 goto cluster_corrupt_out;
3011 }
3012 clcount++;
3013 } else {
3014 xfs_ifunlock(iq);
3015 }
3016 xfs_iunlock(iq, XFS_ILOCK_SHARED);
3017 }
3018
3019 if (clcount) {
3020 XFS_STATS_INC(xs_icluster_flushcnt);
3021 XFS_STATS_ADD(xs_icluster_flushinode, clcount);
3022 }
3023
3024out_free:
3025 rcu_read_unlock();
3026 kmem_free(ilist);
3027out_put:
3028 xfs_perag_put(pag);
3029 return 0;
3030
3031
3032cluster_corrupt_out:
3033
3034
3035
3036
3037 rcu_read_unlock();
3038
3039
3040
3041
3042
3043 bufwasdelwri = (bp->b_flags & _XBF_DELWRI_Q);
3044 if (bufwasdelwri)
3045 xfs_buf_relse(bp);
3046
3047 xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
3048
3049 if (!bufwasdelwri) {
3050
3051
3052
3053
3054
3055 if (bp->b_iodone) {
3056 XFS_BUF_UNDONE(bp);
3057 xfs_buf_stale(bp);
3058 xfs_buf_ioerror(bp, -EIO);
3059 xfs_buf_ioend(bp, 0);
3060 } else {
3061 xfs_buf_stale(bp);
3062 xfs_buf_relse(bp);
3063 }
3064 }
3065
3066
3067
3068
3069 xfs_iflush_abort(iq, false);
3070 kmem_free(ilist);
3071 xfs_perag_put(pag);
3072 return -EFSCORRUPTED;
3073}
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084int
3085xfs_iflush(
3086 struct xfs_inode *ip,
3087 struct xfs_buf **bpp)
3088{
3089 struct xfs_mount *mp = ip->i_mount;
3090 struct xfs_buf *bp;
3091 struct xfs_dinode *dip;
3092 int error;
3093
3094 XFS_STATS_INC(xs_iflush_count);
3095
3096 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED));
3097 ASSERT(xfs_isiflocked(ip));
3098 ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE ||
3099 ip->i_d.di_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK));
3100
3101 *bpp = NULL;
3102
3103 xfs_iunpin_wait(ip);
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113 if (xfs_iflags_test(ip, XFS_ISTALE)) {
3114 xfs_ifunlock(ip);
3115 return 0;
3116 }
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126 if (XFS_FORCED_SHUTDOWN(mp)) {
3127 error = -EIO;
3128 goto abort_out;
3129 }
3130
3131
3132
3133
3134 error = xfs_imap_to_bp(mp, NULL, &ip->i_imap, &dip, &bp, XBF_TRYLOCK,
3135 0);
3136 if (error || !bp) {
3137 xfs_ifunlock(ip);
3138 return error;
3139 }
3140
3141
3142
3143
3144 error = xfs_iflush_int(ip, bp);
3145 if (error)
3146 goto corrupt_out;
3147
3148
3149
3150
3151
3152 if (xfs_buf_ispinned(bp))
3153 xfs_log_force(mp, 0);
3154
3155
3156
3157
3158
3159 error = xfs_iflush_cluster(ip, bp);
3160 if (error)
3161 goto cluster_corrupt_out;
3162
3163 *bpp = bp;
3164 return 0;
3165
3166corrupt_out:
3167 xfs_buf_relse(bp);
3168 xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
3169cluster_corrupt_out:
3170 error = -EFSCORRUPTED;
3171abort_out:
3172
3173
3174
3175 xfs_iflush_abort(ip, false);
3176 return error;
3177}
3178
3179STATIC int
3180xfs_iflush_int(
3181 struct xfs_inode *ip,
3182 struct xfs_buf *bp)
3183{
3184 struct xfs_inode_log_item *iip = ip->i_itemp;
3185 struct xfs_dinode *dip;
3186 struct xfs_mount *mp = ip->i_mount;
3187
3188 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED));
3189 ASSERT(xfs_isiflocked(ip));
3190 ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE ||
3191 ip->i_d.di_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK));
3192 ASSERT(iip != NULL && iip->ili_fields != 0);
3193 ASSERT(ip->i_d.di_version > 1);
3194
3195
3196 dip = (xfs_dinode_t *)xfs_buf_offset(bp, ip->i_imap.im_boffset);
3197
3198 if (XFS_TEST_ERROR(dip->di_magic != cpu_to_be16(XFS_DINODE_MAGIC),
3199 mp, XFS_ERRTAG_IFLUSH_1, XFS_RANDOM_IFLUSH_1)) {
3200 xfs_alert_tag(mp, XFS_PTAG_IFLUSH,
3201 "%s: Bad inode %Lu magic number 0x%x, ptr 0x%p",
3202 __func__, ip->i_ino, be16_to_cpu(dip->di_magic), dip);
3203 goto corrupt_out;
3204 }
3205 if (XFS_TEST_ERROR(ip->i_d.di_magic != XFS_DINODE_MAGIC,
3206 mp, XFS_ERRTAG_IFLUSH_2, XFS_RANDOM_IFLUSH_2)) {
3207 xfs_alert_tag(mp, XFS_PTAG_IFLUSH,
3208 "%s: Bad inode %Lu, ptr 0x%p, magic number 0x%x",
3209 __func__, ip->i_ino, ip, ip->i_d.di_magic);
3210 goto corrupt_out;
3211 }
3212 if (S_ISREG(ip->i_d.di_mode)) {
3213 if (XFS_TEST_ERROR(
3214 (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS) &&
3215 (ip->i_d.di_format != XFS_DINODE_FMT_BTREE),
3216 mp, XFS_ERRTAG_IFLUSH_3, XFS_RANDOM_IFLUSH_3)) {
3217 xfs_alert_tag(mp, XFS_PTAG_IFLUSH,
3218 "%s: Bad regular inode %Lu, ptr 0x%p",
3219 __func__, ip->i_ino, ip);
3220 goto corrupt_out;
3221 }
3222 } else if (S_ISDIR(ip->i_d.di_mode)) {
3223 if (XFS_TEST_ERROR(
3224 (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS) &&
3225 (ip->i_d.di_format != XFS_DINODE_FMT_BTREE) &&
3226 (ip->i_d.di_format != XFS_DINODE_FMT_LOCAL),
3227 mp, XFS_ERRTAG_IFLUSH_4, XFS_RANDOM_IFLUSH_4)) {
3228 xfs_alert_tag(mp, XFS_PTAG_IFLUSH,
3229 "%s: Bad directory inode %Lu, ptr 0x%p",
3230 __func__, ip->i_ino, ip);
3231 goto corrupt_out;
3232 }
3233 }
3234 if (XFS_TEST_ERROR(ip->i_d.di_nextents + ip->i_d.di_anextents >
3235 ip->i_d.di_nblocks, mp, XFS_ERRTAG_IFLUSH_5,
3236 XFS_RANDOM_IFLUSH_5)) {
3237 xfs_alert_tag(mp, XFS_PTAG_IFLUSH,
3238 "%s: detected corrupt incore inode %Lu, "
3239 "total extents = %d, nblocks = %Ld, ptr 0x%p",
3240 __func__, ip->i_ino,
3241 ip->i_d.di_nextents + ip->i_d.di_anextents,
3242 ip->i_d.di_nblocks, ip);
3243 goto corrupt_out;
3244 }
3245 if (XFS_TEST_ERROR(ip->i_d.di_forkoff > mp->m_sb.sb_inodesize,
3246 mp, XFS_ERRTAG_IFLUSH_6, XFS_RANDOM_IFLUSH_6)) {
3247 xfs_alert_tag(mp, XFS_PTAG_IFLUSH,
3248 "%s: bad inode %Lu, forkoff 0x%x, ptr 0x%p",
3249 __func__, ip->i_ino, ip->i_d.di_forkoff, ip);
3250 goto corrupt_out;
3251 }
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262 if (ip->i_d.di_version < 3)
3263 ip->i_d.di_flushiter++;
3264
3265
3266
3267
3268
3269
3270
3271 xfs_dinode_to_disk(dip, &ip->i_d);
3272
3273
3274 if (ip->i_d.di_flushiter == DI_MAX_FLUSH)
3275 ip->i_d.di_flushiter = 0;
3276
3277 xfs_iflush_fork(ip, dip, iip, XFS_DATA_FORK);
3278 if (XFS_IFORK_Q(ip))
3279 xfs_iflush_fork(ip, dip, iip, XFS_ATTR_FORK);
3280 xfs_inobp_check(mp, bp);
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307 iip->ili_last_fields = iip->ili_fields;
3308 iip->ili_fields = 0;
3309 iip->ili_logged = 1;
3310
3311 xfs_trans_ail_copy_lsn(mp->m_ail, &iip->ili_flush_lsn,
3312 &iip->ili_item.li_lsn);
3313
3314
3315
3316
3317
3318
3319
3320 xfs_buf_attach_iodone(bp, xfs_iflush_done, &iip->ili_item);
3321
3322
3323 if (ip->i_d.di_version == 3)
3324 dip->di_lsn = cpu_to_be64(iip->ili_item.li_lsn);
3325
3326
3327 xfs_dinode_calc_crc(mp, dip);
3328
3329 ASSERT(bp->b_fspriv != NULL);
3330 ASSERT(bp->b_iodone != NULL);
3331 return 0;
3332
3333corrupt_out:
3334 return -EFSCORRUPTED;
3335}
3336