~ubuntu-branches/ubuntu/edgy/xfsprogs/edgy

« back to all changes in this revision

Viewing changes to libxfs/util.c

  • Committer: Bazaar Package Importer
  • Author(s): Nathan Scott
  • Date: 2005-11-16 16:32:35 UTC
  • Revision ID: james.westby@ubuntu.com-20051116163235-synnef6xjj18ny42
Tags: 2.7.7-1
* New upstream release.
* Add support for (optional) ATTR2 format extension (closes: #336350)
* Allow gcc -pedantic option for C++ <xfs.h> users (closes: #249429)
* Fix segv in xfs_db frag command (closes: #338207)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
 
2
 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
 
3
 * All Rights Reserved.
3
4
 *
4
 
 * This program is free software; you can redistribute it and/or modify it
5
 
 * under the terms of version 2 of the GNU General Public License as
 
5
 * This program is free software; you can redistribute it and/or
 
6
 * modify it under the terms of the GNU General Public License as
6
7
 * published by the Free Software Foundation.
7
8
 *
8
 
 * This program is distributed in the hope that it would be useful, but
9
 
 * WITHOUT ANY WARRANTY; without even the implied warranty of
10
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11
 
 *
12
 
 * Further, this software is distributed without any warranty that it is
13
 
 * free of the rightful claim of any third person regarding infringement
14
 
 * or the like.  Any license provided herein, whether implied or
15
 
 * otherwise, applies only to this software file.  Patent licenses, if
16
 
 * any, provided herein do not apply to combinations of this program with
17
 
 * other software, or any other product whatsoever.
18
 
 *
19
 
 * You should have received a copy of the GNU General Public License along
20
 
 * with this program; if not, write the Free Software Foundation, Inc., 59
21
 
 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
22
 
 *
23
 
 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24
 
 * Mountain View, CA  94043, or:
25
 
 *
26
 
 * http://www.sgi.com
27
 
 *
28
 
 * For further information regarding this notice, see:
29
 
 *
30
 
 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
 
9
 * This program is distributed in the hope that it would be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 * GNU General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU General Public License
 
15
 * along with this program; if not, write the Free Software Foundation,
 
16
 * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
31
17
 */
32
18
 
33
19
#include <xfs.h>
34
20
#include <time.h>
35
21
 
36
22
/*
37
 
 * Wrapper around call to libxfs_ialloc. Takes care of committing and
38
 
 * allocating a new transaction as needed.
39
 
 *
40
 
 * Originally there were two copies of this code - one in mkfs, the
41
 
 * other in repair - now there is just the one.
42
 
 */
43
 
int
44
 
libxfs_inode_alloc(
45
 
        xfs_trans_t     **tp,
46
 
        xfs_inode_t     *pip,
47
 
        mode_t          mode,
48
 
        ushort          nlink,
49
 
        xfs_dev_t       rdev,
50
 
        cred_t          *cr,
51
 
        xfs_inode_t     **ipp)
52
 
{
53
 
        boolean_t       call_again;
54
 
        int             i;
55
 
        xfs_buf_t       *ialloc_context;
56
 
        xfs_inode_t     *ip;
57
 
        xfs_trans_t     *ntp;
58
 
        int             error;
59
 
 
60
 
        call_again = B_FALSE;
61
 
        ialloc_context = (xfs_buf_t *)0;
62
 
        error = libxfs_ialloc(*tp, pip, mode, nlink, rdev, cr, (xfs_prid_t) 0,
63
 
                           1, &ialloc_context, &call_again, &ip);
64
 
        if (error)
65
 
                return error;
66
 
 
67
 
        if (call_again) {
68
 
                xfs_trans_bhold(*tp, ialloc_context);
69
 
                ntp = xfs_trans_dup(*tp);
70
 
                xfs_trans_commit(*tp, 0, NULL);
71
 
                *tp = ntp;
72
 
                if ((i = xfs_trans_reserve(*tp, 0, 0, 0, 0, 0))) {
73
 
                        fprintf(stderr, _("%s: cannot reserve space: %s\n"),
74
 
                                progname, strerror(errno));
75
 
                        exit(1);
76
 
                }
77
 
                xfs_trans_bjoin(*tp, ialloc_context);
78
 
                error = libxfs_ialloc(*tp, pip, mode, nlink, rdev, cr,
79
 
                                   (xfs_prid_t) 0, 1, &ialloc_context,
80
 
                                   &call_again, &ip);
81
 
                if (!ip)
82
 
                        error = ENOSPC;
83
 
                if (error)
84
 
                        return error;
85
 
        }
86
 
        if (!ip)
87
 
                error = ENOSPC;
88
 
 
89
 
        *ipp = ip;
90
 
        return error;
91
 
}
92
 
 
93
 
/*
94
23
 * Change the requested timestamp in the given inode.
95
24
 *
96
25
 * This was once shared with the kernel, but has diverged to the point
128
57
 * This was once shared with the kernel, but has diverged to the point
129
58
 * where its no longer worth the hassle of maintaining common code.
130
59
 */
131
 
int
 
60
static int
132
61
libxfs_ialloc(
133
62
        xfs_trans_t     *tp,
134
63
        xfs_inode_t     *pip,
135
64
        mode_t          mode,
136
65
        nlink_t         nlink,
137
66
        xfs_dev_t       rdev,
138
 
        cred_t          *cr,
139
 
        xfs_prid_t      prid,
 
67
        struct cred     *cr,
 
68
        struct fsxattr  *fsx,
140
69
        int             okalloc,
141
70
        xfs_buf_t       **ialloc_context,
142
71
        boolean_t       *call_again,
161
90
        }
162
91
        ASSERT(*ialloc_context == NULL);
163
92
 
164
 
        error = xfs_trans_iget(tp->t_mountp, tp, ino, 0, &ip);
 
93
        error = xfs_trans_iget(tp->t_mountp, tp, ino, 0, 0, &ip);
165
94
        if (error != 0)
166
95
                return error;
167
96
        ASSERT(ip != NULL);
172
101
        ASSERT(ip->i_d.di_nlink == nlink);
173
102
        ip->i_d.di_uid = cr->cr_uid;
174
103
        ip->i_d.di_gid = cr->cr_gid;
175
 
        ip->i_d.di_projid = prid;
 
104
        ip->i_d.di_projid = pip ? 0 : fsx->fsx_projid;
176
105
        memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
177
106
 
178
107
        /*
187
116
                /* old link count, projid field, pad field already zeroed */
188
117
        }
189
118
 
 
119
        if (pip && (pip->i_d.di_mode & S_ISGID)) {
 
120
                ip->i_d.di_gid = pip->i_d.di_gid;
 
121
                if ((pip->i_d.di_mode & S_ISGID) && (mode & S_IFMT) == S_IFDIR)
 
122
                        ip->i_d.di_mode |= S_ISGID;
 
123
        }
 
124
 
190
125
        ip->i_d.di_size = 0;
191
126
        ip->i_d.di_nextents = 0;
192
127
        ASSERT(ip->i_d.di_nblocks == 0);
194
129
        /*
195
130
         * di_gen will have been taken care of in xfs_iread.
196
131
         */
197
 
        ip->i_d.di_extsize = 0;
 
132
        ip->i_d.di_extsize = pip ? 0 : fsx->fsx_extsize;
198
133
        ip->i_d.di_dmevmask = 0;
199
134
        ip->i_d.di_dmstate = 0;
200
 
        ip->i_d.di_flags = 0;
 
135
        ip->i_d.di_flags = pip ? 0 : fsx->fsx_xflags;
201
136
        flags = XFS_ILOG_CORE;
202
137
        switch (mode & S_IFMT) {
203
138
        case S_IFIFO:
212
147
                break;
213
148
        case S_IFREG:
214
149
        case S_IFDIR:
 
150
                if (pip && (pip->i_d.di_flags & XFS_DIFLAG_ANY)) {
 
151
                        uint    di_flags = 0;
 
152
 
 
153
                        if ((mode & S_IFMT) == S_IFDIR) {
 
154
                                if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT)
 
155
                                        di_flags |= XFS_DIFLAG_RTINHERIT;
 
156
                                if (pip->i_d.di_flags & XFS_DIFLAG_EXTSZINHERIT) {
 
157
                                        di_flags |= XFS_DIFLAG_EXTSZINHERIT;
 
158
                                        ip->i_d.di_extsize = pip->i_d.di_extsize;
 
159
                                }
 
160
                        } else {
 
161
                                if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT) {
 
162
                                        di_flags |= XFS_DIFLAG_REALTIME;
 
163
                                }
 
164
                                if (pip->i_d.di_flags & XFS_DIFLAG_EXTSZINHERIT) {
 
165
                                        di_flags |= XFS_DIFLAG_EXTSIZE;
 
166
                                        ip->i_d.di_extsize = pip->i_d.di_extsize;
 
167
                                }
 
168
                        }
 
169
                        if (pip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
 
170
                                di_flags |= XFS_DIFLAG_PROJINHERIT;
 
171
                        ip->i_d.di_flags |= di_flags;
 
172
                }
 
173
                /* FALLTHROUGH */
215
174
        case S_IFLNK:
216
175
                ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS;
217
176
                ip->i_df.if_flags = XFS_IFEXTENTS;
339
298
         * because if the inode is dirty at all the core must
340
299
         * be.
341
300
         */
342
 
        xfs_xlate_dinode_core((xfs_caddr_t)&(dip->di_core), &(ip->i_d), -1,
343
 
                                ARCH_CONVERT);
 
301
        xfs_xlate_dinode_core((xfs_caddr_t)&(dip->di_core), &(ip->i_d), -1);
 
302
 
344
303
        /*
345
304
         * If this is really an old format inode and the superblock version
346
305
         * has not been updated to support only new format inodes, then
367
326
                        INT_SET(dip->di_core.di_version, ARCH_CONVERT,
368
327
                                XFS_DINODE_VERSION_2);
369
328
                        ip->i_d.di_onlink = 0;
370
 
                        INT_ZERO(dip->di_core.di_onlink, ARCH_CONVERT);
 
329
                        dip->di_core.di_onlink = 0;
371
330
                        memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
372
331
                        memset(&(dip->di_core.di_pad[0]), 0,
373
332
                                sizeof(dip->di_core.di_pad));
594
553
                        return error;
595
554
                xfs_bmap_del_free(flist, NULL, free);
596
555
        }
 
556
        *committed = 0;
597
557
        return 0;
598
558
}
599
559
 
737
697
        for (i = 0; i < dabuf->nbuf; i++)
738
698
                xfs_trans_bjoin(tp, dabuf->bps[i]);
739
699
}
 
700
 
 
701
/*
 
702
 * Wrapper around call to libxfs_ialloc. Takes care of committing and
 
703
 * allocating a new transaction as needed.
 
704
 *
 
705
 * Originally there were two copies of this code - one in mkfs, the
 
706
 * other in repair - now there is just the one.
 
707
 */
 
708
int
 
709
libxfs_inode_alloc(
 
710
        xfs_trans_t     **tp,
 
711
        xfs_inode_t     *pip,
 
712
        mode_t          mode,
 
713
        nlink_t         nlink,
 
714
        xfs_dev_t       rdev,
 
715
        struct cred     *cr,
 
716
        struct fsxattr  *fsx,
 
717
        xfs_inode_t     **ipp)
 
718
{
 
719
        boolean_t       call_again;
 
720
        int             i;
 
721
        xfs_buf_t       *ialloc_context;
 
722
        xfs_inode_t     *ip;
 
723
        xfs_trans_t     *ntp;
 
724
        int             error;
 
725
 
 
726
        call_again = B_FALSE;
 
727
        ialloc_context = (xfs_buf_t *)0;
 
728
        error = libxfs_ialloc(*tp, pip, mode, nlink, rdev, cr, fsx,
 
729
                           1, &ialloc_context, &call_again, &ip);
 
730
        if (error)
 
731
                return error;
 
732
 
 
733
        if (call_again) {
 
734
                xfs_trans_bhold(*tp, ialloc_context);
 
735
                ntp = xfs_trans_dup(*tp);
 
736
                xfs_trans_commit(*tp, 0, NULL);
 
737
                *tp = ntp;
 
738
                if ((i = xfs_trans_reserve(*tp, 0, 0, 0, 0, 0))) {
 
739
                        fprintf(stderr, _("%s: cannot reserve space: %s\n"),
 
740
                                progname, strerror(errno));
 
741
                        exit(1);
 
742
                }
 
743
                xfs_trans_bjoin(*tp, ialloc_context);
 
744
                error = libxfs_ialloc(*tp, pip, mode, nlink, rdev, cr,
 
745
                                   fsx, 1, &ialloc_context,
 
746
                                   &call_again, &ip);
 
747
                if (!ip)
 
748
                        error = ENOSPC;
 
749
                if (error)
 
750
                        return error;
 
751
        }
 
752
        if (!ip)
 
753
                error = ENOSPC;
 
754
 
 
755
        *ipp = ip;
 
756
        return error;
 
757
}