~ubuntu-branches/ubuntu/utopic/xfsprogs/utopic-proposed

« back to all changes in this revision

Viewing changes to libxfs/xfs_mount.c

  • Committer: Bazaar Package Importer
  • Author(s): Nathan Scott
  • Date: 2009-05-06 11:29:18 UTC
  • mfrom: (8.1.1 jaunty)
  • Revision ID: james.westby@ubuntu.com-20090506112918-uzoyzcp90rtr8td7
Tags: 3.0.2
New bugfix release

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
 
2
 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
3
3
 * All Rights Reserved.
4
4
 *
5
5
 * This program is free software; you can redistribute it and/or
18
18
 
19
19
#include <xfs.h>
20
20
 
21
 
/*
22
 
 * Mount initialization code establishing various mount
23
 
 * fields from the superblock associated with the given
24
 
 * mount structure.
25
 
 */
26
 
void
27
 
xfs_mount_common(xfs_mount_t *mp, xfs_sb_t *sbp)
28
 
{
29
 
        int     i;
30
 
 
31
 
        mp->m_agfrotor = mp->m_agirotor = 0;
32
 
        spinlock_init(&mp->m_agirotor_lock, "m_agirotor_lock");
33
 
        mp->m_maxagi = mp->m_sb.sb_agcount;
34
 
        mp->m_blkbit_log = sbp->sb_blocklog + XFS_NBBYLOG;
35
 
        mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT;
36
 
        mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT;
37
 
        mp->m_agno_log = xfs_highbit32(sbp->sb_agcount - 1) + 1;
38
 
        mp->m_agino_log = sbp->sb_inopblog + sbp->sb_agblklog;
39
 
        mp->m_litino = sbp->sb_inodesize -
40
 
                ((uint)sizeof(xfs_dinode_core_t) + (uint)sizeof(xfs_agino_t));
41
 
        mp->m_blockmask = sbp->sb_blocksize - 1;
42
 
        mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG;
43
 
        mp->m_blockwmask = mp->m_blockwsize - 1;
44
 
        INIT_LIST_HEAD(&mp->m_del_inodes);
45
 
 
46
 
        /*
47
 
         * Setup for attributes, in case they get created.
48
 
         * This value is for inodes getting attributes for the first time,
49
 
         * the per-inode value is for old attribute values.
50
 
         */
51
 
        ASSERT(sbp->sb_inodesize >= 256 && sbp->sb_inodesize <= 2048);
52
 
        switch (sbp->sb_inodesize) {
53
 
        case 256:
54
 
                mp->m_attroffset = XFS_LITINO(mp) -
55
 
                                   XFS_BMDR_SPACE_CALC(MINABTPTRS);
56
 
                break;
57
 
        case 512:
58
 
        case 1024:
59
 
        case 2048:
60
 
                mp->m_attroffset = XFS_BMDR_SPACE_CALC(6 * MINABTPTRS);
61
 
                break;
62
 
        default:
63
 
                ASSERT(0);
64
 
        }
65
 
        ASSERT(mp->m_attroffset < XFS_LITINO(mp));
66
 
 
67
 
        for (i = 0; i < 2; i++) {
68
 
                mp->m_alloc_mxr[i] = XFS_BTREE_BLOCK_MAXRECS(sbp->sb_blocksize,
69
 
                        xfs_alloc, i == 0);
70
 
                mp->m_alloc_mnr[i] = XFS_BTREE_BLOCK_MINRECS(sbp->sb_blocksize,
71
 
                        xfs_alloc, i == 0);
72
 
        }
73
 
        for (i = 0; i < 2; i++) {
74
 
                mp->m_bmap_dmxr[i] = XFS_BTREE_BLOCK_MAXRECS(sbp->sb_blocksize,
75
 
                        xfs_bmbt, i == 0);
76
 
                mp->m_bmap_dmnr[i] = XFS_BTREE_BLOCK_MINRECS(sbp->sb_blocksize,
77
 
                        xfs_bmbt, i == 0);
78
 
        }
79
 
        for (i = 0; i < 2; i++) {
80
 
                mp->m_inobt_mxr[i] = XFS_BTREE_BLOCK_MAXRECS(sbp->sb_blocksize,
81
 
                        xfs_inobt, i == 0);
82
 
                mp->m_inobt_mnr[i] = XFS_BTREE_BLOCK_MINRECS(sbp->sb_blocksize,
83
 
                        xfs_inobt, i == 0);
84
 
        }
85
 
 
86
 
        mp->m_bsize = XFS_FSB_TO_BB(mp, 1);
87
 
        mp->m_ialloc_inos = (int)MAX((__uint16_t)XFS_INODES_PER_CHUNK,
88
 
                                        sbp->sb_inopblock);
89
 
        mp->m_ialloc_blks = mp->m_ialloc_inos >> sbp->sb_inopblog;
90
 
}
91
 
 
92
 
