]>
git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - libxfs/rdwr.c
897aa5761b1809d64db0a973e68f3cf3f4aafe67
2 * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
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
6 * published by the Free Software Foundation.
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.
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.
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.
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
28 * For further information regarding this notice, see:
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
36 #include <xfs_log_priv.h>
38 #define BBTOOFF64(bbs) (((xfs_off_t)(bbs)) << BBSHIFT)
39 #define BDSTRAT_SIZE (256 * 1024)
42 libxfs_device_zero(dev_t dev
, xfs_daddr_t start
, uint len
)
50 size
= BDSTRAT_SIZE
<= BBTOB(len
) ? BDSTRAT_SIZE
: BBTOB(len
);
51 if ((z
= memalign(getpagesize(), size
)) == NULL
) {
52 fprintf(stderr
, "%s: device_zero can't memalign %d bytes: %s\n",
53 progname
, size
, strerror(errno
));
57 fd
= libxfs_device_to_fd(dev
);
58 for (bno
= start
; bno
< start
+ len
; ) {
59 nblks
= (uint
)BTOBB(size
);
60 if (bno
+ nblks
> start
+ len
)
61 nblks
= (uint
)(start
+ len
- bno
);
62 if (lseek64(fd
, BBTOOFF64(bno
), SEEK_SET
) < 0) {
63 fprintf(stderr
, "%s: device_zero lseek64 failed: %s\n",
64 progname
, strerror(errno
));
67 if (write(fd
, z
, BBTOB(nblks
)) < BBTOB(nblks
)) {
68 fprintf(stderr
, "%s: device_zero write failed: %s\n",
69 progname
, strerror(errno
));
86 xlog_rec_header_t
*head
;
88 /* the data section must be 32 bit size aligned */
92 __uint32_t pad2
; /* may as well make it 64 bits */
93 } magic
= { XLOG_UNMOUNT_TYPE
, 0, 0 };
95 if (!device
|| !fs_uuid
)
98 /* first zero the log */
99 libxfs_device_zero(device
, start
, length
);
101 /* then write a log record header */
102 buf
= libxfs_getbuf(device
, start
, 1);
106 memset(XFS_BUF_PTR(buf
), 0, BBSIZE
);
107 head
= (xlog_rec_header_t
*)XFS_BUF_PTR(buf
);
109 /* note that oh_tid actually contains the cycle number
110 * and the tid is stored in h_cycle_data[0] - that's the
111 * way things end up on disk.
114 INT_SET(head
->h_magicno
, ARCH_CONVERT
, XLOG_HEADER_MAGIC_NUM
);
115 INT_SET(head
->h_cycle
, ARCH_CONVERT
, 1);
116 INT_SET(head
->h_version
, ARCH_CONVERT
, 1);
117 INT_SET(head
->h_len
, ARCH_CONVERT
, 20);
118 INT_SET(head
->h_chksum
, ARCH_CONVERT
, 0);
119 INT_SET(head
->h_prev_block
, ARCH_CONVERT
, -1);
120 INT_SET(head
->h_num_logops
, ARCH_CONVERT
, 1);
121 INT_SET(head
->h_cycle_data
[0], ARCH_CONVERT
, 0xb0c0d0d0);
122 INT_SET(head
->h_fmt
, ARCH_CONVERT
, fmt
);
124 ASSIGN_ANY_LSN(head
->h_lsn
, 1, 0, ARCH_CONVERT
);
125 ASSIGN_ANY_LSN(head
->h_tail_lsn
, 1, 0, ARCH_CONVERT
);
127 memcpy(head
->h_fs_uuid
, fs_uuid
, sizeof(uuid_t
));
129 if (libxfs_writebuf(buf
, 0))
132 buf
= libxfs_getbuf(device
, start
+ 1, 1);
136 /* now a log unmount op */
137 memset(XFS_BUF_PTR(buf
), 0, BBSIZE
);
138 op
= (xlog_op_header_t
*)XFS_BUF_PTR(buf
);
139 INT_SET(op
->oh_tid
, ARCH_CONVERT
, 1);
140 INT_SET(op
->oh_len
, ARCH_CONVERT
, sizeof(magic
));
141 INT_SET(op
->oh_clientid
, ARCH_CONVERT
, XFS_LOG
);
142 INT_SET(op
->oh_flags
, ARCH_CONVERT
, XLOG_UNMOUNT_TRANS
);
143 INT_SET(op
->oh_res2
, ARCH_CONVERT
, 0);
145 /* and the data for this op */
147 memcpy(XFS_BUF_PTR(buf
) + sizeof(xlog_op_header_t
),
151 if (libxfs_writebuf(buf
, 0))
158 * Simple I/O interface
162 libxfs_getbuf(dev_t device
, xfs_daddr_t blkno
, int len
)
167 total
= sizeof(xfs_buf_t
) + BBTOB(len
);
168 if ((buf
= calloc(total
, 1)) == NULL
) {
169 fprintf(stderr
, "%s: buf calloc failed (%ld bytes): %s\n",
170 progname
, (long)total
, strerror(errno
));
173 /* by default, we allocate buffer directly after the header */
174 buf
->b_blkno
= blkno
;
175 buf
->b_bcount
= BBTOB(len
);
177 buf
->b_addr
= (char *)(&buf
->b_addr
+ 1); /* must be last field */
179 fprintf(stderr
, "getbuf allocated %ubytes, blkno=%llu(%llu), %p\n",
180 BBTOB(len
), BBTOOFF64(blkno
), blkno
, buf
);
187 libxfs_readbufr(dev_t dev
, xfs_daddr_t blkno
, xfs_buf_t
*buf
, int len
, int die
)
189 int fd
= libxfs_device_to_fd(dev
);
192 buf
->b_blkno
= blkno
;
193 ASSERT(BBTOB(len
) <= buf
->b_bcount
);
195 if (lseek64(fd
, BBTOOFF64(blkno
), SEEK_SET
) < 0) {
196 fprintf(stderr
, "%s: lseek64 to %llu failed: %s\n", progname
,
197 (unsigned long long)BBTOOFF64(blkno
), strerror(errno
));
203 if (read(fd
, buf
->b_addr
, BBTOB(len
)) < 0) {
204 fprintf(stderr
, "%s: read failed: %s\n",
205 progname
, strerror(errno
));
211 fprintf(stderr
, "readbufr read %ubytes, blkno=%llu(%llu), %p\n",
212 BBTOB(len
), BBTOOFF64(blkno
), blkno
, buf
);
218 libxfs_readbuf(dev_t dev
, xfs_daddr_t blkno
, int len
, int die
)
223 buf
= libxfs_getbuf(dev
, blkno
, len
);
224 error
= libxfs_readbufr(dev
, blkno
, buf
, len
, die
);
233 libxfs_getsb(xfs_mount_t
*mp
, int die
)
235 return libxfs_readbuf(mp
->m_dev
, XFS_SB_DADDR
,
236 XFS_FSB_TO_BB(mp
, 1), die
);
240 libxfs_writebuf_int(xfs_buf_t
*buf
, int die
)
243 int fd
= libxfs_device_to_fd(buf
->b_dev
);
245 if (lseek64(fd
, BBTOOFF64(buf
->b_blkno
), SEEK_SET
) < 0) {
246 fprintf(stderr
, "%s: lseek64 to %llu failed: %s\n", progname
,
247 (unsigned long long)BBTOOFF64(buf
->b_blkno
), strerror(errno
));
254 fprintf(stderr
, "writing %ubytes at blkno=%llu(%llu), %p\n",
255 buf
->b_bcount
, BBTOOFF64(buf
->b_blkno
), buf
->b_blkno
, buf
);
257 sts
= write(fd
, buf
->b_addr
, buf
->b_bcount
);
259 fprintf(stderr
, "%s: write failed: %s\n",
260 progname
, strerror(errno
));
266 else if (sts
!= buf
->b_bcount
) {
267 fprintf(stderr
, "%s: error - wrote only %d of %d bytes\n",
268 progname
, sts
, buf
->b_bcount
);
277 libxfs_writebuf(xfs_buf_t
*buf
, int die
)
279 int error
= libxfs_writebuf_int(buf
, die
);
285 libxfs_putbuf(xfs_buf_t
*buf
)
288 xfs_buf_log_item_t
*bip
;
289 extern xfs_zone_t
*xfs_buf_item_zone
;
291 bip
= XFS_BUF_FSPRIVATE(buf
, xfs_buf_log_item_t
*);
294 libxfs_zone_free(xfs_buf_item_zone
, bip
);
296 fprintf(stderr
, "putbuf released %ubytes, %p\n",
306 * Simple memory interface
310 libxfs_zone_init(int size
, char *name
)
314 if ((ptr
= malloc(sizeof(xfs_zone_t
))) == NULL
) {
315 fprintf(stderr
, "%s: zone init failed (%s, %d bytes): %s\n",
316 progname
, name
, (int)sizeof(xfs_zone_t
), strerror(errno
));
319 ptr
->zone_unitsize
= size
;
320 ptr
->zone_name
= name
;
323 fprintf(stderr
, "new zone %p for \"%s\", size=%d\n", ptr
, name
, size
);
329 libxfs_zone_zalloc(xfs_zone_t
*z
)
334 if ((ptr
= calloc(z
->zone_unitsize
, 1)) == NULL
) {
335 fprintf(stderr
, "%s: zone calloc failed (%s, %d bytes): %s\n",
336 progname
, z
->zone_name
, z
->zone_unitsize
,
342 fprintf(stderr
, "## zone alloc'd item %p from %s (%d bytes) (%d active)\n",
343 ptr
, z
->zone_name
, z
->zone_unitsize
,
350 libxfs_zone_free(xfs_zone_t
*z
, void *ptr
)
354 fprintf(stderr
, "## zone freed item %p from %s (%d bytes) (%d active)\n",
355 ptr
, z
->zone_name
, z
->zone_unitsize
,
365 libxfs_malloc(size_t size
)
369 if ((ptr
= calloc(1, size
)) == NULL
) {
370 fprintf(stderr
, "%s: calloc failed (%d bytes): %s\n",
371 progname
, (int)size
, strerror(errno
));
375 fprintf(stderr
, "## calloc'd item %p size %d bytes\n",
382 libxfs_free(void *ptr
)
385 fprintf(stderr
, "## freed item %p\n",
395 libxfs_realloc(void *ptr
, size_t size
)
400 if ((ptr
= realloc(ptr
, size
)) == NULL
) {
401 fprintf(stderr
, "%s: realloc failed (%d bytes): %s\n",
402 progname
, (int)size
, strerror(errno
));
406 fprintf(stderr
, "## realloc'd item %p now %p size %d bytes\n",
414 libxfs_iget(xfs_mount_t
*mp
, xfs_trans_t
*tp
, xfs_ino_t ino
, uint lock_flags
,
415 xfs_inode_t
**ipp
, xfs_daddr_t bno
)
420 error
= libxfs_iread(mp
, tp
, ino
, &ip
, bno
);
428 libxfs_iput(xfs_inode_t
*ip
, uint lock_flags
)
430 extern xfs_zone_t
*xfs_ili_zone
;
431 extern xfs_zone_t
*xfs_inode_zone
;
435 /* free attached inode log item */
437 libxfs_zone_free(xfs_ili_zone
, ip
->i_itemp
);
440 libxfs_zone_free(xfs_inode_zone
, ip
);
446 * libxfs_mod_sb can be used to copy arbitrary changes to the
447 * in-core superblock into the superblock buffer to be logged.
449 * In user-space, we simply convert to big-endian, and write the
450 * the whole superblock - the in-core changes have all been made
454 libxfs_mod_sb(xfs_trans_t
*tp
, __int64_t fields
)
460 bp
= libxfs_getbuf(mp
->m_dev
, XFS_SB_DADDR
, 1);
461 libxfs_xlate_sb(XFS_BUF_PTR(bp
), &mp
->m_sb
, -1, ARCH_CONVERT
,
463 libxfs_writebuf(bp
, 1);