inline_data.c revision 8f22fa055bdf9dbe0dc8a5de440ed57eb706e098
1416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu/* 2416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu * inline_data.c --- data in inode 3416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu * 4416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu * Copyright (C) 2012 Zheng Liu <wenqing.lz@taobao.com> 5416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu * 6416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu * %Begin-Header% 7416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu * This file may be redistributed under the terms of the GNU library 8416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu * General Public License, version 2. 9416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu * %End-Header% 10416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu */ 11416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 12416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu#include "config.h" 13416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu#include <stdio.h> 14416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu#include <time.h> 15416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 16416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu#include "ext2_fs.h" 17416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu#include "ext2_ext_attr.h" 18416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 19416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu#include "ext2fs.h" 20416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu#include "ext2fsP.h" 21416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 22416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liustruct ext2_inline_data { 23416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ext2_filsys fs; 24416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ext2_ino_t ino; 25416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu size_t ea_size; /* the size of inline data in ea area */ 26416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu void *ea_data; 27416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu}; 28416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 29416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liustatic errcode_t ext2fs_inline_data_ea_set(struct ext2_inline_data *data) 30416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu{ 31416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu struct ext2_xattr_handle *handle; 32416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu errcode_t retval; 33416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 34416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu retval = ext2fs_xattrs_open(data->fs, data->ino, &handle); 35416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (retval) 36416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu return retval; 37416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 38416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu retval = ext2fs_xattrs_read(handle); 39416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (retval) 40416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu goto err; 41416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 42416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu retval = ext2fs_xattr_set(handle, "system.data", 43416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu data->ea_data, data->ea_size); 44416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (retval) 45416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu goto err; 46416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 47416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu retval = ext2fs_xattrs_write(handle); 48416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 49416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liuerr: 50416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu (void) ext2fs_xattrs_close(&handle); 51416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu return retval; 52416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu} 53416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 54416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liustatic errcode_t ext2fs_inline_data_ea_get(struct ext2_inline_data *data) 55416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu{ 56416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu struct ext2_xattr_handle *handle; 57416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu errcode_t retval; 58416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 59416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu data->ea_size = 0; 60416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu data->ea_data = 0; 61416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 62416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu retval = ext2fs_xattrs_open(data->fs, data->ino, &handle); 63416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (retval) 64416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu return retval; 65416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 66416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu retval = ext2fs_xattrs_read(handle); 67416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (retval) 68416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu goto err; 69416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 70416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu retval = ext2fs_xattr_get(handle, "system.data", 71416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu (void **)&data->ea_data, &data->ea_size); 72416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (retval) 73416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu goto err; 74416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 75416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liuerr: 76416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu (void) ext2fs_xattrs_close(&handle); 77416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu return retval; 78416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu} 79416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 8082e77d07ee6c9e2414233d4428887a22bf755609Zheng Liuerrcode_t ext2fs_inline_data_init(ext2_filsys fs, ext2_ino_t ino) 8182e77d07ee6c9e2414233d4428887a22bf755609Zheng Liu{ 8282e77d07ee6c9e2414233d4428887a22bf755609Zheng Liu struct ext2_inline_data data; 8382e77d07ee6c9e2414233d4428887a22bf755609Zheng Liu 8482e77d07ee6c9e2414233d4428887a22bf755609Zheng Liu data.fs = fs; 8582e77d07ee6c9e2414233d4428887a22bf755609Zheng Liu data.ino = ino; 8682e77d07ee6c9e2414233d4428887a22bf755609Zheng Liu data.ea_size = 0; 8782e77d07ee6c9e2414233d4428887a22bf755609Zheng Liu data.ea_data = ""; 8882e77d07ee6c9e2414233d4428887a22bf755609Zheng Liu return ext2fs_inline_data_ea_set(&data); 8982e77d07ee6c9e2414233d4428887a22bf755609Zheng Liu} 9082e77d07ee6c9e2414233d4428887a22bf755609Zheng Liu 91133e94627b01823d2555450ddd1d95401ff2227aZheng Liuerrcode_t ext2fs_inline_data_size(ext2_filsys fs, ext2_ino_t ino, size_t *size) 92133e94627b01823d2555450ddd1d95401ff2227aZheng Liu{ 93133e94627b01823d2555450ddd1d95401ff2227aZheng Liu struct ext2_inode inode; 94133e94627b01823d2555450ddd1d95401ff2227aZheng Liu struct ext2_inline_data data; 95133e94627b01823d2555450ddd1d95401ff2227aZheng Liu errcode_t retval; 96133e94627b01823d2555450ddd1d95401ff2227aZheng Liu 97133e94627b01823d2555450ddd1d95401ff2227aZheng Liu retval = ext2fs_read_inode(fs, ino, &inode); 98133e94627b01823d2555450ddd1d95401ff2227aZheng Liu if (retval) 99133e94627b01823d2555450ddd1d95401ff2227aZheng Liu return retval; 100133e94627b01823d2555450ddd1d95401ff2227aZheng Liu 101133e94627b01823d2555450ddd1d95401ff2227aZheng Liu if (!(inode.i_flags & EXT4_INLINE_DATA_FL)) 102133e94627b01823d2555450ddd1d95401ff2227aZheng Liu return EXT2_ET_NO_INLINE_DATA; 103133e94627b01823d2555450ddd1d95401ff2227aZheng Liu 104133e94627b01823d2555450ddd1d95401ff2227aZheng Liu data.fs = fs; 105133e94627b01823d2555450ddd1d95401ff2227aZheng Liu data.ino = ino; 106133e94627b01823d2555450ddd1d95401ff2227aZheng Liu retval = ext2fs_inline_data_ea_get(&data); 107133e94627b01823d2555450ddd1d95401ff2227aZheng Liu if (retval) 108133e94627b01823d2555450ddd1d95401ff2227aZheng Liu return retval; 109133e94627b01823d2555450ddd1d95401ff2227aZheng Liu 110133e94627b01823d2555450ddd1d95401ff2227aZheng Liu *size = EXT4_MIN_INLINE_DATA_SIZE + data.ea_size; 111133e94627b01823d2555450ddd1d95401ff2227aZheng Liu return ext2fs_free_mem(&data.ea_data); 112133e94627b01823d2555450ddd1d95401ff2227aZheng Liu} 113416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 114416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liuint ext2fs_inline_data_dir_iterate(ext2_filsys fs, ext2_ino_t ino, 115416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu void *priv_data) 116416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu{ 117416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu struct dir_context *ctx; 118416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu struct ext2_inode inode; 119416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu struct ext2_dir_entry dirent; 120416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu struct ext2_inline_data data; 121416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu int ret = BLOCK_ABORT; 122416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu e2_blkcnt_t blockcnt = 0; 1238f22fa055bdf9dbe0dc8a5de440ed57eb706e098Darrick J. Wong char *old_buf; 1248f22fa055bdf9dbe0dc8a5de440ed57eb706e098Darrick J. Wong unsigned int old_buflen; 1258f22fa055bdf9dbe0dc8a5de440ed57eb706e098Darrick J. Wong int old_flags; 126416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 127416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ctx = (struct dir_context *)priv_data; 1288f22fa055bdf9dbe0dc8a5de440ed57eb706e098Darrick J. Wong old_buf = ctx->buf; 1298f22fa055bdf9dbe0dc8a5de440ed57eb706e098Darrick J. Wong old_buflen = ctx->buflen; 1308f22fa055bdf9dbe0dc8a5de440ed57eb706e098Darrick J. Wong old_flags = ctx->flags; 1318f22fa055bdf9dbe0dc8a5de440ed57eb706e098Darrick J. Wong ctx->flags |= DIRENT_FLAG_INCLUDE_INLINE_DATA; 132416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 133416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ctx->errcode = ext2fs_read_inode(fs, ino, &inode); 134416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (ctx->errcode) 135416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu goto out; 136416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 137416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (!(inode.i_flags & EXT4_INLINE_DATA_FL)) { 138416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ctx->errcode = EXT2_ET_NO_INLINE_DATA; 139416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu goto out; 140416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu } 141416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 142416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (!LINUX_S_ISDIR(inode.i_mode)) { 143416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ctx->errcode = EXT2_ET_NO_DIRECTORY; 144416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu goto out; 145416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu } 146416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ret = 0; 147416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 148416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu /* we first check '.' and '..' dir */ 149416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu dirent.inode = ino; 150416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu dirent.name_len = 1; 151416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ext2fs_set_rec_len(fs, EXT2_DIR_REC_LEN(2), &dirent); 152416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu dirent.name[0] = '.'; 153416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu dirent.name[1] = '\0'; 154416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ctx->buf = (char *)&dirent; 155416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ext2fs_get_rec_len(fs, &dirent, &ctx->buflen); 156416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ret |= ext2fs_process_dir_block(fs, 0, blockcnt++, 0, 0, priv_data); 157416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (ret & BLOCK_ABORT) 158416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu goto out; 159416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 160416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu dirent.inode = ext2fs_le32_to_cpu(inode.i_block[0]); 161416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu dirent.name_len = 2; 162416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ext2fs_set_rec_len(fs, EXT2_DIR_REC_LEN(3), &dirent); 163416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu dirent.name[0] = '.'; 164416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu dirent.name[1] = '.'; 165416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu dirent.name[2] = '\0'; 166416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ctx->buf = (char *)&dirent; 167416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ext2fs_get_rec_len(fs, &dirent, &ctx->buflen); 168416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ret |= ext2fs_process_dir_block(fs, 0, blockcnt++, 0, 0, priv_data); 169416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (ret & BLOCK_INLINE_DATA_CHANGED) { 170416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu errcode_t err; 171416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 172416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu inode.i_block[0] = ext2fs_cpu_to_le32(dirent.inode); 173416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu err = ext2fs_write_inode(fs, ino, &inode); 174416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (err) 175416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu goto out; 176416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ret &= ~BLOCK_INLINE_DATA_CHANGED; 177416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu } 178416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (ret & BLOCK_ABORT) 179416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu goto out; 180416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 181416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ctx->buf = (char *)inode.i_block + EXT4_INLINE_DATA_DOTDOT_SIZE; 182416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ctx->buflen = EXT4_MIN_INLINE_DATA_SIZE - EXT4_INLINE_DATA_DOTDOT_SIZE; 183416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu#ifdef WORDS_BIGENDIAN 184416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ctx->errcode = ext2fs_dirent_swab_in2(fs, ctx->buf, ctx->buflen, 0); 185416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (ctx->errcode) { 186416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ret |= BLOCK_ABORT; 187416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu goto out; 188416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu } 189416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu#endif 190416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ret |= ext2fs_process_dir_block(fs, 0, blockcnt++, 0, 0, priv_data); 191416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (ret & BLOCK_INLINE_DATA_CHANGED) { 192416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu#ifdef WORDS_BIGENDIAN 193416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ctx->errcode = ext2fs_dirent_swab_out2(fs, ctx->buf, 194416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ctx->buflen, 0); 195416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (ctx->errcode) { 196416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ret |= BLOCK_ABORT; 197416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu goto out; 198416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu } 199416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu#endif 200416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ctx->errcode = ext2fs_write_inode(fs, ino, &inode); 201416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (ctx->errcode) 202416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ret |= BLOCK_ABORT; 203416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ret &= ~BLOCK_INLINE_DATA_CHANGED; 204416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu } 205416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (ret & BLOCK_ABORT) 206416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu goto out; 207416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 208416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu data.fs = fs; 209416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu data.ino = ino; 210416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ctx->errcode = ext2fs_inline_data_ea_get(&data); 211416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (ctx->errcode) { 212416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ret |= BLOCK_ABORT; 213416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu goto out; 214416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu } 215416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (data.ea_size <= 0) 216416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu goto out; 217416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 218416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ctx->buf = data.ea_data; 219416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ctx->buflen = data.ea_size; 220416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu#ifdef WORDS_BIGENDIAN 221416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ctx.errcode = ext2fs_dirent_swab_in2(fs, ctx->buf, ctx->buflen, 0); 222416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (ctx.errcode) { 223416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ret |= BLOCK_ABORT; 224416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu goto out; 225416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu } 226416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu#endif 227416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 228416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ret |= ext2fs_process_dir_block(fs, 0, blockcnt++, 0, 0, priv_data); 229416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (ret & BLOCK_INLINE_DATA_CHANGED) { 230416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu#ifdef WORDS_BIGENDIAN 231416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ctx->errcode = ext2fs_dirent_swab_out2(fs, ctx->buf, 232416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ctx->buflen, 0); 233416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (ctx->errcode) { 234416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ret |= BLOCK_ABORT; 235416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu goto out1; 236416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu } 237416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu#endif 238416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ctx->errcode = ext2fs_inline_data_ea_set(&data); 239416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (ctx->errcode) 240416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ret |= BLOCK_ABORT; 241416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu } 242416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 243416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liuout1: 244416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ext2fs_free_mem(&data.ea_data); 245416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liuout: 2468f22fa055bdf9dbe0dc8a5de440ed57eb706e098Darrick J. Wong ctx->buf = old_buf; 2478f22fa055bdf9dbe0dc8a5de440ed57eb706e098Darrick J. Wong ctx->buflen = old_buflen; 2488f22fa055bdf9dbe0dc8a5de440ed57eb706e098Darrick J. Wong ctx->flags = old_flags; 249416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ret &= ~(BLOCK_ABORT | BLOCK_INLINE_DATA_CHANGED); 250416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu return ret; 251416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu} 25246bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 25397581d448127f95dcc968c0785f7ab3413bf0222Zheng Liuerrcode_t ext2fs_inline_data_ea_remove(ext2_filsys fs, ext2_ino_t ino) 25446bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu{ 25546bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu struct ext2_xattr_handle *handle; 25646bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu errcode_t retval; 25746bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 25846bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu retval = ext2fs_xattrs_open(fs, ino, &handle); 25946bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu if (retval) 26046bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu return retval; 26146bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 26246bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu retval = ext2fs_xattrs_read(handle); 26346bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu if (retval) 26446bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu goto err; 26546bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 26646bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu retval = ext2fs_xattr_remove(handle, "system.data"); 26746bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu if (retval) 26846bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu goto err; 26946bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 27046bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu retval = ext2fs_xattrs_write(handle); 27146bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 27246bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liuerr: 27346bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu (void) ext2fs_xattrs_close(&handle); 27446bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu return retval; 27546bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu} 27646bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 27746bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liustatic errcode_t ext2fs_inline_data_convert_dir(ext2_filsys fs, ext2_ino_t ino, 27846bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu char *bbuf, char *ibuf, int size) 27946bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu{ 28046bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu struct ext2_dir_entry *dir, *dir2; 28146bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu struct ext2_dir_entry_tail *t; 28246bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu errcode_t retval; 28346bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu unsigned int offset; 28446bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu int csum_size = 0; 28546bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu int filetype = 0; 28646bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu int rec_len; 28746bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 28846bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super, 28946bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 29046bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu csum_size = sizeof(struct ext2_dir_entry_tail); 29146bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 29246bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu /* Create '.' and '..' */ 29346bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu if (EXT2_HAS_INCOMPAT_FEATURE(fs->super, 29446bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu EXT2_FEATURE_INCOMPAT_FILETYPE)) 29546bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu filetype = EXT2_FT_DIR; 29646bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 29746bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu /* 29846bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu * Set up entry for '.' 29946bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu */ 30046bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu dir = (struct ext2_dir_entry *) bbuf; 30146bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu dir->inode = ino; 30246bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu ext2fs_dirent_set_name_len(dir, 1); 30346bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu ext2fs_dirent_set_file_type(dir, filetype); 30446bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu dir->name[0] = '.'; 30546bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu rec_len = (fs->blocksize - csum_size) - EXT2_DIR_REC_LEN(1); 30646bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu dir->rec_len = EXT2_DIR_REC_LEN(1); 30746bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 30846bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu /* 30946bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu * Set up entry for '..' 31046bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu */ 31146bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu dir = (struct ext2_dir_entry *) (bbuf + dir->rec_len); 31246bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu dir->rec_len = EXT2_DIR_REC_LEN(2); 31346bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu dir->inode = ext2fs_le32_to_cpu(((__u32 *)ibuf)[0]); 31446bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu ext2fs_dirent_set_name_len(dir, 2); 31546bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu ext2fs_dirent_set_file_type(dir, filetype); 31646bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu dir->name[0] = '.'; 31746bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu dir->name[1] = '.'; 31846bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 31946bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu /* 32046bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu * Ajust the last rec_len 32146bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu */ 32246bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu offset = EXT2_DIR_REC_LEN(1) + EXT2_DIR_REC_LEN(2); 32346bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu dir = (struct ext2_dir_entry *) (bbuf + offset); 32446bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu memcpy(bbuf + offset, ibuf + EXT4_INLINE_DATA_DOTDOT_SIZE, 32546bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu size - EXT4_INLINE_DATA_DOTDOT_SIZE); 32646bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu size += EXT2_DIR_REC_LEN(1) + EXT2_DIR_REC_LEN(2) - 32746bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu EXT4_INLINE_DATA_DOTDOT_SIZE; 32846bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 32946bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu do { 33046bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu dir2 = dir; 33146bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu retval = ext2fs_get_rec_len(fs, dir, &rec_len); 33246bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu if (retval) 33346bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu goto err; 33446bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu offset += rec_len; 33546bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu dir = (struct ext2_dir_entry *) (bbuf + offset); 33646bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu } while (offset < size); 33746bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu rec_len += fs->blocksize - csum_size - offset; 33846bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu retval = ext2fs_set_rec_len(fs, rec_len, dir2); 33946bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu if (retval) 34046bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu goto err; 34146bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 34246bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu if (csum_size) { 34346bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu t = EXT2_DIRENT_TAIL(bbuf, fs->blocksize); 34446bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu ext2fs_initialize_dirent_tail(fs, t); 34546bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu } 34646bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 34746bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liuerr: 34846bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu return retval; 34946bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu} 35046bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 35154e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liustatic errcode_t 35254e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liuext2fs_inline_data_dir_expand(ext2_filsys fs, ext2_ino_t ino, 35354e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu struct ext2_inode *inode, char *buf, size_t size) 35454e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu{ 35554e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu errcode_t retval; 35654e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu blk64_t blk; 35754e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu char *blk_buf; 35854e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 35954e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu retval = ext2fs_get_memzero(fs->blocksize, &blk_buf); 36054e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (retval) 36154e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu return retval; 36254e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 36354e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu#ifdef WORDS_BIGENDIAN 36454e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu retval = ext2fs_dirent_swab_in2(fs, buf, size); 36554e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (retval) 36654e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu goto errout; 36754e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu#endif 36854e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 36954e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu /* Adjust the rec_len */ 37054e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu retval = ext2fs_inline_data_convert_dir(fs, ino, blk_buf, buf, size); 37154e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu /* Allocate a new block */ 37254e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu retval = ext2fs_new_block2(fs, 0, 0, &blk); 37354e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (retval) 37454e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu goto errout; 37554e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu retval = ext2fs_write_dir_block4(fs, blk, blk_buf, 0, ino); 37654e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (retval) 37754e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu goto errout; 37854e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 37954e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu /* Update inode */ 38054e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (EXT2_HAS_INCOMPAT_FEATURE(fs->super, EXT3_FEATURE_INCOMPAT_EXTENTS)) 38154e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu inode->i_flags |= EXT4_EXTENTS_FL; 38254e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu inode->i_flags &= ~EXT4_INLINE_DATA_FL; 38397bd89cd398108b05e33b676809b50348bf6abb2Darrick J. Wong retval = ext2fs_iblk_add_blocks(fs, inode, 1); 38497bd89cd398108b05e33b676809b50348bf6abb2Darrick J. Wong if (retval) 38597bd89cd398108b05e33b676809b50348bf6abb2Darrick J. Wong goto errout; 38654e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu inode->i_size = fs->blocksize; 38754e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu retval = ext2fs_bmap2(fs, ino, inode, 0, BMAP_SET, 0, 0, &blk); 38854e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (retval) 38954e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu goto errout; 39054e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu retval = ext2fs_write_inode(fs, ino, inode); 39154e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (retval) 39254e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu goto errout; 39354e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu ext2fs_block_alloc_stats(fs, blk, +1); 39454e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 39554e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liuerrout: 39654e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu ext2fs_free_mem(&blk_buf); 39754e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu return retval; 39854e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu} 39954e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 40054e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liustatic errcode_t 40154e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liuext2fs_inline_data_file_expand(ext2_filsys fs, ext2_ino_t ino, 40254e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu struct ext2_inode *inode, char *buf, size_t size) 40354e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu{ 40454e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu ext2_file_t e2_file; 40554e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu errcode_t retval; 40654e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 40754e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu /* Update inode */ 40854e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (EXT2_HAS_INCOMPAT_FEATURE(fs->super, 40954e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu EXT3_FEATURE_INCOMPAT_EXTENTS)) { 41054e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu int i; 41154e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu struct ext3_extent_header *eh; 41254e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 41354e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu eh = (struct ext3_extent_header *) &inode->i_block[0]; 41454e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu eh->eh_depth = 0; 41554e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu eh->eh_entries = 0; 41654e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu eh->eh_magic = EXT3_EXT_MAGIC; 41754e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu i = (sizeof(inode->i_block) - sizeof(*eh)) / 41854e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu sizeof(struct ext3_extent); 41954e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu eh->eh_max = ext2fs_cpu_to_le16(i); 42054e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu inode->i_flags |= EXT4_EXTENTS_FL; 42154e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu } 42254e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu inode->i_flags &= ~EXT4_INLINE_DATA_FL; 42354e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu inode->i_size = 0; 42454e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu retval = ext2fs_write_inode(fs, ino, inode); 42554e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (retval) 42654e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu return retval; 42754e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 42854e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu /* Write out the block buffer */ 42954e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu retval = ext2fs_file_open(fs, ino, EXT2_FILE_WRITE, &e2_file); 43054e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (retval) 43154e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu return retval; 43254e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu retval = ext2fs_file_write(e2_file, buf, size, 0); 43354e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu ext2fs_file_close(e2_file); 43454e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu return retval; 43554e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu} 43654e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 43746bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liuerrcode_t ext2fs_inline_data_expand(ext2_filsys fs, ext2_ino_t ino) 43846bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu{ 43946bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu struct ext2_inode inode; 44046bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu struct ext2_inline_data data; 44146bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu errcode_t retval; 44254e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu size_t inline_size; 44346bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu char *inline_buf = 0; 44446bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 44546bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); 44646bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 44746bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu retval = ext2fs_read_inode(fs, ino, &inode); 44846bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu if (retval) 44946bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu return retval; 45046bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 45146bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu if (!(inode.i_flags & EXT4_INLINE_DATA_FL)) 45246bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu return EXT2_ET_NO_INLINE_DATA; 45346bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 45446bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu data.fs = fs; 45546bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu data.ino = ino; 45646bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu retval = ext2fs_inline_data_ea_get(&data); 45746bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu if (retval) 45846bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu return retval; 45954e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu inline_size = data.ea_size + EXT4_MIN_INLINE_DATA_SIZE; 46054e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu retval = ext2fs_get_mem(inline_size, &inline_buf); 46146bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu if (retval) 46246bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu goto errout; 46346bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 46446bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu memcpy(inline_buf, (void *)inode.i_block, EXT4_MIN_INLINE_DATA_SIZE); 46546bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu if (data.ea_size > 0) { 46646bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu memcpy(inline_buf + EXT4_MIN_INLINE_DATA_SIZE, 46746bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu data.ea_data, data.ea_size); 46846bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu } 46946bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 47046bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu memset((void *)inode.i_block, 0, EXT4_MIN_INLINE_DATA_SIZE); 471179e3bd708251048980c845d0080de1ce79ef21aDarrick J. Wong /* 472179e3bd708251048980c845d0080de1ce79ef21aDarrick J. Wong * NOTE: We must do this write -> ea_remove -> read cycle here because 473179e3bd708251048980c845d0080de1ce79ef21aDarrick J. Wong * removing the inline data EA can free the EA block, which is a change 474179e3bd708251048980c845d0080de1ce79ef21aDarrick J. Wong * that our stack copy of the inode will never see. If that happens, 475179e3bd708251048980c845d0080de1ce79ef21aDarrick J. Wong * we can end up with the EA block and lblk 0 pointing to the same 476179e3bd708251048980c845d0080de1ce79ef21aDarrick J. Wong * pblk, which is bad news. 477179e3bd708251048980c845d0080de1ce79ef21aDarrick J. Wong */ 478179e3bd708251048980c845d0080de1ce79ef21aDarrick J. Wong retval = ext2fs_write_inode(fs, ino, &inode); 479179e3bd708251048980c845d0080de1ce79ef21aDarrick J. Wong if (retval) 480179e3bd708251048980c845d0080de1ce79ef21aDarrick J. Wong goto errout; 48146bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu retval = ext2fs_inline_data_ea_remove(fs, ino); 48246bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu if (retval) 48346bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu goto errout; 484179e3bd708251048980c845d0080de1ce79ef21aDarrick J. Wong retval = ext2fs_read_inode(fs, ino, &inode); 485179e3bd708251048980c845d0080de1ce79ef21aDarrick J. Wong if (retval) 486179e3bd708251048980c845d0080de1ce79ef21aDarrick J. Wong goto errout; 48746bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 48854e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (LINUX_S_ISDIR(inode.i_mode)) { 48954e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu retval = ext2fs_inline_data_dir_expand(fs, ino, &inode, 49054e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu inline_buf, inline_size); 49154e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu } else { 49254e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu retval = ext2fs_inline_data_file_expand(fs, ino, &inode, 49354e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu inline_buf, inline_size); 49454e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu } 49546bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 49646bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liuerrout: 49746bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu if (inline_buf) 49846bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu ext2fs_free_mem(&inline_buf); 49946bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu ext2fs_free_mem(&data.ea_data); 50046bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu return retval; 50146bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu} 50254e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 50354e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu/* 50454e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu * When caller uses this function to retrieve the inline data, it must 50554e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu * allocate a buffer which has the size of inline data. The size of 50654e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu * inline data can be know by ext2fs_inline_data_get_size(). 50754e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu */ 50854e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liuerrcode_t ext2fs_inline_data_get(ext2_filsys fs, ext2_ino_t ino, 50954e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu struct ext2_inode *inode, 51054e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu void *buf, size_t *size) 51154e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu{ 51254e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu struct ext2_inode inode_buf; 51354e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu struct ext2_inline_data data; 51454e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu errcode_t retval; 51554e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 51654e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (!inode) { 51754e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu retval = ext2fs_read_inode(fs, ino, &inode_buf); 51854e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (retval) 51954e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu return retval; 52054e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu inode = &inode_buf; 52154e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu } 52254e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 52354e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu data.fs = fs; 52454e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu data.ino = ino; 52554e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu retval = ext2fs_inline_data_ea_get(&data); 52654e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (retval) 52754e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu return retval; 52854e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 52954e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu memcpy(buf, (void *)inode->i_block, EXT4_MIN_INLINE_DATA_SIZE); 53054e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (data.ea_size > 0) 53154e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu memcpy(buf + EXT4_MIN_INLINE_DATA_SIZE, 53254e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu data.ea_data, data.ea_size); 53354e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 53454e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (size) 53554e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu *size = EXT4_MIN_INLINE_DATA_SIZE + data.ea_size; 53654e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu ext2fs_free_mem(&data.ea_data); 53754e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu return 0; 53854e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu} 53954e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 54054e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liuerrcode_t ext2fs_inline_data_set(ext2_filsys fs, ext2_ino_t ino, 54154e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu struct ext2_inode *inode, 54254e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu void *buf, size_t size) 54354e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu{ 54454e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu struct ext2_inode inode_buf; 54554e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu struct ext2_inline_data data; 54654e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu errcode_t retval; 547cb803fc2caa45fe40f326dcf51f525a56e8af01bDarrick J. Wong size_t free_ea_size, existing_size, free_inode_size; 54854e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 54954e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (!inode) { 55054e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu retval = ext2fs_read_inode(fs, ino, &inode_buf); 55154e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (retval) 55254e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu return retval; 55354e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu inode = &inode_buf; 55454e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu } 55554e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 55654e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (size <= EXT4_MIN_INLINE_DATA_SIZE) { 55754e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu memcpy((void *)inode->i_block, buf, size); 55854e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu return ext2fs_write_inode(fs, ino, inode); 55954e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu } 56054e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 561cb803fc2caa45fe40f326dcf51f525a56e8af01bDarrick J. Wong retval = ext2fs_xattr_inode_max_size(fs, ino, &free_ea_size); 56254e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (retval) 56354e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu return retval; 56454e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 565cb803fc2caa45fe40f326dcf51f525a56e8af01bDarrick J. Wong retval = ext2fs_inline_data_size(fs, ino, &existing_size); 566cb803fc2caa45fe40f326dcf51f525a56e8af01bDarrick J. Wong if (retval) 567cb803fc2caa45fe40f326dcf51f525a56e8af01bDarrick J. Wong return retval; 568cb803fc2caa45fe40f326dcf51f525a56e8af01bDarrick J. Wong 569cb803fc2caa45fe40f326dcf51f525a56e8af01bDarrick J. Wong if (existing_size < EXT4_MIN_INLINE_DATA_SIZE) 570cb803fc2caa45fe40f326dcf51f525a56e8af01bDarrick J. Wong free_inode_size = EXT4_MIN_INLINE_DATA_SIZE - existing_size; 571cb803fc2caa45fe40f326dcf51f525a56e8af01bDarrick J. Wong else 572cb803fc2caa45fe40f326dcf51f525a56e8af01bDarrick J. Wong free_inode_size = 0; 573cb803fc2caa45fe40f326dcf51f525a56e8af01bDarrick J. Wong 574cb803fc2caa45fe40f326dcf51f525a56e8af01bDarrick J. Wong if (size > existing_size + free_ea_size + free_inode_size) 57554e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu return EXT2_ET_INLINE_DATA_NO_SPACE; 57654e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 57754e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu memcpy((void *)inode->i_block, buf, EXT4_MIN_INLINE_DATA_SIZE); 57854e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu retval = ext2fs_write_inode(fs, ino, inode); 57954e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (retval) 58054e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu return retval; 58154e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu data.fs = fs; 58254e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu data.ino = ino; 58354e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu data.ea_size = size - EXT4_MIN_INLINE_DATA_SIZE; 58454e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu data.ea_data = buf + EXT4_MIN_INLINE_DATA_SIZE; 58554e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu return ext2fs_inline_data_ea_set(&data); 58654e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu} 58731253488385a62e4db53cad04f55188a2861b4bbZheng Liu 58831253488385a62e4db53cad04f55188a2861b4bbZheng Liu#ifdef DEBUG 58931253488385a62e4db53cad04f55188a2861b4bbZheng Liu#include "e2p/e2p.h" 59031253488385a62e4db53cad04f55188a2861b4bbZheng Liu 59131253488385a62e4db53cad04f55188a2861b4bbZheng Liu/* 59231253488385a62e4db53cad04f55188a2861b4bbZheng Liu * The length of buffer is set to 64 because in inode's i_block member it only 59331253488385a62e4db53cad04f55188a2861b4bbZheng Liu * can save 60 bytes. Thus this value can let the data being saved in extra 59431253488385a62e4db53cad04f55188a2861b4bbZheng Liu * space. 59531253488385a62e4db53cad04f55188a2861b4bbZheng Liu */ 59631253488385a62e4db53cad04f55188a2861b4bbZheng Liu#define BUFF_SIZE (64) 59731253488385a62e4db53cad04f55188a2861b4bbZheng Liu 59831253488385a62e4db53cad04f55188a2861b4bbZheng Liustatic errcode_t file_test(ext2_filsys fs) 59931253488385a62e4db53cad04f55188a2861b4bbZheng Liu{ 60031253488385a62e4db53cad04f55188a2861b4bbZheng Liu struct ext2_inode inode; 60131253488385a62e4db53cad04f55188a2861b4bbZheng Liu ext2_ino_t newfile; 60231253488385a62e4db53cad04f55188a2861b4bbZheng Liu errcode_t retval; 60331253488385a62e4db53cad04f55188a2861b4bbZheng Liu size_t size; 60431253488385a62e4db53cad04f55188a2861b4bbZheng Liu char *buf = 0, *cmpbuf = 0; 60531253488385a62e4db53cad04f55188a2861b4bbZheng Liu int i; 60631253488385a62e4db53cad04f55188a2861b4bbZheng Liu 60731253488385a62e4db53cad04f55188a2861b4bbZheng Liu /* create a new file */ 60831253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = ext2fs_new_inode(fs, 2, 010755, 0, &newfile); 60931253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (retval) { 61031253488385a62e4db53cad04f55188a2861b4bbZheng Liu com_err("file_test", retval, "while allocaing a new inode"); 61131253488385a62e4db53cad04f55188a2861b4bbZheng Liu return 1; 61231253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 61331253488385a62e4db53cad04f55188a2861b4bbZheng Liu 61431253488385a62e4db53cad04f55188a2861b4bbZheng Liu memset(&inode, 0, sizeof(inode)); 61531253488385a62e4db53cad04f55188a2861b4bbZheng Liu inode.i_flags |= EXT4_INLINE_DATA_FL; 61631253488385a62e4db53cad04f55188a2861b4bbZheng Liu inode.i_size = EXT4_MIN_INLINE_DATA_SIZE; 61731253488385a62e4db53cad04f55188a2861b4bbZheng Liu inode.i_mode = LINUX_S_IFREG; 61831253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = ext2fs_write_new_inode(fs, newfile, &inode); 61931253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (retval) { 62031253488385a62e4db53cad04f55188a2861b4bbZheng Liu com_err("file_test", retval, "while writting a new inode"); 62131253488385a62e4db53cad04f55188a2861b4bbZheng Liu return 1; 62231253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 62331253488385a62e4db53cad04f55188a2861b4bbZheng Liu 62431253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = ext2fs_inline_data_init(fs, newfile); 62531253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (retval) { 62631253488385a62e4db53cad04f55188a2861b4bbZheng Liu com_err("file_test", retval, "while init 'system.data'"); 62731253488385a62e4db53cad04f55188a2861b4bbZheng Liu return 1; 62831253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 62931253488385a62e4db53cad04f55188a2861b4bbZheng Liu 63031253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = ext2fs_inline_data_size(fs, newfile, &size); 63131253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (retval) { 63231253488385a62e4db53cad04f55188a2861b4bbZheng Liu com_err("file_test", retval, "while getting size"); 63331253488385a62e4db53cad04f55188a2861b4bbZheng Liu return 1; 63431253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 63531253488385a62e4db53cad04f55188a2861b4bbZheng Liu 63631253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (size != EXT4_MIN_INLINE_DATA_SIZE) { 63731253488385a62e4db53cad04f55188a2861b4bbZheng Liu fprintf(stderr, 63831253488385a62e4db53cad04f55188a2861b4bbZheng Liu "tst_inline_data: size of inline data is wrong\n"); 63931253488385a62e4db53cad04f55188a2861b4bbZheng Liu return 1; 64031253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 64131253488385a62e4db53cad04f55188a2861b4bbZheng Liu 64231253488385a62e4db53cad04f55188a2861b4bbZheng Liu ext2fs_get_mem(BUFF_SIZE, &buf); 64331253488385a62e4db53cad04f55188a2861b4bbZheng Liu memset(buf, 'a', BUFF_SIZE); 64431253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = ext2fs_inline_data_set(fs, newfile, 0, buf, BUFF_SIZE); 64531253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (retval) { 64631253488385a62e4db53cad04f55188a2861b4bbZheng Liu com_err("file_test", retval, 64731253488385a62e4db53cad04f55188a2861b4bbZheng Liu "while setting inline data %s", buf); 64831253488385a62e4db53cad04f55188a2861b4bbZheng Liu goto err; 64931253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 65031253488385a62e4db53cad04f55188a2861b4bbZheng Liu 65131253488385a62e4db53cad04f55188a2861b4bbZheng Liu ext2fs_get_mem(BUFF_SIZE, &cmpbuf); 65231253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = ext2fs_inline_data_get(fs, newfile, 0, cmpbuf, &size); 65331253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (retval) { 65431253488385a62e4db53cad04f55188a2861b4bbZheng Liu com_err("file_test", retval, "while getting inline data"); 65531253488385a62e4db53cad04f55188a2861b4bbZheng Liu goto err; 65631253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 65731253488385a62e4db53cad04f55188a2861b4bbZheng Liu 65831253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (size != BUFF_SIZE) { 65931253488385a62e4db53cad04f55188a2861b4bbZheng Liu fprintf(stderr, 66031253488385a62e4db53cad04f55188a2861b4bbZheng Liu "tst_inline_data: size %lu != buflen %lu\n", 66131253488385a62e4db53cad04f55188a2861b4bbZheng Liu size, BUFF_SIZE); 66231253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = 1; 66331253488385a62e4db53cad04f55188a2861b4bbZheng Liu goto err; 66431253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 66531253488385a62e4db53cad04f55188a2861b4bbZheng Liu 66631253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (memcmp(buf, cmpbuf, BUFF_SIZE)) { 66731253488385a62e4db53cad04f55188a2861b4bbZheng Liu fprintf(stderr, "tst_inline_data: buf != cmpbuf\n"); 66831253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = 1; 66931253488385a62e4db53cad04f55188a2861b4bbZheng Liu goto err; 67031253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 67131253488385a62e4db53cad04f55188a2861b4bbZheng Liu 67231253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = ext2fs_punch(fs, newfile, 0, 0, 0, ~0ULL); 67331253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (retval) { 67431253488385a62e4db53cad04f55188a2861b4bbZheng Liu com_err("file_test", retval, "while truncating inode"); 67531253488385a62e4db53cad04f55188a2861b4bbZheng Liu goto err; 67631253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 67731253488385a62e4db53cad04f55188a2861b4bbZheng Liu 67831253488385a62e4db53cad04f55188a2861b4bbZheng Liu /* reload inode and check isize */ 67931253488385a62e4db53cad04f55188a2861b4bbZheng Liu ext2fs_read_inode(fs, newfile, &inode); 68031253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (inode.i_size != 0) { 68131253488385a62e4db53cad04f55188a2861b4bbZheng Liu fprintf(stderr, "tst_inline_data: i_size should be 0\n"); 68231253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = 1; 68331253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 68431253488385a62e4db53cad04f55188a2861b4bbZheng Liu 68531253488385a62e4db53cad04f55188a2861b4bbZheng Liuerr: 68631253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (cmpbuf) 68731253488385a62e4db53cad04f55188a2861b4bbZheng Liu ext2fs_free_mem(&cmpbuf); 68831253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (buf) 68931253488385a62e4db53cad04f55188a2861b4bbZheng Liu ext2fs_free_mem(&buf); 69031253488385a62e4db53cad04f55188a2861b4bbZheng Liu return retval; 69131253488385a62e4db53cad04f55188a2861b4bbZheng Liu} 69231253488385a62e4db53cad04f55188a2861b4bbZheng Liu 69331253488385a62e4db53cad04f55188a2861b4bbZheng Liustatic errcode_t dir_test(ext2_filsys fs) 69431253488385a62e4db53cad04f55188a2861b4bbZheng Liu{ 69531253488385a62e4db53cad04f55188a2861b4bbZheng Liu const char *dot_name = "."; 69631253488385a62e4db53cad04f55188a2861b4bbZheng Liu const char *stub_name = "stub"; 69731253488385a62e4db53cad04f55188a2861b4bbZheng Liu const char *parent_name = "test"; 69831253488385a62e4db53cad04f55188a2861b4bbZheng Liu ext2_ino_t parent, dir, tmp; 69931253488385a62e4db53cad04f55188a2861b4bbZheng Liu errcode_t retval; 70031253488385a62e4db53cad04f55188a2861b4bbZheng Liu char dirname[PATH_MAX]; 70131253488385a62e4db53cad04f55188a2861b4bbZheng Liu int i; 70231253488385a62e4db53cad04f55188a2861b4bbZheng Liu 70331253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = ext2fs_mkdir(fs, 11, 11, stub_name); 70431253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (retval) { 70531253488385a62e4db53cad04f55188a2861b4bbZheng Liu com_err("dir_test", retval, "while creating %s dir", stub_name); 70631253488385a62e4db53cad04f55188a2861b4bbZheng Liu return retval; 70731253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 70831253488385a62e4db53cad04f55188a2861b4bbZheng Liu 70931253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = ext2fs_mkdir(fs, 11, 0, parent_name); 71031253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (retval) { 71131253488385a62e4db53cad04f55188a2861b4bbZheng Liu com_err("dir_test", retval, 71231253488385a62e4db53cad04f55188a2861b4bbZheng Liu "while creating %s dir", parent_name); 71331253488385a62e4db53cad04f55188a2861b4bbZheng Liu return retval; 71431253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 71531253488385a62e4db53cad04f55188a2861b4bbZheng Liu 71631253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = ext2fs_lookup(fs, 11, parent_name, strlen(parent_name), 71731253488385a62e4db53cad04f55188a2861b4bbZheng Liu 0, &parent); 71831253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (retval) { 71931253488385a62e4db53cad04f55188a2861b4bbZheng Liu com_err("dir_test", retval, 72031253488385a62e4db53cad04f55188a2861b4bbZheng Liu "while looking up %s dir", parent_name); 72131253488385a62e4db53cad04f55188a2861b4bbZheng Liu return retval; 72231253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 72331253488385a62e4db53cad04f55188a2861b4bbZheng Liu 72431253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = ext2fs_lookup(fs, parent, dot_name, strlen(dot_name), 72531253488385a62e4db53cad04f55188a2861b4bbZheng Liu 0, &tmp); 72631253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (retval) { 72731253488385a62e4db53cad04f55188a2861b4bbZheng Liu com_err("dir_test", retval, 72831253488385a62e4db53cad04f55188a2861b4bbZheng Liu "while looking up %s dir", parent_name); 72931253488385a62e4db53cad04f55188a2861b4bbZheng Liu return retval; 73031253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 73131253488385a62e4db53cad04f55188a2861b4bbZheng Liu 73231253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (parent != tmp) { 73331253488385a62e4db53cad04f55188a2861b4bbZheng Liu fprintf(stderr, "tst_inline_data: parent (%lu) != tmp (%lu)\n", 73431253488385a62e4db53cad04f55188a2861b4bbZheng Liu parent, tmp); 73531253488385a62e4db53cad04f55188a2861b4bbZheng Liu return 1; 73631253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 73731253488385a62e4db53cad04f55188a2861b4bbZheng Liu 73831253488385a62e4db53cad04f55188a2861b4bbZheng Liu for (i = 0, dir = 13; i < 4; i++, dir++) { 73931253488385a62e4db53cad04f55188a2861b4bbZheng Liu tmp = 0; 74031253488385a62e4db53cad04f55188a2861b4bbZheng Liu snprintf(dirname, PATH_MAX, "%d", i); 74131253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = ext2fs_mkdir(fs, parent, 0, dirname); 74231253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (retval) { 74331253488385a62e4db53cad04f55188a2861b4bbZheng Liu com_err("dir_test", retval, 74431253488385a62e4db53cad04f55188a2861b4bbZheng Liu "while creating %s dir", dirname); 74531253488385a62e4db53cad04f55188a2861b4bbZheng Liu return retval; 74631253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 74731253488385a62e4db53cad04f55188a2861b4bbZheng Liu 74831253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = ext2fs_lookup(fs, parent, dirname, strlen(dirname), 74931253488385a62e4db53cad04f55188a2861b4bbZheng Liu 0, &tmp); 75031253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (retval) { 75131253488385a62e4db53cad04f55188a2861b4bbZheng Liu com_err("dir_test", retval, 75231253488385a62e4db53cad04f55188a2861b4bbZheng Liu "while looking up %s dir", parent_name); 75331253488385a62e4db53cad04f55188a2861b4bbZheng Liu return retval; 75431253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 75531253488385a62e4db53cad04f55188a2861b4bbZheng Liu 75631253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (dir != tmp) { 75731253488385a62e4db53cad04f55188a2861b4bbZheng Liu fprintf(stderr, "tst_inline_data: dir (%lu) != tmp (%lu)\n", 75831253488385a62e4db53cad04f55188a2861b4bbZheng Liu dir, tmp); 75931253488385a62e4db53cad04f55188a2861b4bbZheng Liu return 1; 76031253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 76131253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 76231253488385a62e4db53cad04f55188a2861b4bbZheng Liu 76331253488385a62e4db53cad04f55188a2861b4bbZheng Liu snprintf(dirname, PATH_MAX, "%d", i); 76431253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = ext2fs_mkdir(fs, parent, 0, dirname); 76531253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (retval && retval != EXT2_ET_DIR_NO_SPACE) { 76631253488385a62e4db53cad04f55188a2861b4bbZheng Liu com_err("dir_test", retval, "while creating %s dir", dirname); 76731253488385a62e4db53cad04f55188a2861b4bbZheng Liu return retval; 76831253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 76931253488385a62e4db53cad04f55188a2861b4bbZheng Liu 77031253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = ext2fs_expand_dir(fs, parent); 77131253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (retval) { 77231253488385a62e4db53cad04f55188a2861b4bbZheng Liu com_err("dir_test", retval, "while expanding %s dir", parent_name); 77331253488385a62e4db53cad04f55188a2861b4bbZheng Liu return retval; 77431253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 77531253488385a62e4db53cad04f55188a2861b4bbZheng Liu 77631253488385a62e4db53cad04f55188a2861b4bbZheng Liu return 0; 77731253488385a62e4db53cad04f55188a2861b4bbZheng Liu} 77831253488385a62e4db53cad04f55188a2861b4bbZheng Liu 77931253488385a62e4db53cad04f55188a2861b4bbZheng Liuint main(int argc, char *argv[]) 78031253488385a62e4db53cad04f55188a2861b4bbZheng Liu{ 78131253488385a62e4db53cad04f55188a2861b4bbZheng Liu ext2_filsys fs; 78231253488385a62e4db53cad04f55188a2861b4bbZheng Liu struct ext2_super_block param; 78331253488385a62e4db53cad04f55188a2861b4bbZheng Liu errcode_t retval; 78431253488385a62e4db53cad04f55188a2861b4bbZheng Liu int i; 78531253488385a62e4db53cad04f55188a2861b4bbZheng Liu 78631253488385a62e4db53cad04f55188a2861b4bbZheng Liu /* setup */ 78731253488385a62e4db53cad04f55188a2861b4bbZheng Liu initialize_ext2_error_table(); 78831253488385a62e4db53cad04f55188a2861b4bbZheng Liu 78931253488385a62e4db53cad04f55188a2861b4bbZheng Liu memset(¶m, 0, sizeof(param)); 79031253488385a62e4db53cad04f55188a2861b4bbZheng Liu ext2fs_blocks_count_set(¶m, 32768); 79131253488385a62e4db53cad04f55188a2861b4bbZheng Liu param.s_inodes_count = 100; 79231253488385a62e4db53cad04f55188a2861b4bbZheng Liu 79331253488385a62e4db53cad04f55188a2861b4bbZheng Liu param.s_feature_incompat |= EXT4_FEATURE_INCOMPAT_INLINE_DATA; 79431253488385a62e4db53cad04f55188a2861b4bbZheng Liu param.s_rev_level = EXT2_DYNAMIC_REV; 79531253488385a62e4db53cad04f55188a2861b4bbZheng Liu param.s_inode_size = 256; 79631253488385a62e4db53cad04f55188a2861b4bbZheng Liu 79731253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = ext2fs_initialize("test fs", EXT2_FLAG_64BITS, ¶m, 79831253488385a62e4db53cad04f55188a2861b4bbZheng Liu test_io_manager, &fs); 79931253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (retval) { 80031253488385a62e4db53cad04f55188a2861b4bbZheng Liu com_err("setup", retval, 80131253488385a62e4db53cad04f55188a2861b4bbZheng Liu "while initializing filesystem"); 80231253488385a62e4db53cad04f55188a2861b4bbZheng Liu exit(1); 80331253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 80431253488385a62e4db53cad04f55188a2861b4bbZheng Liu 80531253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = ext2fs_allocate_tables(fs); 80631253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (retval) { 80731253488385a62e4db53cad04f55188a2861b4bbZheng Liu com_err("setup", retval, 80831253488385a62e4db53cad04f55188a2861b4bbZheng Liu "while allocating tables for test filesysmte"); 80931253488385a62e4db53cad04f55188a2861b4bbZheng Liu exit(1); 81031253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 81131253488385a62e4db53cad04f55188a2861b4bbZheng Liu 81231253488385a62e4db53cad04f55188a2861b4bbZheng Liu /* initialize inode cache */ 81331253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (!fs->icache) { 81431253488385a62e4db53cad04f55188a2861b4bbZheng Liu struct ext2_inode inode; 81531253488385a62e4db53cad04f55188a2861b4bbZheng Liu ext2_ino_t first_ino = EXT2_FIRST_INO(fs->super); 81631253488385a62e4db53cad04f55188a2861b4bbZheng Liu int i; 81731253488385a62e4db53cad04f55188a2861b4bbZheng Liu 81831253488385a62e4db53cad04f55188a2861b4bbZheng Liu /* we just want to init inode cache. So ignore error */ 81931253488385a62e4db53cad04f55188a2861b4bbZheng Liu ext2fs_create_inode_cache(fs, 16); 82031253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (!fs->icache) { 82131253488385a62e4db53cad04f55188a2861b4bbZheng Liu fprintf(stderr, 82231253488385a62e4db53cad04f55188a2861b4bbZheng Liu "tst_inline_data: init inode cache failed\n"); 82331253488385a62e4db53cad04f55188a2861b4bbZheng Liu exit(1); 82431253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 82531253488385a62e4db53cad04f55188a2861b4bbZheng Liu 82631253488385a62e4db53cad04f55188a2861b4bbZheng Liu /* setup inode cache */ 82731253488385a62e4db53cad04f55188a2861b4bbZheng Liu for (i = 0; i < fs->icache->cache_size; i++) 82831253488385a62e4db53cad04f55188a2861b4bbZheng Liu fs->icache->cache[i].ino = first_ino++; 82931253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 83031253488385a62e4db53cad04f55188a2861b4bbZheng Liu 83131253488385a62e4db53cad04f55188a2861b4bbZheng Liu /* test */ 83231253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (file_test(fs)) { 83331253488385a62e4db53cad04f55188a2861b4bbZheng Liu fprintf(stderr, "tst_inline_data(FILE): FAILED\n"); 83431253488385a62e4db53cad04f55188a2861b4bbZheng Liu return 1; 83531253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 83631253488385a62e4db53cad04f55188a2861b4bbZheng Liu printf("tst_inline_data(FILE): OK\n"); 83731253488385a62e4db53cad04f55188a2861b4bbZheng Liu 83831253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (dir_test(fs)) { 83931253488385a62e4db53cad04f55188a2861b4bbZheng Liu fprintf(stderr, "tst_inline_data(DIR): FAILED\n"); 84031253488385a62e4db53cad04f55188a2861b4bbZheng Liu return 1; 84131253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 84231253488385a62e4db53cad04f55188a2861b4bbZheng Liu printf("tst_inline_data(DIR): OK\n"); 84331253488385a62e4db53cad04f55188a2861b4bbZheng Liu 84431253488385a62e4db53cad04f55188a2861b4bbZheng Liu return 0; 84531253488385a62e4db53cad04f55188a2861b4bbZheng Liu} 84631253488385a62e4db53cad04f55188a2861b4bbZheng Liu#endif 847