static struct {
93
 
    short offset;
94
 
    short type;     /* 0 = integer
95
 
                     * 1 = binary / string (no translation)
96
 
                     */
 
21
static const struct {
 
22
        short offset;
 
23
        short type;     /* 0 = integer
 
24
                         * 1 = binary / string (no translation)
 
25
                         */
97
26
} xfs_sb_info[] = {
98
 
    { offsetof(xfs_sb_t, sb_magicnum),   0 },
99
 
    { offsetof(xfs_sb_t, sb_blocksize),  0 },
100
 
    { offsetof(xfs_sb_t, sb_dblocks),    0 },
101
 
    { offsetof(xfs_sb_t, sb_rblocks),    0 },
102
 
    { offsetof(xfs_sb_t, sb_rextents),   0 },
103
 
    { offsetof(xfs_sb_t, sb_uuid),       1 },
104
 
    { offsetof(xfs_sb_t, sb_logstart),   0 },
105
 
    { offsetof(xfs_sb_t, sb_rootino),    0 },
106
 
    { offsetof(xfs_sb_t, sb_rbmino),     0 },
107
 
    { offsetof(xfs_sb_t, sb_rsumino),    0 },
108
 
    { offsetof(xfs_sb_t, sb_rextsize),   0 },
109
 
    { offsetof(xfs_sb_t, sb_agblocks),   0 },
110
 
    { offsetof(xfs_sb_t, sb_agcount),    0 },
111
 
    { offsetof(xfs_sb_t, sb_rbmblocks),  0 },
112
 
    { offsetof(xfs_sb_t, sb_logblocks),  0 },
 
27
    { offsetof(xfs_sb_t, sb_magicnum),   0 },
 
28
    { offsetof(xfs_sb_t, sb_blocksize),  0 },
 
29
    { offsetof(xfs_sb_t, sb_dblocks),    0 },
 
30
    { offsetof(xfs_sb_t, sb_rblocks),    0 },
 
31
    { offsetof(xfs_sb_t, sb_rextents),   0 },
 
32
    { offsetof(xfs_sb_t, sb_uuid),       1 },
 
33
    { offsetof(xfs_sb_t, sb_logstart),   0 },
 
34
    { offsetof(xfs_sb_t, sb_rootino),    0 },
 
35
    { offsetof(xfs_sb_t, sb_rbmino),     0 },
 
36
    { offsetof(xfs_sb_t, sb_rsumino),    0 },
 
37
    { offsetof(xfs_sb_t, sb_rextsize),   0 },
 
38
    { offsetof(xfs_sb_t, sb_agblocks),   0 },
 
39
    { offsetof(xfs_sb_t, sb_agcount),    0 },
 
40
    { offsetof(xfs_sb_t, sb_rbmblocks),  0 },
 
41
    { offsetof(xfs_sb_t, sb_logblocks),  0 },
113
42
    { offsetof(xfs_sb_t, sb_versionnum), 0 },
114
 
    { offsetof(xfs_sb_t, sb_sectsize),   0 },
115
 
    { offsetof(xfs_sb_t, sb_inodesize),  0 },
116
 
    { offsetof(xfs_sb_t, sb_inopblock),  0 },
117
 
    { offsetof(xfs_sb_t, sb_fname[0]),   1 },
118
 
    { offsetof(xfs_sb_t, sb_blocklog),   0 },
119
 
    { offsetof(xfs_sb_t, sb_sectlog),    0 },
120
 
    { offsetof(xfs_sb_t, sb_inodelog),   0 },
121
 
    { offsetof(xfs_sb_t, sb_inopblog),   0 },
122
 
    { offsetof(xfs_sb_t, sb_agblklog),   0 },
123
 
    { offsetof(xfs_sb_t, sb_rextslog),   0 },
 
43
    { offsetof(xfs_sb_t, sb_sectsize),   0 },
 
44
    { offsetof(xfs_sb_t, sb_inodesize),  0 },
 
45
    { offsetof(xfs_sb_t, sb_inopblock),  0 },
 
46
    { offsetof(xfs_sb_t, sb_fname[0]),   1 },
 
47
    { offsetof(xfs_sb_t, sb_blocklog),   0 },
 
48
    { offsetof(xfs_sb_t, sb_sectlog),    0 },
 
49
    { offsetof(xfs_sb_t, sb_inodelog),   0 },
 
50
    { offsetof(xfs_sb_t, sb_inopblog),   0 },
 
51
    { offsetof(xfs_sb_t, sb_agblklog),   0 },
 
52
    { offsetof(xfs_sb_t, sb_rextslog),   0 },
124
53
    { offsetof(xfs_sb_t, sb_inprogress), 0 },
125
 
    { offsetof(xfs_sb_t, sb_imax_pct),   0 },
126
 
    { offsetof(xfs_sb_t, sb_icount),     0 },
127
 
    { offsetof(xfs_sb_t, sb_ifree),      0 },
128
 
    { offsetof(xfs_sb_t, sb_fdblocks),   0 },
129
 
    { offsetof(xfs_sb_t, sb_frextents),  0 },
130
 
    { offsetof(xfs_sb_t, sb_uquotino),   0 },
131
 
    { offsetof(xfs_sb_t, sb_gquotino),   0 },
132
 
    { offsetof(xfs_sb_t, sb_qflags),     0 },
133
 
    { offsetof(xfs_sb_t, sb_flags),      0 },
134
 
    { offsetof(xfs_sb_t, sb_shared_vn),  0 },
 
54
    { offsetof(xfs_sb_t, sb_imax_pct),   0 },
 
55
    { offsetof(xfs_sb_t, sb_icount),     0 },
 
56
    { offsetof(xfs_sb_t, sb_ifree),      0 },
 
57
    { offsetof(xfs_sb_t, sb_fdblocks),   0 },
 
58
    { offsetof(xfs_sb_t, sb_frextents),  0 },
 
59
    { offsetof(xfs_sb_t, sb_uquotino),   0 },
 
60
    { offsetof(xfs_sb_t, sb_gquotino),   0 },
 
61
    { offsetof(xfs_sb_t, sb_qflags),     0 },
 
62
    { offsetof(xfs_sb_t, sb_flags),      0 },
 
63
    { offsetof(xfs_sb_t, sb_shared_vn),  0 },
135
64
    { offsetof(xfs_sb_t, sb_inoalignmt), 0 },
136
65
    { offsetof(xfs_sb_t, sb_unit),       0 },
137
66
    { offsetof(xfs_sb_t, sb_width),      0 },
144
73
    { sizeof(xfs_sb_t),                  0 }
145
74
};
146
75
 
147
 
/*
148
 
 * xfs_xlatesb
149
 
 *     data       - on disk version of sb
150
 
 *     sb         - a superblock
151
 
 *     dir        - conversion direction: <0 - convert sb to buf
152
 
 *                                        >0 - convert buf to sb
153
 
 *     arch       - architecture to read/write from/to buf
154
 
 *     fields     - which fields to copy (bitmask)
155
 
 */
156
 
void
157
 
xfs_xlatesb(
158
 
        void            *data,
159
 
        xfs_sb_t        *sb,
160
 
        int             dir,
161
 
        __int64_t       fields)
162
 
{
163
 
        xfs_caddr_t     buf_ptr;
164
 
        xfs_caddr_t     mem_ptr;
165
 
        xfs_sb_field_t  f;
166
 
        int             first;
167
 
        int             size;
168
 
 
169
 
        ASSERT(dir);
170
 
        ASSERT(fields);
171
 
 
172
 
        if (!fields)
173
 
                return;
174
 
 
175
 
        buf_ptr = (xfs_caddr_t)data;
176
 
        mem_ptr = (xfs_caddr_t)sb;
177
 
 
178
 
        while (fields) {
179
 
                f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields);
180
 
                first = xfs_sb_info[f].offset;
181
 
                size = xfs_sb_info[f + 1].offset - first;
182
 
 
183
 
                ASSERT(xfs_sb_info[f].type == 0 || xfs_sb_info[f].type == 1);
184
 
 
185
 
                if (size == 1 || xfs_sb_info[f].type == 1) {
186
 
                        if (dir > 0) {
187
 
                                memcpy(mem_ptr + first, buf_ptr + first, size);
188
 
                        } else {
189
 
                                memcpy(buf_ptr + first, mem_ptr + first, size);
190
 
                        }
191
 
                } else {
192
 
                        switch (size) {
193
 
                        case 2:
194
 
                                INT_XLATE(*(__uint16_t*)(buf_ptr+first),
195
 
                                          *(__uint16_t*)(mem_ptr+first),
196
 
                                          dir, ARCH_CONVERT);
197
 
                                break;
198
 
                        case 4:
199
 
                                INT_XLATE(*(__uint32_t*)(buf_ptr+first),
200
 
                                          *(__uint32_t*)(mem_ptr+first),
201
 
                                          dir, ARCH_CONVERT);
202
 
                                break;
203
 
                        case 8:
204
 
                                INT_XLATE(*(__uint64_t*)(buf_ptr+first),
205
 
                                          *(__uint64_t*)(mem_ptr+first), dir, ARCH_CONVERT);
206
 
                                break;
207
 
                        default:
208
 
                                ASSERT(0);
209
 
                        }
210
 
                }
211
 
 
212
 
                fields &= ~(1LL << f);
213
 
        }
214
 
}
215
 
 
216
 
