1 /* ----------------------------------------------------------------------- *
3 * Copyright 2010 Intel Corp. - All Rights Reserved
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, Inc., 53 Temple Place Ste 330,
8 * Boston MA 02111-1307, USA; either version 2 of the License, or
9 * (at your option) any later version; incorporated herein by reference.
11 * ----------------------------------------------------------------------- */
16 * common functions for extlinux & syslinux installer
30 #include <sys/types.h>
31 #include <sys/mount.h>
33 #include "linuxioctl.h"
41 # define dprintf printf
43 # define dprintf(...) ((void)0)
46 #define SECTOR_SHIFT 9
48 static void die(const char *msg
)
55 * read/write wrapper functions
57 ssize_t
xpread(int fd
, void *buf
, size_t count
, off_t offset
)
59 char *bufp
= (char *)buf
;
64 rv
= pread(fd
, bufp
, count
, offset
);
67 } else if (rv
== -1) {
84 ssize_t
xpwrite(int fd
, const void *buf
, size_t count
, off_t offset
)
86 const char *bufp
= (const char *)buf
;
91 rv
= pwrite(fd
, bufp
, count
, offset
);
94 } else if (rv
== -1) {
112 * Set and clear file attributes
114 void clear_attributes(int fd
)
118 if (!fstat(fd
, &st
)) {
124 if (!ioctl(fd
, EXT2_IOC_GETFLAGS
, &flags
)) {
125 flags
&= ~EXT2_IMMUTABLE_FL
;
126 ioctl(fd
, EXT2_IOC_SETFLAGS
, &flags
);
132 uint32_t attr
= 0x00; /* Clear all attributes */
133 ioctl(fd
, FAT_IOCTL_SET_ATTRIBUTES
, &attr
);
139 fchmod(fd
, st
.st_mode
| S_IWUSR
);
143 void set_attributes(int fd
)
147 if (!fstat(fd
, &st
)) {
148 fchmod(fd
, st
.st_mode
& (S_IRUSR
| S_IRGRP
| S_IROTH
));
154 if (st
.st_uid
== 0 && !ioctl(fd
, EXT2_IOC_GETFLAGS
, &flags
)) {
155 flags
|= EXT2_IMMUTABLE_FL
;
156 ioctl(fd
, EXT2_IOC_SETFLAGS
, &flags
);
162 uint32_t attr
= 0x07; /* Hidden+System+Readonly */
163 ioctl(fd
, FAT_IOCTL_SET_ATTRIBUTES
, &attr
);
172 /* New FIEMAP based mapping */
173 static int sectmap_fie(int fd
, sector_t
*sectors
, int nsectors
)
176 struct fiemap_extent
*fe
;
177 unsigned int i
, nsec
;
178 sector_t sec
, *secp
, *esec
;
185 fm
= alloca(sizeof(struct fiemap
)
186 + nsectors
* sizeof(struct fiemap_extent
));
188 memset(fm
, 0, sizeof *fm
);
190 maplen
= (uint64_t)nsectors
<< SECTOR_SHIFT
;
191 if (maplen
> (uint64_t)st
.st_size
)
195 fm
->fm_length
= maplen
;
196 fm
->fm_flags
= FIEMAP_FLAG_SYNC
;
197 fm
->fm_extent_count
= nsectors
;
199 if (ioctl(fd
, FS_IOC_FIEMAP
, fm
))
202 memset(sectors
, 0, nsectors
* sizeof *sectors
);
203 esec
= sectors
+ nsectors
;
207 if (fm
->fm_mapped_extents
< 1 ||
208 !(fe
[fm
->fm_mapped_extents
-1].fe_flags
& FIEMAP_EXTENT_LAST
))
211 for (i
= 0; i
< fm
->fm_mapped_extents
; i
++) {
212 if (fe
->fe_flags
& FIEMAP_EXTENT_LAST
) {
213 /* If this is the *final* extent, pad the length */
214 fe
->fe_length
= (fe
->fe_length
+ SECTOR_SIZE
- 1)
215 & ~(SECTOR_SIZE
- 1);
218 if ((fe
->fe_logical
| fe
->fe_physical
| fe
->fe_length
) &
222 if (fe
->fe_flags
& (FIEMAP_EXTENT_UNKNOWN
|
223 FIEMAP_EXTENT_DELALLOC
|
224 FIEMAP_EXTENT_ENCODED
|
225 FIEMAP_EXTENT_DATA_ENCRYPTED
|
226 FIEMAP_EXTENT_UNWRITTEN
))
229 secp
= sectors
+ (fe
->fe_logical
>> SECTOR_SHIFT
);
230 sec
= fe
->fe_physical
>> SECTOR_SHIFT
;
231 nsec
= fe
->fe_length
>> SECTOR_SHIFT
;
245 /* Legacy FIBMAP based mapping */
246 static int sectmap_fib(int fd
, sector_t
*sectors
, int nsectors
)
248 unsigned int blk
, nblk
;
250 unsigned int blksize
;
254 if (ioctl(fd
, FIGETBSZ
, &blksize
))
257 /* Number of sectors per block */
258 blksize
>>= SECTOR_SHIFT
;
263 if (ioctl(fd
, FIBMAP
, &blk
))
266 sec
= (sector_t
)blk
* blksize
;
267 for (i
= 0; i
< blksize
; i
++) {
280 int sectmap(int fd
, sector_t
*sectors
, int nsectors
)
282 if (!sectmap_fie(fd
, sectors
, nsectors
))
285 return sectmap_fib(fd
, sectors
, nsectors
);