]> Git Repo - J-linux.git/blob - fs/xfs/xfs_inode_item.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / fs / xfs / xfs_inode_item.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
4  * All Rights Reserved.
5  */
6 #include "xfs.h"
7 #include "xfs_fs.h"
8 #include "xfs_shared.h"
9 #include "xfs_format.h"
10 #include "xfs_log_format.h"
11 #include "xfs_trans_resv.h"
12 #include "xfs_mount.h"
13 #include "xfs_inode.h"
14 #include "xfs_trans.h"
15 #include "xfs_inode_item.h"
16 #include "xfs_trace.h"
17 #include "xfs_trans_priv.h"
18 #include "xfs_buf_item.h"
19 #include "xfs_log.h"
20 #include "xfs_log_priv.h"
21 #include "xfs_error.h"
22 #include "xfs_rtbitmap.h"
23
24 #include <linux/iversion.h>
25
26 struct kmem_cache       *xfs_ili_cache;         /* inode log item */
27
28 static inline struct xfs_inode_log_item *INODE_ITEM(struct xfs_log_item *lip)
29 {
30         return container_of(lip, struct xfs_inode_log_item, ili_item);
31 }
32
33 static uint64_t
34 xfs_inode_item_sort(
35         struct xfs_log_item     *lip)
36 {
37         return INODE_ITEM(lip)->ili_inode->i_ino;
38 }
39
40 #ifdef DEBUG_EXPENSIVE
41 static void
42 xfs_inode_item_precommit_check(
43         struct xfs_inode        *ip)
44 {
45         struct xfs_mount        *mp = ip->i_mount;
46         struct xfs_dinode       *dip;
47         xfs_failaddr_t          fa;
48
49         dip = kzalloc(mp->m_sb.sb_inodesize, GFP_KERNEL | GFP_NOFS);
50         if (!dip) {
51                 ASSERT(dip != NULL);
52                 return;
53         }
54
55         xfs_inode_to_disk(ip, dip, 0);
56         xfs_dinode_calc_crc(mp, dip);
57         fa = xfs_dinode_verify(mp, ip->i_ino, dip);
58         if (fa) {
59                 xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, dip,
60                                 sizeof(*dip), fa);
61                 xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
62                 ASSERT(fa == NULL);
63         }
64         kfree(dip);
65 }
66 #else
67 # define xfs_inode_item_precommit_check(ip)     ((void)0)
68 #endif
69
70 /*
71  * Prior to finally logging the inode, we have to ensure that all the
72  * per-modification inode state changes are applied. This includes VFS inode
73  * state updates, format conversions, verifier state synchronisation and
74  * ensuring the inode buffer remains in memory whilst the inode is dirty.
75  *
76  * We have to be careful when we grab the inode cluster buffer due to lock
77  * ordering constraints. The unlinked inode modifications (xfs_iunlink_item)
78  * require AGI -> inode cluster buffer lock order. The inode cluster buffer is
79  * not locked until ->precommit, so it happens after everything else has been
80  * modified.
81  *
82  * Further, we have AGI -> AGF lock ordering, and with O_TMPFILE handling we
83  * have AGI -> AGF -> iunlink item -> inode cluster buffer lock order. Hence we
84  * cannot safely lock the inode cluster buffer in xfs_trans_log_inode() because
85  * it can be called on a inode (e.g. via bumplink/droplink) before we take the
86  * AGF lock modifying directory blocks.
87  *
88  * Rather than force a complete rework of all the transactions to call
89  * xfs_trans_log_inode() once and once only at the end of every transaction, we
90  * move the pinning of the inode cluster buffer to a ->precommit operation. This
91  * matches how the xfs_iunlink_item locks the inode cluster buffer, and it
92  * ensures that the inode cluster buffer locking is always done last in a
93  * transaction. i.e. we ensure the lock order is always AGI -> AGF -> inode
94  * cluster buffer.
95  *
96  * If we return the inode number as the precommit sort key then we'll also
97  * guarantee that the order all inode cluster buffer locking is the same all the
98  * inodes and unlink items in the transaction.
99  */
100 static int
101 xfs_inode_item_precommit(
102         struct xfs_trans        *tp,
103         struct xfs_log_item     *lip)
104 {
105         struct xfs_inode_log_item *iip = INODE_ITEM(lip);
106         struct xfs_inode        *ip = iip->ili_inode;
107         struct inode            *inode = VFS_I(ip);
108         unsigned int            flags = iip->ili_dirty_flags;
109
110         /*
111          * Don't bother with i_lock for the I_DIRTY_TIME check here, as races
112          * don't matter - we either will need an extra transaction in 24 hours
113          * to log the timestamps, or will clear already cleared fields in the
114          * worst case.
115          */
116         if (inode->i_state & I_DIRTY_TIME) {
117                 spin_lock(&inode->i_lock);
118                 inode->i_state &= ~I_DIRTY_TIME;
119                 spin_unlock(&inode->i_lock);
120         }
121
122         /*
123          * If we're updating the inode core or the timestamps and it's possible
124          * to upgrade this inode to bigtime format, do so now.
125          */
126         if ((flags & (XFS_ILOG_CORE | XFS_ILOG_TIMESTAMP)) &&
127             xfs_has_bigtime(ip->i_mount) &&
128             !xfs_inode_has_bigtime(ip)) {
129                 ip->i_diflags2 |= XFS_DIFLAG2_BIGTIME;
130                 flags |= XFS_ILOG_CORE;
131         }
132
133         /*
134          * Inode verifiers do not check that the extent size hint is an integer
135          * multiple of the rt extent size on a directory with both rtinherit
136          * and extszinherit flags set.  If we're logging a directory that is
137          * misconfigured in this way, clear the hint.
138          */
139         if ((ip->i_diflags & XFS_DIFLAG_RTINHERIT) &&
140             (ip->i_diflags & XFS_DIFLAG_EXTSZINHERIT) &&
141             xfs_extlen_to_rtxmod(ip->i_mount, ip->i_extsize) > 0) {
142                 ip->i_diflags &= ~(XFS_DIFLAG_EXTSIZE |
143                                    XFS_DIFLAG_EXTSZINHERIT);
144                 ip->i_extsize = 0;
145                 flags |= XFS_ILOG_CORE;
146         }
147
148         /*
149          * Record the specific change for fdatasync optimisation. This allows
150          * fdatasync to skip log forces for inodes that are only timestamp
151          * dirty. Once we've processed the XFS_ILOG_IVERSION flag, convert it
152          * to XFS_ILOG_CORE so that the actual on-disk dirty tracking
153          * (ili_fields) correctly tracks that the version has changed.
154          */
155         spin_lock(&iip->ili_lock);
156         iip->ili_fsync_fields |= (flags & ~XFS_ILOG_IVERSION);
157         if (flags & XFS_ILOG_IVERSION)
158                 flags = ((flags & ~XFS_ILOG_IVERSION) | XFS_ILOG_CORE);
159
160         if (!iip->ili_item.li_buf) {
161                 struct xfs_buf  *bp;
162                 int             error;
163
164                 /*
165                  * We hold the ILOCK here, so this inode is not going to be
166                  * flushed while we are here. Further, because there is no
167                  * buffer attached to the item, we know that there is no IO in
168                  * progress, so nothing will clear the ili_fields while we read
169                  * in the buffer. Hence we can safely drop the spin lock and
170                  * read the buffer knowing that the state will not change from
171                  * here.
172                  */
173                 spin_unlock(&iip->ili_lock);
174                 error = xfs_imap_to_bp(ip->i_mount, tp, &ip->i_imap, &bp);
175                 if (error)
176                         return error;
177
178                 /*
179                  * We need an explicit buffer reference for the log item but
180                  * don't want the buffer to remain attached to the transaction.
181                  * Hold the buffer but release the transaction reference once
182                  * we've attached the inode log item to the buffer log item
183                  * list.
184                  */
185                 xfs_buf_hold(bp);
186                 spin_lock(&iip->ili_lock);
187                 iip->ili_item.li_buf = bp;
188                 bp->b_flags |= _XBF_INODES;
189                 list_add_tail(&iip->ili_item.li_bio_list, &bp->b_li_list);
190                 xfs_trans_brelse(tp, bp);
191         }
192
193         /*
194          * Always OR in the bits from the ili_last_fields field.  This is to
195          * coordinate with the xfs_iflush() and xfs_buf_inode_iodone() routines
196          * in the eventual clearing of the ili_fields bits.  See the big comment
197          * in xfs_iflush() for an explanation of this coordination mechanism.
198          */
199         iip->ili_fields |= (flags | iip->ili_last_fields);
200         spin_unlock(&iip->ili_lock);
201
202         xfs_inode_item_precommit_check(ip);
203
204         /*
205          * We are done with the log item transaction dirty state, so clear it so
206          * that it doesn't pollute future transactions.
207          */
208         iip->ili_dirty_flags = 0;
209         return 0;
210 }
211
212 /*
213  * The logged size of an inode fork is always the current size of the inode
214  * fork. This means that when an inode fork is relogged, the size of the logged
215  * region is determined by the current state, not the combination of the
216  * previously logged state + the current state. This is different relogging
217  * behaviour to most other log items which will retain the size of the
218  * previously logged changes when smaller regions are relogged.
219  *
220  * Hence operations that remove data from the inode fork (e.g. shortform
221  * dir/attr remove, extent form extent removal, etc), the size of the relogged
222  * inode gets -smaller- rather than stays the same size as the previously logged
223  * size and this can result in the committing transaction reducing the amount of
224  * space being consumed by the CIL.
225  */
226 STATIC void
227 xfs_inode_item_data_fork_size(
228         struct xfs_inode_log_item *iip,
229         int                     *nvecs,
230         int                     *nbytes)
231 {
232         struct xfs_inode        *ip = iip->ili_inode;
233
234         switch (ip->i_df.if_format) {
235         case XFS_DINODE_FMT_EXTENTS:
236                 if ((iip->ili_fields & XFS_ILOG_DEXT) &&
237                     ip->i_df.if_nextents > 0 &&
238                     ip->i_df.if_bytes > 0) {
239                         /* worst case, doesn't subtract delalloc extents */
240                         *nbytes += xfs_inode_data_fork_size(ip);
241                         *nvecs += 1;
242                 }
243                 break;
244         case XFS_DINODE_FMT_BTREE:
245                 if ((iip->ili_fields & XFS_ILOG_DBROOT) &&
246                     ip->i_df.if_broot_bytes > 0) {
247                         *nbytes += ip->i_df.if_broot_bytes;
248                         *nvecs += 1;
249                 }
250                 break;
251         case XFS_DINODE_FMT_LOCAL:
252                 if ((iip->ili_fields & XFS_ILOG_DDATA) &&
253                     ip->i_df.if_bytes > 0) {
254                         *nbytes += xlog_calc_iovec_len(ip->i_df.if_bytes);
255                         *nvecs += 1;
256                 }
257                 break;
258
259         case XFS_DINODE_FMT_DEV:
260                 break;
261         default:
262                 ASSERT(0);
263                 break;
264         }
265 }
266
267 STATIC void
268 xfs_inode_item_attr_fork_size(
269         struct xfs_inode_log_item *iip,
270         int                     *nvecs,
271         int                     *nbytes)
272 {
273         struct xfs_inode        *ip = iip->ili_inode;
274
275         switch (ip->i_af.if_format) {
276         case XFS_DINODE_FMT_EXTENTS:
277                 if ((iip->ili_fields & XFS_ILOG_AEXT) &&
278                     ip->i_af.if_nextents > 0 &&
279                     ip->i_af.if_bytes > 0) {
280                         /* worst case, doesn't subtract unused space */
281                         *nbytes += xfs_inode_attr_fork_size(ip);
282                         *nvecs += 1;
283                 }
284                 break;
285         case XFS_DINODE_FMT_BTREE:
286                 if ((iip->ili_fields & XFS_ILOG_ABROOT) &&
287                     ip->i_af.if_broot_bytes > 0) {
288                         *nbytes += ip->i_af.if_broot_bytes;
289                         *nvecs += 1;
290                 }
291                 break;
292         case XFS_DINODE_FMT_LOCAL:
293                 if ((iip->ili_fields & XFS_ILOG_ADATA) &&
294                     ip->i_af.if_bytes > 0) {
295                         *nbytes += xlog_calc_iovec_len(ip->i_af.if_bytes);
296                         *nvecs += 1;
297                 }
298                 break;
299         default:
300                 ASSERT(0);
301                 break;
302         }
303 }
304
305 /*
306  * This returns the number of iovecs needed to log the given inode item.
307  *
308  * We need one iovec for the inode log format structure, one for the
309  * inode core, and possibly one for the inode data/extents/b-tree root
310  * and one for the inode attribute data/extents/b-tree root.
311  */
312 STATIC void
313 xfs_inode_item_size(
314         struct xfs_log_item     *lip,
315         int                     *nvecs,
316         int                     *nbytes)
317 {
318         struct xfs_inode_log_item *iip = INODE_ITEM(lip);
319         struct xfs_inode        *ip = iip->ili_inode;
320
321         *nvecs += 2;
322         *nbytes += sizeof(struct xfs_inode_log_format) +
323                    xfs_log_dinode_size(ip->i_mount);
324
325         xfs_inode_item_data_fork_size(iip, nvecs, nbytes);
326         if (xfs_inode_has_attr_fork(ip))
327                 xfs_inode_item_attr_fork_size(iip, nvecs, nbytes);
328 }
329
330 STATIC void
331 xfs_inode_item_format_data_fork(
332         struct xfs_inode_log_item *iip,
333         struct xfs_inode_log_format *ilf,
334         struct xfs_log_vec      *lv,
335         struct xfs_log_iovec    **vecp)
336 {
337         struct xfs_inode        *ip = iip->ili_inode;
338         size_t                  data_bytes;
339
340         switch (ip->i_df.if_format) {
341         case XFS_DINODE_FMT_EXTENTS:
342                 iip->ili_fields &=
343                         ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT | XFS_ILOG_DEV);
344
345                 if ((iip->ili_fields & XFS_ILOG_DEXT) &&
346                     ip->i_df.if_nextents > 0 &&
347                     ip->i_df.if_bytes > 0) {
348                         struct xfs_bmbt_rec *p;
349
350                         ASSERT(xfs_iext_count(&ip->i_df) > 0);
351
352                         p = xlog_prepare_iovec(lv, vecp, XLOG_REG_TYPE_IEXT);
353                         data_bytes = xfs_iextents_copy(ip, p, XFS_DATA_FORK);
354                         xlog_finish_iovec(lv, *vecp, data_bytes);
355
356                         ASSERT(data_bytes <= ip->i_df.if_bytes);
357
358                         ilf->ilf_dsize = data_bytes;
359                         ilf->ilf_size++;
360                 } else {
361                         iip->ili_fields &= ~XFS_ILOG_DEXT;
362                 }
363                 break;
364         case XFS_DINODE_FMT_BTREE:
365                 iip->ili_fields &=
366                         ~(XFS_ILOG_DDATA | XFS_ILOG_DEXT | XFS_ILOG_DEV);
367
368                 if ((iip->ili_fields & XFS_ILOG_DBROOT) &&
369                     ip->i_df.if_broot_bytes > 0) {
370                         ASSERT(ip->i_df.if_broot != NULL);
371                         xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_IBROOT,
372                                         ip->i_df.if_broot,
373                                         ip->i_df.if_broot_bytes);
374                         ilf->ilf_dsize = ip->i_df.if_broot_bytes;
375                         ilf->ilf_size++;
376                 } else {
377                         ASSERT(!(iip->ili_fields &
378                                  XFS_ILOG_DBROOT));
379                         iip->ili_fields &= ~XFS_ILOG_DBROOT;
380                 }
381                 break;
382         case XFS_DINODE_FMT_LOCAL:
383                 iip->ili_fields &=
384                         ~(XFS_ILOG_DEXT | XFS_ILOG_DBROOT | XFS_ILOG_DEV);
385                 if ((iip->ili_fields & XFS_ILOG_DDATA) &&
386                     ip->i_df.if_bytes > 0) {
387                         ASSERT(ip->i_df.if_data != NULL);
388                         ASSERT(ip->i_disk_size > 0);
389                         xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_ILOCAL,
390                                         ip->i_df.if_data, ip->i_df.if_bytes);
391                         ilf->ilf_dsize = (unsigned)ip->i_df.if_bytes;
392                         ilf->ilf_size++;
393                 } else {
394                         iip->ili_fields &= ~XFS_ILOG_DDATA;
395                 }
396                 break;
397         case XFS_DINODE_FMT_DEV:
398                 iip->ili_fields &=
399                         ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT | XFS_ILOG_DEXT);
400                 if (iip->ili_fields & XFS_ILOG_DEV)
401                         ilf->ilf_u.ilfu_rdev = sysv_encode_dev(VFS_I(ip)->i_rdev);
402                 break;
403         default:
404                 ASSERT(0);
405                 break;
406         }
407 }
408
409 STATIC void
410 xfs_inode_item_format_attr_fork(
411         struct xfs_inode_log_item *iip,
412         struct xfs_inode_log_format *ilf,
413         struct xfs_log_vec      *lv,
414         struct xfs_log_iovec    **vecp)
415 {
416         struct xfs_inode        *ip = iip->ili_inode;
417         size_t                  data_bytes;
418
419         switch (ip->i_af.if_format) {
420         case XFS_DINODE_FMT_EXTENTS:
421                 iip->ili_fields &=
422                         ~(XFS_ILOG_ADATA | XFS_ILOG_ABROOT);
423
424                 if ((iip->ili_fields & XFS_ILOG_AEXT) &&
425                     ip->i_af.if_nextents > 0 &&
426                     ip->i_af.if_bytes > 0) {
427                         struct xfs_bmbt_rec *p;
428
429                         ASSERT(xfs_iext_count(&ip->i_af) ==
430                                 ip->i_af.if_nextents);
431
432                         p = xlog_prepare_iovec(lv, vecp, XLOG_REG_TYPE_IATTR_EXT);
433                         data_bytes = xfs_iextents_copy(ip, p, XFS_ATTR_FORK);
434                         xlog_finish_iovec(lv, *vecp, data_bytes);
435
436                         ilf->ilf_asize = data_bytes;
437                         ilf->ilf_size++;
438                 } else {
439                         iip->ili_fields &= ~XFS_ILOG_AEXT;
440                 }
441                 break;
442         case XFS_DINODE_FMT_BTREE:
443                 iip->ili_fields &=
444                         ~(XFS_ILOG_ADATA | XFS_ILOG_AEXT);
445
446                 if ((iip->ili_fields & XFS_ILOG_ABROOT) &&
447                     ip->i_af.if_broot_bytes > 0) {
448                         ASSERT(ip->i_af.if_broot != NULL);
449
450                         xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_IATTR_BROOT,
451                                         ip->i_af.if_broot,
452                                         ip->i_af.if_broot_bytes);
453                         ilf->ilf_asize = ip->i_af.if_broot_bytes;
454                         ilf->ilf_size++;
455                 } else {
456                         iip->ili_fields &= ~XFS_ILOG_ABROOT;
457                 }
458                 break;
459         case XFS_DINODE_FMT_LOCAL:
460                 iip->ili_fields &=
461                         ~(XFS_ILOG_AEXT | XFS_ILOG_ABROOT);
462
463                 if ((iip->ili_fields & XFS_ILOG_ADATA) &&
464                     ip->i_af.if_bytes > 0) {
465                         ASSERT(ip->i_af.if_data != NULL);
466                         xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_IATTR_LOCAL,
467                                         ip->i_af.if_data, ip->i_af.if_bytes);
468                         ilf->ilf_asize = (unsigned)ip->i_af.if_bytes;
469                         ilf->ilf_size++;
470                 } else {
471                         iip->ili_fields &= ~XFS_ILOG_ADATA;
472                 }
473                 break;
474         default:
475                 ASSERT(0);
476                 break;
477         }
478 }
479
480 /*
481  * Convert an incore timestamp to a log timestamp.  Note that the log format
482  * specifies host endian format!
483  */
484 static inline xfs_log_timestamp_t
485 xfs_inode_to_log_dinode_ts(
486         struct xfs_inode                *ip,
487         const struct timespec64         tv)
488 {
489         struct xfs_log_legacy_timestamp *lits;
490         xfs_log_timestamp_t             its;
491
492         if (xfs_inode_has_bigtime(ip))
493                 return xfs_inode_encode_bigtime(tv);
494
495         lits = (struct xfs_log_legacy_timestamp *)&its;
496         lits->t_sec = tv.tv_sec;
497         lits->t_nsec = tv.tv_nsec;
498
499         return its;
500 }
501
502 /*
503  * The legacy DMAPI fields are only present in the on-disk and in-log inodes,
504  * but not in the in-memory one.  But we are guaranteed to have an inode buffer
505  * in memory when logging an inode, so we can just copy it from the on-disk
506  * inode to the in-log inode here so that recovery of file system with these
507  * fields set to non-zero values doesn't lose them.  For all other cases we zero
508  * the fields.
509  */
510 static void
511 xfs_copy_dm_fields_to_log_dinode(
512         struct xfs_inode        *ip,
513         struct xfs_log_dinode   *to)
514 {
515         struct xfs_dinode       *dip;
516
517         dip = xfs_buf_offset(ip->i_itemp->ili_item.li_buf,
518                              ip->i_imap.im_boffset);
519
520         if (xfs_iflags_test(ip, XFS_IPRESERVE_DM_FIELDS)) {
521                 to->di_dmevmask = be32_to_cpu(dip->di_dmevmask);
522                 to->di_dmstate = be16_to_cpu(dip->di_dmstate);
523         } else {
524                 to->di_dmevmask = 0;
525                 to->di_dmstate = 0;
526         }
527 }
528
529 static inline void
530 xfs_inode_to_log_dinode_iext_counters(
531         struct xfs_inode        *ip,
532         struct xfs_log_dinode   *to)
533 {
534         if (xfs_inode_has_large_extent_counts(ip)) {
535                 to->di_big_nextents = xfs_ifork_nextents(&ip->i_df);
536                 to->di_big_anextents = xfs_ifork_nextents(&ip->i_af);
537                 to->di_nrext64_pad = 0;
538         } else {
539                 to->di_nextents = xfs_ifork_nextents(&ip->i_df);
540                 to->di_anextents = xfs_ifork_nextents(&ip->i_af);
541         }
542 }
543
544 static void
545 xfs_inode_to_log_dinode(
546         struct xfs_inode        *ip,
547         struct xfs_log_dinode   *to,
548         xfs_lsn_t               lsn)
549 {
550         struct inode            *inode = VFS_I(ip);
551
552         to->di_magic = XFS_DINODE_MAGIC;
553         to->di_format = xfs_ifork_format(&ip->i_df);
554         to->di_uid = i_uid_read(inode);
555         to->di_gid = i_gid_read(inode);
556         to->di_projid_lo = ip->i_projid & 0xffff;
557         to->di_projid_hi = ip->i_projid >> 16;
558
559         to->di_atime = xfs_inode_to_log_dinode_ts(ip, inode_get_atime(inode));
560         to->di_mtime = xfs_inode_to_log_dinode_ts(ip, inode_get_mtime(inode));
561         to->di_ctime = xfs_inode_to_log_dinode_ts(ip, inode_get_ctime(inode));
562         to->di_nlink = inode->i_nlink;
563         to->di_gen = inode->i_generation;
564         to->di_mode = inode->i_mode;
565
566         to->di_size = ip->i_disk_size;
567         to->di_nblocks = ip->i_nblocks;
568         to->di_extsize = ip->i_extsize;
569         to->di_forkoff = ip->i_forkoff;
570         to->di_aformat = xfs_ifork_format(&ip->i_af);
571         to->di_flags = ip->i_diflags;
572
573         xfs_copy_dm_fields_to_log_dinode(ip, to);
574
575         /* log a dummy value to ensure log structure is fully initialised */
576         to->di_next_unlinked = NULLAGINO;
577
578         if (xfs_has_v3inodes(ip->i_mount)) {
579                 to->di_version = 3;
580                 to->di_changecount = inode_peek_iversion(inode);
581                 to->di_crtime = xfs_inode_to_log_dinode_ts(ip, ip->i_crtime);
582                 to->di_flags2 = ip->i_diflags2;
583                 to->di_cowextsize = ip->i_cowextsize;
584                 to->di_ino = ip->i_ino;
585                 to->di_lsn = lsn;
586                 memset(to->di_pad2, 0, sizeof(to->di_pad2));
587                 uuid_copy(&to->di_uuid, &ip->i_mount->m_sb.sb_meta_uuid);
588                 to->di_v3_pad = 0;
589
590                 /* dummy value for initialisation */
591                 to->di_crc = 0;
592
593                 if (xfs_is_metadir_inode(ip))
594                         to->di_metatype = ip->i_metatype;
595                 else
596                         to->di_metatype = 0;
597         } else {
598                 to->di_version = 2;
599                 to->di_flushiter = ip->i_flushiter;
600                 memset(to->di_v2_pad, 0, sizeof(to->di_v2_pad));
601                 to->di_metatype = 0;
602         }
603
604         xfs_inode_to_log_dinode_iext_counters(ip, to);
605 }
606
607 /*
608  * Format the inode core. Current timestamp data is only in the VFS inode
609  * fields, so we need to grab them from there. Hence rather than just copying
610  * the XFS inode core structure, format the fields directly into the iovec.
611  */
612 static void
613 xfs_inode_item_format_core(
614         struct xfs_inode        *ip,
615         struct xfs_log_vec      *lv,
616         struct xfs_log_iovec    **vecp)
617 {
618         struct xfs_log_dinode   *dic;
619
620         dic = xlog_prepare_iovec(lv, vecp, XLOG_REG_TYPE_ICORE);
621         xfs_inode_to_log_dinode(ip, dic, ip->i_itemp->ili_item.li_lsn);
622         xlog_finish_iovec(lv, *vecp, xfs_log_dinode_size(ip->i_mount));
623 }
624
625 /*
626  * This is called to fill in the vector of log iovecs for the given inode
627  * log item.  It fills the first item with an inode log format structure,
628  * the second with the on-disk inode structure, and a possible third and/or
629  * fourth with the inode data/extents/b-tree root and inode attributes
630  * data/extents/b-tree root.
631  *
632  * Note: Always use the 64 bit inode log format structure so we don't
633  * leave an uninitialised hole in the format item on 64 bit systems. Log
634  * recovery on 32 bit systems handles this just fine, so there's no reason
635  * for not using an initialising the properly padded structure all the time.
636  */
637 STATIC void
638 xfs_inode_item_format(
639         struct xfs_log_item     *lip,
640         struct xfs_log_vec      *lv)
641 {
642         struct xfs_inode_log_item *iip = INODE_ITEM(lip);
643         struct xfs_inode        *ip = iip->ili_inode;
644         struct xfs_log_iovec    *vecp = NULL;
645         struct xfs_inode_log_format *ilf;
646
647         ilf = xlog_prepare_iovec(lv, &vecp, XLOG_REG_TYPE_IFORMAT);
648         ilf->ilf_type = XFS_LI_INODE;
649         ilf->ilf_ino = ip->i_ino;
650         ilf->ilf_blkno = ip->i_imap.im_blkno;
651         ilf->ilf_len = ip->i_imap.im_len;
652         ilf->ilf_boffset = ip->i_imap.im_boffset;
653         ilf->ilf_fields = XFS_ILOG_CORE;
654         ilf->ilf_size = 2; /* format + core */
655
656         /*
657          * make sure we don't leak uninitialised data into the log in the case
658          * when we don't log every field in the inode.
659          */
660         ilf->ilf_dsize = 0;
661         ilf->ilf_asize = 0;
662         ilf->ilf_pad = 0;
663         memset(&ilf->ilf_u, 0, sizeof(ilf->ilf_u));
664
665         xlog_finish_iovec(lv, vecp, sizeof(*ilf));
666
667         xfs_inode_item_format_core(ip, lv, &vecp);
668         xfs_inode_item_format_data_fork(iip, ilf, lv, &vecp);
669         if (xfs_inode_has_attr_fork(ip)) {
670                 xfs_inode_item_format_attr_fork(iip, ilf, lv, &vecp);
671         } else {
672                 iip->ili_fields &=
673                         ~(XFS_ILOG_ADATA | XFS_ILOG_ABROOT | XFS_ILOG_AEXT);
674         }
675
676         /* update the format with the exact fields we actually logged */
677         ilf->ilf_fields |= (iip->ili_fields & ~XFS_ILOG_TIMESTAMP);
678 }
679
680 /*
681  * This is called to pin the inode associated with the inode log
682  * item in memory so it cannot be written out.
683  */
684 STATIC void
685 xfs_inode_item_pin(
686         struct xfs_log_item     *lip)
687 {
688         struct xfs_inode        *ip = INODE_ITEM(lip)->ili_inode;
689
690         xfs_assert_ilocked(ip, XFS_ILOCK_EXCL);
691         ASSERT(lip->li_buf);
692
693         trace_xfs_inode_pin(ip, _RET_IP_);
694         atomic_inc(&ip->i_pincount);
695 }
696
697
698 /*
699  * This is called to unpin the inode associated with the inode log
700  * item which was previously pinned with a call to xfs_inode_item_pin().
701  *
702  * Also wake up anyone in xfs_iunpin_wait() if the count goes to 0.
703  *
704  * Note that unpin can race with inode cluster buffer freeing marking the buffer
705  * stale. In that case, flush completions are run from the buffer unpin call,
706  * which may happen before the inode is unpinned. If we lose the race, there
707  * will be no buffer attached to the log item, but the inode will be marked
708  * XFS_ISTALE.
709  */
710 STATIC void
711 xfs_inode_item_unpin(
712         struct xfs_log_item     *lip,
713         int                     remove)
714 {
715         struct xfs_inode        *ip = INODE_ITEM(lip)->ili_inode;
716
717         trace_xfs_inode_unpin(ip, _RET_IP_);
718         ASSERT(lip->li_buf || xfs_iflags_test(ip, XFS_ISTALE));
719         ASSERT(atomic_read(&ip->i_pincount) > 0);
720         if (atomic_dec_and_test(&ip->i_pincount))
721                 wake_up_bit(&ip->i_flags, __XFS_IPINNED_BIT);
722 }
723
724 STATIC uint
725 xfs_inode_item_push(
726         struct xfs_log_item     *lip,
727         struct list_head        *buffer_list)
728                 __releases(&lip->li_ailp->ail_lock)
729                 __acquires(&lip->li_ailp->ail_lock)
730 {
731         struct xfs_inode_log_item *iip = INODE_ITEM(lip);
732         struct xfs_inode        *ip = iip->ili_inode;
733         struct xfs_buf          *bp = lip->li_buf;
734         uint                    rval = XFS_ITEM_SUCCESS;
735         int                     error;
736
737         if (!bp || (ip->i_flags & XFS_ISTALE)) {
738                 /*
739                  * Inode item/buffer is being aborted due to cluster
740                  * buffer deletion. Trigger a log force to have that operation
741                  * completed and items removed from the AIL before the next push
742                  * attempt.
743                  */
744                 return XFS_ITEM_PINNED;
745         }
746
747         if (xfs_ipincount(ip) > 0 || xfs_buf_ispinned(bp))
748                 return XFS_ITEM_PINNED;
749
750         if (xfs_iflags_test(ip, XFS_IFLUSHING))
751                 return XFS_ITEM_FLUSHING;
752
753         if (!xfs_buf_trylock(bp))
754                 return XFS_ITEM_LOCKED;
755
756         spin_unlock(&lip->li_ailp->ail_lock);
757
758         /*
759          * We need to hold a reference for flushing the cluster buffer as it may
760          * fail the buffer without IO submission. In which case, we better get a
761          * reference for that completion because otherwise we don't get a
762          * reference for IO until we queue the buffer for delwri submission.
763          */
764         xfs_buf_hold(bp);
765         error = xfs_iflush_cluster(bp);
766         if (!error) {
767                 if (!xfs_buf_delwri_queue(bp, buffer_list))
768                         rval = XFS_ITEM_FLUSHING;
769                 xfs_buf_relse(bp);
770         } else {
771                 /*
772                  * Release the buffer if we were unable to flush anything. On
773                  * any other error, the buffer has already been released.
774                  */
775                 if (error == -EAGAIN)
776                         xfs_buf_relse(bp);
777                 rval = XFS_ITEM_LOCKED;
778         }
779
780         spin_lock(&lip->li_ailp->ail_lock);
781         return rval;
782 }
783
784 /*
785  * Unlock the inode associated with the inode log item.
786  */
787 STATIC void
788 xfs_inode_item_release(
789         struct xfs_log_item     *lip)
790 {
791         struct xfs_inode_log_item *iip = INODE_ITEM(lip);
792         struct xfs_inode        *ip = iip->ili_inode;
793         unsigned short          lock_flags;
794
795         ASSERT(ip->i_itemp != NULL);
796         xfs_assert_ilocked(ip, XFS_ILOCK_EXCL);
797
798         lock_flags = iip->ili_lock_flags;
799         iip->ili_lock_flags = 0;
800         if (lock_flags)
801                 xfs_iunlock(ip, lock_flags);
802 }
803
804 /*
805  * This is called to find out where the oldest active copy of the inode log
806  * item in the on disk log resides now that the last log write of it completed
807  * at the given lsn.  Since we always re-log all dirty data in an inode, the
808  * latest copy in the on disk log is the only one that matters.  Therefore,
809  * simply return the given lsn.
810  *
811  * If the inode has been marked stale because the cluster is being freed, we
812  * don't want to (re-)insert this inode into the AIL. There is a race condition
813  * where the cluster buffer may be unpinned before the inode is inserted into
814  * the AIL during transaction committed processing. If the buffer is unpinned
815  * before the inode item has been committed and inserted, then it is possible
816  * for the buffer to be written and IO completes before the inode is inserted
817  * into the AIL. In that case, we'd be inserting a clean, stale inode into the
818  * AIL which will never get removed. It will, however, get reclaimed which
819  * triggers an assert in xfs_inode_free() complaining about freein an inode
820  * still in the AIL.
821  *
822  * To avoid this, just unpin the inode directly and return a LSN of -1 so the
823  * transaction committed code knows that it does not need to do any further
824  * processing on the item.
825  */
826 STATIC xfs_lsn_t
827 xfs_inode_item_committed(
828         struct xfs_log_item     *lip,
829         xfs_lsn_t               lsn)
830 {
831         struct xfs_inode_log_item *iip = INODE_ITEM(lip);
832         struct xfs_inode        *ip = iip->ili_inode;
833
834         if (xfs_iflags_test(ip, XFS_ISTALE)) {
835                 xfs_inode_item_unpin(lip, 0);
836                 return -1;
837         }
838         return lsn;
839 }
840
841 STATIC void
842 xfs_inode_item_committing(
843         struct xfs_log_item     *lip,
844         xfs_csn_t               seq)
845 {
846         INODE_ITEM(lip)->ili_commit_seq = seq;
847         return xfs_inode_item_release(lip);
848 }
849
850 static const struct xfs_item_ops xfs_inode_item_ops = {
851         .iop_sort       = xfs_inode_item_sort,
852         .iop_precommit  = xfs_inode_item_precommit,
853         .iop_size       = xfs_inode_item_size,
854         .iop_format     = xfs_inode_item_format,
855         .iop_pin        = xfs_inode_item_pin,
856         .iop_unpin      = xfs_inode_item_unpin,
857         .iop_release    = xfs_inode_item_release,
858         .iop_committed  = xfs_inode_item_committed,
859         .iop_push       = xfs_inode_item_push,
860         .iop_committing = xfs_inode_item_committing,
861 };
862
863
864 /*
865  * Initialize the inode log item for a newly allocated (in-core) inode.
866  */
867 void
868 xfs_inode_item_init(
869         struct xfs_inode        *ip,
870         struct xfs_mount        *mp)
871 {
872         struct xfs_inode_log_item *iip;
873
874         ASSERT(ip->i_itemp == NULL);
875         iip = ip->i_itemp = kmem_cache_zalloc(xfs_ili_cache,
876                                               GFP_KERNEL | __GFP_NOFAIL);
877
878         iip->ili_inode = ip;
879         spin_lock_init(&iip->ili_lock);
880         xfs_log_item_init(mp, &iip->ili_item, XFS_LI_INODE,
881                                                 &xfs_inode_item_ops);
882 }
883
884 /*
885  * Free the inode log item and any memory hanging off of it.
886  */
887 void
888 xfs_inode_item_destroy(
889         struct xfs_inode        *ip)
890 {
891         struct xfs_inode_log_item *iip = ip->i_itemp;
892
893         ASSERT(iip->ili_item.li_buf == NULL);
894
895         ip->i_itemp = NULL;
896         kvfree(iip->ili_item.li_lv_shadow);
897         kmem_cache_free(xfs_ili_cache, iip);
898 }
899
900
901 /*
902  * We only want to pull the item from the AIL if it is actually there
903  * and its location in the log has not changed since we started the
904  * flush.  Thus, we only bother if the inode's lsn has not changed.
905  */
906 static void
907 xfs_iflush_ail_updates(
908         struct xfs_ail          *ailp,
909         struct list_head        *list)
910 {
911         struct xfs_log_item     *lip;
912         xfs_lsn_t               tail_lsn = 0;
913
914         /* this is an opencoded batch version of xfs_trans_ail_delete */
915         spin_lock(&ailp->ail_lock);
916         list_for_each_entry(lip, list, li_bio_list) {
917                 xfs_lsn_t       lsn;
918
919                 clear_bit(XFS_LI_FAILED, &lip->li_flags);
920                 if (INODE_ITEM(lip)->ili_flush_lsn != lip->li_lsn)
921                         continue;
922
923                 /*
924                  * dgc: Not sure how this happens, but it happens very
925                  * occassionaly via generic/388.  xfs_iflush_abort() also
926                  * silently handles this same "under writeback but not in AIL at
927                  * shutdown" condition via xfs_trans_ail_delete().
928                  */
929                 if (!test_bit(XFS_LI_IN_AIL, &lip->li_flags)) {
930                         ASSERT(xlog_is_shutdown(lip->li_log));
931                         continue;
932                 }
933
934                 lsn = xfs_ail_delete_one(ailp, lip);
935                 if (!tail_lsn && lsn)
936                         tail_lsn = lsn;
937         }
938         xfs_ail_update_finish(ailp, tail_lsn);
939 }
940
941 /*
942  * Walk the list of inodes that have completed their IOs. If they are clean
943  * remove them from the list and dissociate them from the buffer. Buffers that
944  * are still dirty remain linked to the buffer and on the list. Caller must
945  * handle them appropriately.
946  */
947 static void
948 xfs_iflush_finish(
949         struct xfs_buf          *bp,
950         struct list_head        *list)
951 {
952         struct xfs_log_item     *lip, *n;
953
954         list_for_each_entry_safe(lip, n, list, li_bio_list) {
955                 struct xfs_inode_log_item *iip = INODE_ITEM(lip);
956                 bool    drop_buffer = false;
957
958                 spin_lock(&iip->ili_lock);
959
960                 /*
961                  * Remove the reference to the cluster buffer if the inode is
962                  * clean in memory and drop the buffer reference once we've
963                  * dropped the locks we hold.
964                  */
965                 ASSERT(iip->ili_item.li_buf == bp);
966                 if (!iip->ili_fields) {
967                         iip->ili_item.li_buf = NULL;
968                         list_del_init(&lip->li_bio_list);
969                         drop_buffer = true;
970                 }
971                 iip->ili_last_fields = 0;
972                 iip->ili_flush_lsn = 0;
973                 clear_bit(XFS_LI_FLUSHING, &lip->li_flags);
974                 spin_unlock(&iip->ili_lock);
975                 xfs_iflags_clear(iip->ili_inode, XFS_IFLUSHING);
976                 if (drop_buffer)
977                         xfs_buf_rele(bp);
978         }
979 }
980
981 /*
982  * Inode buffer IO completion routine.  It is responsible for removing inodes
983  * attached to the buffer from the AIL if they have not been re-logged and
984  * completing the inode flush.
985  */
986 void
987 xfs_buf_inode_iodone(
988         struct xfs_buf          *bp)
989 {
990         struct xfs_log_item     *lip, *n;
991         LIST_HEAD(flushed_inodes);
992         LIST_HEAD(ail_updates);
993
994         /*
995          * Pull the attached inodes from the buffer one at a time and take the
996          * appropriate action on them.
997          */
998         list_for_each_entry_safe(lip, n, &bp->b_li_list, li_bio_list) {
999                 struct xfs_inode_log_item *iip = INODE_ITEM(lip);
1000
1001                 if (xfs_iflags_test(iip->ili_inode, XFS_ISTALE)) {
1002                         xfs_iflush_abort(iip->ili_inode);
1003                         continue;
1004                 }
1005                 if (!iip->ili_last_fields)
1006                         continue;
1007
1008                 /* Do an unlocked check for needing the AIL lock. */
1009                 if (iip->ili_flush_lsn == lip->li_lsn ||
1010                     test_bit(XFS_LI_FAILED, &lip->li_flags))
1011                         list_move_tail(&lip->li_bio_list, &ail_updates);
1012                 else
1013                         list_move_tail(&lip->li_bio_list, &flushed_inodes);
1014         }
1015
1016         if (!list_empty(&ail_updates)) {
1017                 xfs_iflush_ail_updates(bp->b_mount->m_ail, &ail_updates);
1018                 list_splice_tail(&ail_updates, &flushed_inodes);
1019         }
1020
1021         xfs_iflush_finish(bp, &flushed_inodes);
1022         if (!list_empty(&flushed_inodes))
1023                 list_splice_tail(&flushed_inodes, &bp->b_li_list);
1024 }
1025
1026 void
1027 xfs_buf_inode_io_fail(
1028         struct xfs_buf          *bp)
1029 {
1030         struct xfs_log_item     *lip;
1031
1032         list_for_each_entry(lip, &bp->b_li_list, li_bio_list) {
1033                 set_bit(XFS_LI_FAILED, &lip->li_flags);
1034                 clear_bit(XFS_LI_FLUSHING, &lip->li_flags);
1035         }
1036 }
1037
1038 /*
1039  * Clear the inode logging fields so no more flushes are attempted.  If we are
1040  * on a buffer list, it is now safe to remove it because the buffer is
1041  * guaranteed to be locked. The caller will drop the reference to the buffer
1042  * the log item held.
1043  */
1044 static void
1045 xfs_iflush_abort_clean(
1046         struct xfs_inode_log_item *iip)
1047 {
1048         iip->ili_last_fields = 0;
1049         iip->ili_fields = 0;
1050         iip->ili_fsync_fields = 0;
1051         iip->ili_flush_lsn = 0;
1052         iip->ili_item.li_buf = NULL;
1053         list_del_init(&iip->ili_item.li_bio_list);
1054         clear_bit(XFS_LI_FLUSHING, &iip->ili_item.li_flags);
1055 }
1056
1057 /*
1058  * Abort flushing the inode from a context holding the cluster buffer locked.
1059  *
1060  * This is the normal runtime method of aborting writeback of an inode that is
1061  * attached to a cluster buffer. It occurs when the inode and the backing
1062  * cluster buffer have been freed (i.e. inode is XFS_ISTALE), or when cluster
1063  * flushing or buffer IO completion encounters a log shutdown situation.
1064  *
1065  * If we need to abort inode writeback and we don't already hold the buffer
1066  * locked, call xfs_iflush_shutdown_abort() instead as this should only ever be
1067  * necessary in a shutdown situation.
1068  */
1069 void
1070 xfs_iflush_abort(
1071         struct xfs_inode        *ip)
1072 {
1073         struct xfs_inode_log_item *iip = ip->i_itemp;
1074         struct xfs_buf          *bp;
1075
1076         if (!iip) {
1077                 /* clean inode, nothing to do */
1078                 xfs_iflags_clear(ip, XFS_IFLUSHING);
1079                 return;
1080         }
1081
1082         /*
1083          * Remove the inode item from the AIL before we clear its internal
1084          * state. Whilst the inode is in the AIL, it should have a valid buffer
1085          * pointer for push operations to access - it is only safe to remove the
1086          * inode from the buffer once it has been removed from the AIL.
1087          *
1088          * We also clear the failed bit before removing the item from the AIL
1089          * as xfs_trans_ail_delete()->xfs_clear_li_failed() will release buffer
1090          * references the inode item owns and needs to hold until we've fully
1091          * aborted the inode log item and detached it from the buffer.
1092          */
1093         clear_bit(XFS_LI_FAILED, &iip->ili_item.li_flags);
1094         xfs_trans_ail_delete(&iip->ili_item, 0);
1095
1096         /*
1097          * Grab the inode buffer so can we release the reference the inode log
1098          * item holds on it.
1099          */
1100         spin_lock(&iip->ili_lock);
1101         bp = iip->ili_item.li_buf;
1102         xfs_iflush_abort_clean(iip);
1103         spin_unlock(&iip->ili_lock);
1104
1105         xfs_iflags_clear(ip, XFS_IFLUSHING);
1106         if (bp)
1107                 xfs_buf_rele(bp);
1108 }
1109
1110 /*
1111  * Abort an inode flush in the case of a shutdown filesystem. This can be called
1112  * from anywhere with just an inode reference and does not require holding the
1113  * inode cluster buffer locked. If the inode is attached to a cluster buffer,
1114  * it will grab and lock it safely, then abort the inode flush.
1115  */
1116 void
1117 xfs_iflush_shutdown_abort(
1118         struct xfs_inode        *ip)
1119 {
1120         struct xfs_inode_log_item *iip = ip->i_itemp;
1121         struct xfs_buf          *bp;
1122
1123         if (!iip) {
1124                 /* clean inode, nothing to do */
1125                 xfs_iflags_clear(ip, XFS_IFLUSHING);
1126                 return;
1127         }
1128
1129         spin_lock(&iip->ili_lock);
1130         bp = iip->ili_item.li_buf;
1131         if (!bp) {
1132                 spin_unlock(&iip->ili_lock);
1133                 xfs_iflush_abort(ip);
1134                 return;
1135         }
1136
1137         /*
1138          * We have to take a reference to the buffer so that it doesn't get
1139          * freed when we drop the ili_lock and then wait to lock the buffer.
1140          * We'll clean up the extra reference after we pick up the ili_lock
1141          * again.
1142          */
1143         xfs_buf_hold(bp);
1144         spin_unlock(&iip->ili_lock);
1145         xfs_buf_lock(bp);
1146
1147         spin_lock(&iip->ili_lock);
1148         if (!iip->ili_item.li_buf) {
1149                 /*
1150                  * Raced with another removal, hold the only reference
1151                  * to bp now. Inode should not be in the AIL now, so just clean
1152                  * up and return;
1153                  */
1154                 ASSERT(list_empty(&iip->ili_item.li_bio_list));
1155                 ASSERT(!test_bit(XFS_LI_IN_AIL, &iip->ili_item.li_flags));
1156                 xfs_iflush_abort_clean(iip);
1157                 spin_unlock(&iip->ili_lock);
1158                 xfs_iflags_clear(ip, XFS_IFLUSHING);
1159                 xfs_buf_relse(bp);
1160                 return;
1161         }
1162
1163         /*
1164          * Got two references to bp. The first will get dropped by
1165          * xfs_iflush_abort() when the item is removed from the buffer list, but
1166          * we can't drop our reference until _abort() returns because we have to
1167          * unlock the buffer as well. Hence we abort and then unlock and release
1168          * our reference to the buffer.
1169          */
1170         ASSERT(iip->ili_item.li_buf == bp);
1171         spin_unlock(&iip->ili_lock);
1172         xfs_iflush_abort(ip);
1173         xfs_buf_relse(bp);
1174 }
1175
1176
1177 /*
1178  * convert an xfs_inode_log_format struct from the old 32 bit version
1179  * (which can have different field alignments) to the native 64 bit version
1180  */
1181 int
1182 xfs_inode_item_format_convert(
1183         struct xfs_log_iovec            *buf,
1184         struct xfs_inode_log_format     *in_f)
1185 {
1186         struct xfs_inode_log_format_32  *in_f32 = buf->i_addr;
1187
1188         if (buf->i_len != sizeof(*in_f32)) {
1189                 XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, NULL);
1190                 return -EFSCORRUPTED;
1191         }
1192
1193         in_f->ilf_type = in_f32->ilf_type;
1194         in_f->ilf_size = in_f32->ilf_size;
1195         in_f->ilf_fields = in_f32->ilf_fields;
1196         in_f->ilf_asize = in_f32->ilf_asize;
1197         in_f->ilf_dsize = in_f32->ilf_dsize;
1198         in_f->ilf_ino = in_f32->ilf_ino;
1199         memcpy(&in_f->ilf_u, &in_f32->ilf_u, sizeof(in_f->ilf_u));
1200         in_f->ilf_blkno = in_f32->ilf_blkno;
1201         in_f->ilf_len = in_f32->ilf_len;
1202         in_f->ilf_boffset = in_f32->ilf_boffset;
1203         return 0;
1204 }
This page took 0.094026 seconds and 4 git commands to generate.