/*
217
 
 * xfs_mod_sb() can be used to copy arbitrary changes to the
218
 
 * in-core superblock into the superblock buffer to be logged.
219
 
 * It does not provide the higher level of locking that is
220
 
 * needed to protect the in-core superblock from concurrent
221
 
 * access.
222
 
 */
223
 
void
224
 
xfs_mod_sb(xfs_trans_t *tp, __int64_t fields)
225
 
{
226
 
        xfs_buf_t       *bp;
227
 
        int             first;
228
 
        int             last;
229
 
        xfs_mount_t     *mp;
230
 
        xfs_sb_t        *sbp;
231
 
        xfs_sb_field_t  f;
232
 
 
233
 
        ASSERT(fields);
234
 
        if (!fields)
235
 
                return;
236
 
        mp = tp->t_mountp;
237
 
        bp = xfs_trans_getsb(tp, mp, 0);
238
 
        sbp = XFS_BUF_TO_SBP(bp);
239
 
        first = sizeof(xfs_sb_t);
240
 
        last = 0;
241
 
 
242
 
        /* translate/copy */
243
 
        xfs_xlatesb(XFS_BUF_PTR(bp), &(mp->m_sb), -1, fields);
244
 
 
245
 
        /* find modified range */
246
 
        f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields);
247
 
        ASSERT((1LL << f) & XFS_SB_MOD_BITS);
248
 
        first = xfs_sb_info[f].offset;
249
 
        f = (xfs_sb_field_t)xfs_highbit64((__uint64_t)fields);
250
 
        ASSERT((1LL << f) & XFS_SB_MOD_BITS);
251
 
        last = xfs_sb_info[f + 1].offset - 1;
252
 
 
253
 
        xfs_trans_log_buf(tp, bp, first, last);
254
 
}
255
 
 
256
76
xfs_agnumber_t
257
 
xfs_initialize_perag(xfs_mount_t *mp, xfs_agnumber_t agcount)
 
77
xfs_initialize_perag(
 
78
        xfs_mount_t     *mp,
 
79
        xfs_agnumber_t  agcount)
258
80
{
259
81
        xfs_agnumber_t  index, max_metadata;
260
82
        xfs_perag_t     *pag;
270
92
        /* Clear the mount flag if no inode can overflow 32 bits
271
93
         * on this filesystem, or if specifically requested..
272
94
         */
273
 
        if ((mp->m_flags & XFS_MOUNT_32BITINOOPT) && ino > max_inum) {
 
95
        if ((mp->m_flags & XFS_MOUNT_SMALL_INUMS) && ino > max_inum) {
274
96
                mp->m_flags |= XFS_MOUNT_32BITINODES;
275
97
        } else {
276
98
                mp->m_flags &= ~XFS_MOUNT_32BITINODES;
299
121
                                break;
300
122
                        }
301
123
 
302
 
                        /* This ag is prefered for inodes */
 
124
                        /* This ag is preferred for inodes */
303
125
                        pag = &mp->m_perag[index];
304
126
                        pag->pagi_inodeok = 1;
305
127
                        if (index < max_metadata)
306
128
                                pag->pagf_metadata = 1;
 
129
                        xfs_initialize_perag_icache(pag);
307
130
                }
308
131
        } else {
309
132
                /* Setup default behavior for smaller filesystems */
310
133
                for (index = 0; index < agcount; index++) {
311
134
                        pag = &mp->m_perag[index];
312
135
                        pag->pagi_inodeok = 1;
 
136
                        xfs_initialize_perag_icache(pag);
313
137
                }
314
138
        }
315
139
        return index;
316
140
}
317
141
 
 
142
void
 
143
xfs_sb_from_disk(
 
144
        xfs_sb_t        *to,
 
145
        xfs_dsb_t       *from)
 
146
{
 
147
        to->sb_magicnum = be32_to_cpu(from->sb_magicnum);
 
148
        to->sb_blocksize = be32_to_cpu(from->sb_blocksize);
 
149
        to->sb_dblocks = be64_to_cpu(from->sb_dblocks);
 
150
        to->sb_rblocks = be64_to_cpu(from->sb_rblocks);
 
151
        to->sb_rextents = be64_to_cpu(from->sb_rextents);
 
152
        memcpy(&to->sb_uuid, &from->sb_uuid, sizeof(to->sb_uuid));
 
153
        to->sb_logstart = be64_to_cpu(from->sb_logstart);
 
154
        to->sb_rootino = be64_to_cpu(from->sb_rootino);
 
155
        to->sb_rbmino = be64_to_cpu(from->sb_rbmino);
 
156
        to->sb_rsumino = be64_to_cpu(from->sb_rsumino);
 
157
        to->sb_rextsize = be32_to_cpu(from->sb_rextsize);
 
158
        to->sb_agblocks = be32_to_cpu(from->sb_agblocks);
 
159
        to->sb_agcount = be32_to_cpu(from->sb_agcount);
 
160
        to->sb_rbmblocks = be32_to_cpu(from->sb_rbmblocks);
 
161
        to->sb_logblocks = be32_to_cpu(from->sb_logblocks);
 
162
        to->sb_versionnum = be16_to_cpu(from->sb_versionnum);
 
163
        to->sb_sectsize = be16_to_cpu(from->sb_sectsize);
 
164
        to->sb_inodesize = be16_to_cpu(from->sb_inodesize);
 
165
        to->sb_inopblock = be16_to_cpu(from->sb_inopblock);
 
166
        memcpy(&to->sb_fname, &from->sb_fname, sizeof(to->sb_fname));
 
167
        to->sb_blocklog = from->sb_blocklog;
 
168
        to->sb_sectlog = from->sb_sectlog;
 
169
        to->sb_inodelog = from->sb_inodelog;
 
170
        to->sb_inopblog = from->sb_inopblog;
 
171
        to->sb_agblklog = from->sb_agblklog;
 
172
        to->sb_rextslog = from->sb_rextslog;
 
173
        to->sb_inprogress = from->sb_inprogress;
 
174
        to->sb_imax_pct = from->sb_imax_pct;
 
175
        to->sb_icount = be64_to_cpu(from->sb_icount);
 
176
        to->sb_ifree = be64_to_cpu(from->sb_ifree);
 
177
        to->sb_fdblocks = be64_to_cpu(from->sb_fdblocks);
 
178
        to->sb_frextents = be64_to_cpu(from->sb_frextents);
 
179
        to->sb_uquotino = be64_to_cpu(from->sb_uquotino);
 
180
        to->sb_gquotino = be64_to_cpu(from->sb_gquotino);
 
181
        to->sb_qflags = be16_to_cpu(from->sb_qflags);
 
182
        to->sb_flags = from->sb_flags;
 
183
        to->sb_shared_vn = from->sb_shared_vn;
 
184
        to->sb_inoalignmt = be32_to_cpu(from->sb_inoalignmt);
 
185
        to->sb_unit = be32_to_cpu(from->sb_unit);
 
186
        to->sb_width = be32_to_cpu(from->sb_width);
 
187
        to->sb_dirblklog = from->sb_dirblklog;
 
188
        to->sb_logsectlog = from->sb_logsectlog;
 
189
        to->sb_logsectsize = be16_to_cpu(from->sb_logsectsize);
 
190
        to->sb_logsunit = be32_to_cpu(from->sb_logsunit);
 
191
        to->sb_features2 = be32_to_cpu(from->sb_features2);
 
192
        to->sb_bad_features2 = be32_to_cpu(from->sb_bad_features2);
 
193
}
 
194
 
 
195
/*
 
196
 * Copy in core superblock to ondisk one.
 
197
 *
 
198
 * The fields argument is mask of superblock fields to copy.
 
199
 */
 
200
void
 
201
xfs_sb_to_disk(
 
202
        xfs_dsb_t       *to,
 
203
        xfs_sb_t        *from,
 
204
        __int64_t       fields)
 
205
{
 
206
        xfs_caddr_t     to_ptr = (xfs_caddr_t)to;
 
207
        xfs_caddr_t     from_ptr = (xfs_caddr_t)from;
 
208
        xfs_sb_field_t  f;
 
209
        int             first;
 
210
        int             size;
 
211
 
 
212
        ASSERT(fields);
 
213
        if (!fields)
 
214
                return;
 
215
 
 
216
        while (fields) {
 
217
                f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields);
 
218
                first = xfs_sb_info[f].offset;
 
219
                size = xfs_sb_info[f + 1].offset - first;
 
220
 
 
221
                ASSERT(xfs_sb_info[f].type == 0 || xfs_sb_info[f].type == 1);
 
222
 
 
223
                if (size == 1 || xfs_sb_info[f].type == 1) {
 
224
                        memcpy(to_ptr + first, from_ptr + first, size);
 
225
                } else {
 
226
                        switch (size) {
 
227
                        case 2:
 
228
                                *(__be16 *)(to_ptr + first) =
 
229
                                        cpu_to_be16(*(__u16 *)(from_ptr + first));
 
230
                                break;
 
231
                        case 4:
 
232
                                *(__be32 *)(to_ptr + first) =
 
233
                                        cpu_to_be32(*(__u32 *)(from_ptr + first));
 
234
                                break;
 
235
                        case 8:
 
236
                                *(__be64 *)(to_ptr + first) =
 
237
                                        cpu_to_be64(*(__u64 *)(from_ptr + first));
 
238
                                break;
 
239
                        default:
 
240
                                ASSERT(0);
 
241
                        }
 
242
                }
 
243
 
 
244
                fields &= ~(1LL << f);
 
245
        }
 
246
}
 
247
 
 
248
/*
 
249
 * xfs_mount_common
 
250
 *
 
251
 * Mount initialization code establishing various mount
 
252
 * fields from the superblock associated with the given
 
253
 * mount structure
 
254
 *
 
255
 * Note: this requires user-space public scope for libxfs_mount
 
256
 */
 
257
void
 
258
xfs_mount_common(xfs_mount_t *mp, xfs_sb_t *sbp)
 
259
{
 
260
        mp->m_agfrotor = mp->m_agirotor = 0;
 
261
        spin_lock_init(&mp->m_agirotor_lock);
 
262
        mp->m_maxagi = mp->m_sb.sb_agcount;
 
263
        mp->m_blkbit_log = sbp->sb_blocklog + XFS_NBBYLOG;
 
264
        mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT;
 
265
        mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT;
 
266
        mp->m_agno_log = xfs_highbit32(sbp->sb_agcount - 1) + 1;
 
267
        mp->m_agino_log = sbp->sb_inopblog + sbp->sb_agblklog;
 
268
        mp->m_litino = sbp->sb_inodesize -
 
269
                ((uint)sizeof(xfs_dinode_core_t) + (uint)sizeof(xfs_agino_t));
 
270
        mp->m_blockmask = sbp->sb_blocksize - 1;
 
271
        mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG;
 
272
        mp->m_blockwmask = mp->m_blockwsize - 1;
 
273
        INIT_LIST_HEAD(&mp->m_del_inodes);
 
274
 
 
275
        /*
 
276
         * Setup for attributes, in case they get created.
 
277
         * This value is for inodes getting attributes for the first time,
 
278
         * the per-inode value is for old attribute values.
 
279
         */
 
280
        ASSERT(sbp->sb_inodesize >= 256 && sbp->sb_inodesize <= 2048);
 
281
        switch (sbp->sb_inodesize) {
 
282
        case 256:
 
283
                mp->m_attroffset = XFS_LITINO(mp) -
 
284
                                   XFS_BMDR_SPACE_CALC(MINABTPTRS);
 
285
                break;
 
286
        case 512:
 
287
        case 1024:
 
288
        case 2048:
 
289
                mp->m_attroffset = XFS_BMDR_SPACE_CALC(6 * MINABTPTRS);
 
290
                break;
 
291
        default:
 
292
                ASSERT(0);
 
293
        }
 
294
        ASSERT(mp->m_attroffset < XFS_LITINO(mp));
 
295
 
 
296
        mp->m_alloc_mxr[0] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 1);
 
297
        mp->m_alloc_mxr[1] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 0);
 
298
        mp->m_alloc_mnr[0] = mp->m_alloc_mxr[0] / 2;
 
299
        mp->m_alloc_mnr[1] = mp->m_alloc_mxr[1] / 2;
 
300
 
 
301
        mp->m_inobt_mxr[0] = xfs_inobt_maxrecs(mp, sbp->sb_blocksize, 1);
 
302
        mp->m_inobt_mxr[1] = xfs_inobt_maxrecs(mp, sbp->sb_blocksize, 0);
 
303
        mp->m_inobt_mnr[0] = mp->m_inobt_mxr[0] / 2;
 
304
        mp->m_inobt_mnr[1] = mp->m_inobt_mxr[1] / 2;
 
305
 
 
306
        mp->m_bmap_dmxr[0] = xfs_bmbt_maxrecs(mp, sbp->sb_blocksize, 1);
 
307
        mp->m_bmap_dmxr[1] = xfs_bmbt_maxrecs(mp, sbp->sb_blocksize, 0);
 
308
        mp->m_bmap_dmnr[0] = mp->m_bmap_dmxr[0] / 2;
 
309
        mp->m_bmap_dmnr[1] = mp->m_bmap_dmxr[1] / 2;
 
310
 
 
311
        mp->m_bsize = XFS_FSB_TO_BB(mp, 1);
 
312
        mp->m_ialloc_inos = (int)MAX((__uint16_t)XFS_INODES_PER_CHUNK,
 
313
                                        sbp->sb_inopblock);
 
314
        mp->m_ialloc_blks = mp->m_ialloc_inos >> sbp->sb_inopblog;
 
315
}
 
316
 
318
317
/*
319
318
 * xfs_initialize_perag_data
320
319
 *
322
321
 * allocated inodes, free inodes and used filesystem blocks as this
323
322
 * information is no longer persistent in the superblock. Once we have
324
323
 * this information, write it into the in-core superblock structure.
 
324
 *
 
325
 * Note: this requires user-space public scope for libxfs_mount
325
326
 */
326
 
STATIC int
 
327
int
327
328
xfs_initialize_perag_data(xfs_mount_t *mp, xfs_agnumber_t agcount)
328
329
{
329
330
        xfs_agnumber_t  index;
330
331
        xfs_perag_t     *pag;
331
332
        xfs_sb_t        *sbp = &mp->m_sb;
332
 
        __uint64_t      ifree = 0;
333
 
        __uint64_t      ialloc = 0;
334
 
        __uint64_t      bfree = 0;
335
 
        __uint64_t      bfreelst = 0;
336
 
        __uint64_t      btree = 0;
 
333
        uint64_t        ifree = 0;
 
334
        uint64_t        ialloc = 0;
 
335
        uint64_t        bfree = 0;
 
336
        uint64_t        bfreelst = 0;
 
337
        uint64_t        btree = 0;
337
338
        int             error;
338
 
        int             s;
339
339
 
340
340
        for (index = 0; index < agcount; index++) {
341
341
                /*
342
342
                 * read the agf, then the agi. This gets us
343
 
                 * all the information we need and populates the
 
343
                 * all the inforamtion we need and populates the
344
344
                 * per-ag structures for us.
345
345
                 */
346
346
                error = xfs_alloc_pagf_init(mp, NULL, index, 0);
360
360
        /*
361
361
         * Overwrite incore superblock counters with just-read data
362
362
         */
363
 
        s = XFS_SB_LOCK(mp);
 
363
        spin_lock(&mp->m_sb_lock);
364
364
        sbp->sb_ifree = ifree;
365
365
        sbp->sb_icount = ialloc;
366
366
        sbp->sb_fdblocks = bfree + bfreelst + btree;
367
 
        XFS_SB_UNLOCK(mp, s);
 
367
        spin_unlock(&mp->m_sb_lock);
 
368
 
 
369
        /* Fixup the per-cpu counters as well. */
 
370
        xfs_icsb_reinit_counters(mp);
 
371
 
368
372
        return 0;
369
373
}
 
374
 
 
375
/*
 
376
 * xfs_mod_sb() can be used to copy arbitrary changes to the
 
377
 * in-core superblock into the superblock buffer to be logged.
 
378
 * It does not provide the higher level of locking that is
 
379
 * needed to protect the in-core superblock from concurrent
 
380
 * access.
 
381
 */
 
382
void
 
383
xfs_mod_sb(xfs_trans_t *tp, __int64_t fields)
 
384
{
 
385
        xfs_buf_t       *bp;
 
386
        int             first;
 
387
        int             last;
 
388
        xfs_mount_t     *mp;
 
389
        xfs_sb_field_t  f;
 
390
 
 
391
        ASSERT(fields);
 
392
        if (!fields)
 
393
                return;
 
394
        mp = tp->t_mountp;
 
395
        bp = xfs_trans_getsb(tp, mp, 0);
 
396
        first = sizeof(xfs_sb_t);
 
397
        last = 0;
 
398
 
 
399
        /* translate/copy */
 
400
 
 
401
        xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb, fields);
 
402
 
 
403
        /* find modified range */
 
404
 
 
405
        f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields);
 
406
        ASSERT((1LL << f) & XFS_SB_MOD_BITS);
 
407
        first = xfs_sb_info[f].offset;
 
408
 
 
409
        f = (xfs_sb_field_t)xfs_highbit64((__uint64_t)fields);
 
410
        ASSERT((1LL << f) & XFS_SB_MOD_BITS);
 
411
        last = xfs_sb_info[f + 1].offset - 1;
 
412
 
 
413
        xfs_trans_log_buf(tp, bp, first, last);
 
414
}