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> 15bbccc6f3c6a106721fb6f1ef4df6bc32c7986235Andreas Dilger#include <limits.h> /* for PATH_MAX */ 16416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 17416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu#include "ext2_fs.h" 18416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu#include "ext2_ext_attr.h" 19416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 20416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu#include "ext2fs.h" 21416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu#include "ext2fsP.h" 22416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 23416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liustruct ext2_inline_data { 24416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ext2_filsys fs; 25416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ext2_ino_t ino; 26416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu size_t ea_size; /* the size of inline data in ea area */ 27416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu void *ea_data; 28416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu}; 29416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 30416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liustatic errcode_t ext2fs_inline_data_ea_set(struct ext2_inline_data *data) 31416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu{ 32416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu struct ext2_xattr_handle *handle; 33416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu errcode_t retval; 34416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 35416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu retval = ext2fs_xattrs_open(data->fs, data->ino, &handle); 36416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (retval) 37416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu return retval; 38416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 39416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu retval = ext2fs_xattrs_read(handle); 40416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (retval) 41416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu goto err; 42416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 43416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu retval = ext2fs_xattr_set(handle, "system.data", 44416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu data->ea_data, data->ea_size); 45416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (retval) 46416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu goto err; 47416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 48416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu retval = ext2fs_xattrs_write(handle); 49416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 50416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liuerr: 51416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu (void) ext2fs_xattrs_close(&handle); 52416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu return retval; 53416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu} 54416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 55416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liustatic errcode_t ext2fs_inline_data_ea_get(struct ext2_inline_data *data) 56416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu{ 57416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu struct ext2_xattr_handle *handle; 58416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu errcode_t retval; 59416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 60416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu data->ea_size = 0; 61416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu data->ea_data = 0; 62416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 63416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu retval = ext2fs_xattrs_open(data->fs, data->ino, &handle); 64416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (retval) 65416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu return retval; 66416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 67416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu retval = ext2fs_xattrs_read(handle); 68416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (retval) 69416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu goto err; 70416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 71416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu retval = ext2fs_xattr_get(handle, "system.data", 72416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu (void **)&data->ea_data, &data->ea_size); 73996999a1a45e1d36ff0e24925ee02fca87ad8283Darrick J. Wong if (retval == EXT2_ET_EA_KEY_NOT_FOUND) { 74996999a1a45e1d36ff0e24925ee02fca87ad8283Darrick J. Wong data->ea_size = 0; 75996999a1a45e1d36ff0e24925ee02fca87ad8283Darrick J. Wong data->ea_data = NULL; 76996999a1a45e1d36ff0e24925ee02fca87ad8283Darrick J. Wong retval = 0; 77996999a1a45e1d36ff0e24925ee02fca87ad8283Darrick J. Wong } else if (retval) 78416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu goto err; 79416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 80416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liuerr: 81416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu (void) ext2fs_xattrs_close(&handle); 82416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu return retval; 83416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu} 84416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 8582e77d07ee6c9e2414233d4428887a22bf755609Zheng Liuerrcode_t ext2fs_inline_data_init(ext2_filsys fs, ext2_ino_t ino) 8682e77d07ee6c9e2414233d4428887a22bf755609Zheng Liu{ 8782e77d07ee6c9e2414233d4428887a22bf755609Zheng Liu struct ext2_inline_data data; 888f8511aba07c47df779be94eeb5970f2b73000d8Theodore Ts'o char empty[1] = { '\0' }; 8982e77d07ee6c9e2414233d4428887a22bf755609Zheng Liu 9082e77d07ee6c9e2414233d4428887a22bf755609Zheng Liu data.fs = fs; 9182e77d07ee6c9e2414233d4428887a22bf755609Zheng Liu data.ino = ino; 9282e77d07ee6c9e2414233d4428887a22bf755609Zheng Liu data.ea_size = 0; 938f8511aba07c47df779be94eeb5970f2b73000d8Theodore Ts'o data.ea_data = empty; 9482e77d07ee6c9e2414233d4428887a22bf755609Zheng Liu return ext2fs_inline_data_ea_set(&data); 9582e77d07ee6c9e2414233d4428887a22bf755609Zheng Liu} 9682e77d07ee6c9e2414233d4428887a22bf755609Zheng Liu 97133e94627b01823d2555450ddd1d95401ff2227aZheng Liuerrcode_t ext2fs_inline_data_size(ext2_filsys fs, ext2_ino_t ino, size_t *size) 98133e94627b01823d2555450ddd1d95401ff2227aZheng Liu{ 99133e94627b01823d2555450ddd1d95401ff2227aZheng Liu struct ext2_inode inode; 100133e94627b01823d2555450ddd1d95401ff2227aZheng Liu struct ext2_inline_data data; 101133e94627b01823d2555450ddd1d95401ff2227aZheng Liu errcode_t retval; 102133e94627b01823d2555450ddd1d95401ff2227aZheng Liu 103133e94627b01823d2555450ddd1d95401ff2227aZheng Liu retval = ext2fs_read_inode(fs, ino, &inode); 104133e94627b01823d2555450ddd1d95401ff2227aZheng Liu if (retval) 105133e94627b01823d2555450ddd1d95401ff2227aZheng Liu return retval; 106133e94627b01823d2555450ddd1d95401ff2227aZheng Liu 107133e94627b01823d2555450ddd1d95401ff2227aZheng Liu if (!(inode.i_flags & EXT4_INLINE_DATA_FL)) 108133e94627b01823d2555450ddd1d95401ff2227aZheng Liu return EXT2_ET_NO_INLINE_DATA; 109133e94627b01823d2555450ddd1d95401ff2227aZheng Liu 110133e94627b01823d2555450ddd1d95401ff2227aZheng Liu data.fs = fs; 111133e94627b01823d2555450ddd1d95401ff2227aZheng Liu data.ino = ino; 112133e94627b01823d2555450ddd1d95401ff2227aZheng Liu retval = ext2fs_inline_data_ea_get(&data); 113133e94627b01823d2555450ddd1d95401ff2227aZheng Liu if (retval) 114133e94627b01823d2555450ddd1d95401ff2227aZheng Liu return retval; 115133e94627b01823d2555450ddd1d95401ff2227aZheng Liu 116133e94627b01823d2555450ddd1d95401ff2227aZheng Liu *size = EXT4_MIN_INLINE_DATA_SIZE + data.ea_size; 117133e94627b01823d2555450ddd1d95401ff2227aZheng Liu return ext2fs_free_mem(&data.ea_data); 118133e94627b01823d2555450ddd1d95401ff2227aZheng Liu} 119416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 120416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liuint ext2fs_inline_data_dir_iterate(ext2_filsys fs, ext2_ino_t ino, 121416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu void *priv_data) 122416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu{ 123416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu struct dir_context *ctx; 124416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu struct ext2_inode inode; 125416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu struct ext2_dir_entry dirent; 126416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu struct ext2_inline_data data; 127416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu int ret = BLOCK_ABORT; 128416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu e2_blkcnt_t blockcnt = 0; 1298f22fa055bdf9dbe0dc8a5de440ed57eb706e098Darrick J. Wong char *old_buf; 1308f22fa055bdf9dbe0dc8a5de440ed57eb706e098Darrick J. Wong unsigned int old_buflen; 1318f22fa055bdf9dbe0dc8a5de440ed57eb706e098Darrick J. Wong int old_flags; 132416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 133416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ctx = (struct dir_context *)priv_data; 1348f22fa055bdf9dbe0dc8a5de440ed57eb706e098Darrick J. Wong old_buf = ctx->buf; 1358f22fa055bdf9dbe0dc8a5de440ed57eb706e098Darrick J. Wong old_buflen = ctx->buflen; 1368f22fa055bdf9dbe0dc8a5de440ed57eb706e098Darrick J. Wong old_flags = ctx->flags; 1378f22fa055bdf9dbe0dc8a5de440ed57eb706e098Darrick J. Wong ctx->flags |= DIRENT_FLAG_INCLUDE_INLINE_DATA; 138416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 139416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ctx->errcode = ext2fs_read_inode(fs, ino, &inode); 140416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (ctx->errcode) 141416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu goto out; 142416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 143416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (!(inode.i_flags & EXT4_INLINE_DATA_FL)) { 144416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ctx->errcode = EXT2_ET_NO_INLINE_DATA; 145416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu goto out; 146416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu } 147416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 148416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (!LINUX_S_ISDIR(inode.i_mode)) { 149416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ctx->errcode = EXT2_ET_NO_DIRECTORY; 150416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu goto out; 151416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu } 152416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ret = 0; 153416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 154416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu /* we first check '.' and '..' dir */ 155416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu dirent.inode = ino; 156416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu dirent.name_len = 1; 157416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ext2fs_set_rec_len(fs, EXT2_DIR_REC_LEN(2), &dirent); 158416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu dirent.name[0] = '.'; 159416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu dirent.name[1] = '\0'; 160416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ctx->buf = (char *)&dirent; 161416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ext2fs_get_rec_len(fs, &dirent, &ctx->buflen); 162416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ret |= ext2fs_process_dir_block(fs, 0, blockcnt++, 0, 0, priv_data); 163416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (ret & BLOCK_ABORT) 164416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu goto out; 165416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 166416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu dirent.inode = ext2fs_le32_to_cpu(inode.i_block[0]); 167416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu dirent.name_len = 2; 168416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ext2fs_set_rec_len(fs, EXT2_DIR_REC_LEN(3), &dirent); 169416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu dirent.name[0] = '.'; 170416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu dirent.name[1] = '.'; 171416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu dirent.name[2] = '\0'; 172416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ctx->buf = (char *)&dirent; 173416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ext2fs_get_rec_len(fs, &dirent, &ctx->buflen); 174416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ret |= ext2fs_process_dir_block(fs, 0, blockcnt++, 0, 0, priv_data); 175416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (ret & BLOCK_INLINE_DATA_CHANGED) { 176416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu errcode_t err; 177416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 178416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu inode.i_block[0] = ext2fs_cpu_to_le32(dirent.inode); 179416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu err = ext2fs_write_inode(fs, ino, &inode); 180416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (err) 181416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu goto out; 182416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ret &= ~BLOCK_INLINE_DATA_CHANGED; 183416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu } 184416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (ret & BLOCK_ABORT) 185416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu goto out; 186416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 187416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ctx->buf = (char *)inode.i_block + EXT4_INLINE_DATA_DOTDOT_SIZE; 188416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ctx->buflen = EXT4_MIN_INLINE_DATA_SIZE - EXT4_INLINE_DATA_DOTDOT_SIZE; 189416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu#ifdef WORDS_BIGENDIAN 190416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ctx->errcode = ext2fs_dirent_swab_in2(fs, ctx->buf, ctx->buflen, 0); 191416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (ctx->errcode) { 192416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ret |= BLOCK_ABORT; 193416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu goto out; 194416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu } 195416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu#endif 196416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ret |= ext2fs_process_dir_block(fs, 0, blockcnt++, 0, 0, priv_data); 197416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (ret & BLOCK_INLINE_DATA_CHANGED) { 198416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu#ifdef WORDS_BIGENDIAN 199416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ctx->errcode = ext2fs_dirent_swab_out2(fs, ctx->buf, 200416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ctx->buflen, 0); 201416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (ctx->errcode) { 202416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ret |= BLOCK_ABORT; 203416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu goto out; 204416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu } 205416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu#endif 206416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ctx->errcode = ext2fs_write_inode(fs, ino, &inode); 207416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (ctx->errcode) 208416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ret |= BLOCK_ABORT; 209416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ret &= ~BLOCK_INLINE_DATA_CHANGED; 210416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu } 211416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (ret & BLOCK_ABORT) 212416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu goto out; 213416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 214416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu data.fs = fs; 215416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu data.ino = ino; 216416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ctx->errcode = ext2fs_inline_data_ea_get(&data); 217416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (ctx->errcode) { 218416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ret |= BLOCK_ABORT; 219416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu goto out; 220416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu } 221416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (data.ea_size <= 0) 222657f508cbf4c2ff180ea086bd7041125ec4e5b61Darrick J. Wong goto out1; 223416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 224416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ctx->buf = data.ea_data; 225416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ctx->buflen = data.ea_size; 226416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu#ifdef WORDS_BIGENDIAN 227251edc3d3b6fd3b8c2d93dd247e21a03705e4a6bEryu Guan ctx->errcode = ext2fs_dirent_swab_in2(fs, ctx->buf, ctx->buflen, 0); 228251edc3d3b6fd3b8c2d93dd247e21a03705e4a6bEryu Guan if (ctx->errcode) { 229416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ret |= BLOCK_ABORT; 230657f508cbf4c2ff180ea086bd7041125ec4e5b61Darrick J. Wong goto out1; 231416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu } 232416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu#endif 233416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 234416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ret |= ext2fs_process_dir_block(fs, 0, blockcnt++, 0, 0, priv_data); 235416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (ret & BLOCK_INLINE_DATA_CHANGED) { 236416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu#ifdef WORDS_BIGENDIAN 237416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ctx->errcode = ext2fs_dirent_swab_out2(fs, ctx->buf, 238416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ctx->buflen, 0); 239416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (ctx->errcode) { 240416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ret |= BLOCK_ABORT; 241416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu goto out1; 242416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu } 243416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu#endif 244416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ctx->errcode = ext2fs_inline_data_ea_set(&data); 245416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu if (ctx->errcode) 246416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ret |= BLOCK_ABORT; 247416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu } 248416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu 249416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liuout1: 250416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ext2fs_free_mem(&data.ea_data); 251416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liuout: 2528f22fa055bdf9dbe0dc8a5de440ed57eb706e098Darrick J. Wong ctx->buf = old_buf; 2538f22fa055bdf9dbe0dc8a5de440ed57eb706e098Darrick J. Wong ctx->buflen = old_buflen; 2548f22fa055bdf9dbe0dc8a5de440ed57eb706e098Darrick J. Wong ctx->flags = old_flags; 255416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu ret &= ~(BLOCK_ABORT | BLOCK_INLINE_DATA_CHANGED); 256416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu return ret; 257416c1de94ddf7199aedaf7b039292a36b92699fbZheng Liu} 25846bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 25997581d448127f95dcc968c0785f7ab3413bf0222Zheng Liuerrcode_t ext2fs_inline_data_ea_remove(ext2_filsys fs, ext2_ino_t ino) 26046bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu{ 26146bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu struct ext2_xattr_handle *handle; 26246bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu errcode_t retval; 26346bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 26446bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu retval = ext2fs_xattrs_open(fs, ino, &handle); 26546bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu if (retval) 26646bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu return retval; 26746bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 26846bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu retval = ext2fs_xattrs_read(handle); 26946bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu if (retval) 27046bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu goto err; 27146bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 27246bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu retval = ext2fs_xattr_remove(handle, "system.data"); 27346bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu if (retval) 27446bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu goto err; 27546bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 27646bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu retval = ext2fs_xattrs_write(handle); 27746bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 27846bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liuerr: 27946bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu (void) ext2fs_xattrs_close(&handle); 28046bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu return retval; 28146bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu} 28246bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 28346bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liustatic errcode_t ext2fs_inline_data_convert_dir(ext2_filsys fs, ext2_ino_t ino, 28446bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu char *bbuf, char *ibuf, int size) 28546bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu{ 28646bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu struct ext2_dir_entry *dir, *dir2; 28746bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu struct ext2_dir_entry_tail *t; 28846bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu errcode_t retval; 2898f8511aba07c47df779be94eeb5970f2b73000d8Theodore Ts'o int offset; 2908f8511aba07c47df779be94eeb5970f2b73000d8Theodore Ts'o unsigned int rec_len; 29146bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu int csum_size = 0; 29246bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu int filetype = 0; 29346bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 29477b3e9871877fce9908b0696250787fd6ea61af9Darrick J. Wong if (ext2fs_has_feature_metadata_csum(fs->super)) 29546bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu csum_size = sizeof(struct ext2_dir_entry_tail); 29646bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 29746bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu /* Create '.' and '..' */ 29877b3e9871877fce9908b0696250787fd6ea61af9Darrick J. Wong if (ext2fs_has_feature_filetype(fs->super)) 29946bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu filetype = EXT2_FT_DIR; 30046bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 30146bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu /* 30246bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu * Set up entry for '.' 30346bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu */ 30446bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu dir = (struct ext2_dir_entry *) bbuf; 30546bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu dir->inode = ino; 30646bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu ext2fs_dirent_set_name_len(dir, 1); 30746bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu ext2fs_dirent_set_file_type(dir, filetype); 30846bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu dir->name[0] = '.'; 30946bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu rec_len = (fs->blocksize - csum_size) - EXT2_DIR_REC_LEN(1); 31046bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu dir->rec_len = EXT2_DIR_REC_LEN(1); 31146bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 31246bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu /* 31346bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu * Set up entry for '..' 31446bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu */ 31546bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu dir = (struct ext2_dir_entry *) (bbuf + dir->rec_len); 31646bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu dir->rec_len = EXT2_DIR_REC_LEN(2); 31746bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu dir->inode = ext2fs_le32_to_cpu(((__u32 *)ibuf)[0]); 31846bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu ext2fs_dirent_set_name_len(dir, 2); 31946bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu ext2fs_dirent_set_file_type(dir, filetype); 32046bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu dir->name[0] = '.'; 32146bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu dir->name[1] = '.'; 32246bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 32346bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu /* 32446bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu * Ajust the last rec_len 32546bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu */ 32646bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu offset = EXT2_DIR_REC_LEN(1) + EXT2_DIR_REC_LEN(2); 32746bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu dir = (struct ext2_dir_entry *) (bbuf + offset); 32846bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu memcpy(bbuf + offset, ibuf + EXT4_INLINE_DATA_DOTDOT_SIZE, 32946bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu size - EXT4_INLINE_DATA_DOTDOT_SIZE); 33046bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu size += EXT2_DIR_REC_LEN(1) + EXT2_DIR_REC_LEN(2) - 33146bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu EXT4_INLINE_DATA_DOTDOT_SIZE; 33246bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 33346bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu do { 33446bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu dir2 = dir; 33546bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu retval = ext2fs_get_rec_len(fs, dir, &rec_len); 33646bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu if (retval) 33746bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu goto err; 33846bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu offset += rec_len; 33946bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu dir = (struct ext2_dir_entry *) (bbuf + offset); 34046bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu } while (offset < size); 34146bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu rec_len += fs->blocksize - csum_size - offset; 34246bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu retval = ext2fs_set_rec_len(fs, rec_len, dir2); 34346bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu if (retval) 34446bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu goto err; 34546bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 34646bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu if (csum_size) { 34746bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu t = EXT2_DIRENT_TAIL(bbuf, fs->blocksize); 34846bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu ext2fs_initialize_dirent_tail(fs, t); 34946bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu } 35046bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 35146bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liuerr: 35246bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu return retval; 35346bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu} 35446bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 35554e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liustatic errcode_t 35654e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liuext2fs_inline_data_dir_expand(ext2_filsys fs, ext2_ino_t ino, 35754e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu struct ext2_inode *inode, char *buf, size_t size) 35854e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu{ 35954e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu errcode_t retval; 36054e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu blk64_t blk; 36154e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu char *blk_buf; 36254e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 36354e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu retval = ext2fs_get_memzero(fs->blocksize, &blk_buf); 36454e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (retval) 36554e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu return retval; 36654e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 36754e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu#ifdef WORDS_BIGENDIAN 368cd971869d77a9899db326d2ed42e1ef2916ba29fDarrick J. Wong retval = ext2fs_dirent_swab_in2(fs, buf + EXT4_INLINE_DATA_DOTDOT_SIZE, 369cd971869d77a9899db326d2ed42e1ef2916ba29fDarrick J. Wong size, 0); 37054e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (retval) 37154e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu goto errout; 37254e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu#endif 37354e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 37454e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu /* Adjust the rec_len */ 37554e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu retval = ext2fs_inline_data_convert_dir(fs, ino, blk_buf, buf, size); 376cd971869d77a9899db326d2ed42e1ef2916ba29fDarrick J. Wong if (retval) 377cd971869d77a9899db326d2ed42e1ef2916ba29fDarrick J. Wong goto errout; 37854e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu /* Allocate a new block */ 37954e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu retval = ext2fs_new_block2(fs, 0, 0, &blk); 38054e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (retval) 38154e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu goto errout; 38254e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu retval = ext2fs_write_dir_block4(fs, blk, blk_buf, 0, ino); 38354e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (retval) 38454e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu goto errout; 38554e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 38654e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu /* Update inode */ 38777b3e9871877fce9908b0696250787fd6ea61af9Darrick J. Wong if (ext2fs_has_feature_extents(fs->super)) 38854e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu inode->i_flags |= EXT4_EXTENTS_FL; 38954e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu inode->i_flags &= ~EXT4_INLINE_DATA_FL; 39097bd89cd398108b05e33b676809b50348bf6abb2Darrick J. Wong retval = ext2fs_iblk_add_blocks(fs, inode, 1); 39197bd89cd398108b05e33b676809b50348bf6abb2Darrick J. Wong if (retval) 39297bd89cd398108b05e33b676809b50348bf6abb2Darrick J. Wong goto errout; 39354e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu inode->i_size = fs->blocksize; 39454e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu retval = ext2fs_bmap2(fs, ino, inode, 0, BMAP_SET, 0, 0, &blk); 39554e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (retval) 39654e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu goto errout; 39754e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu retval = ext2fs_write_inode(fs, ino, inode); 39854e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (retval) 39954e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu goto errout; 40054e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu ext2fs_block_alloc_stats(fs, blk, +1); 40154e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 40254e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liuerrout: 40354e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu ext2fs_free_mem(&blk_buf); 40454e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu return retval; 40554e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu} 40654e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 40754e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liustatic errcode_t 40854e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liuext2fs_inline_data_file_expand(ext2_filsys fs, ext2_ino_t ino, 40954e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu struct ext2_inode *inode, char *buf, size_t size) 41054e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu{ 41154e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu ext2_file_t e2_file; 41254e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu errcode_t retval; 41354e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 41454e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu /* Update inode */ 4153548bb64b5690608720120b56beeafaecc68d68bDarrick J. Wong memset(inode->i_block, 0, sizeof(inode->i_block)); 41677b3e9871877fce9908b0696250787fd6ea61af9Darrick J. Wong if (ext2fs_has_feature_extents(fs->super)) { 4173548bb64b5690608720120b56beeafaecc68d68bDarrick J. Wong ext2_extent_handle_t handle; 4183548bb64b5690608720120b56beeafaecc68d68bDarrick J. Wong 4193548bb64b5690608720120b56beeafaecc68d68bDarrick J. Wong inode->i_flags &= ~EXT4_EXTENTS_FL; 4203548bb64b5690608720120b56beeafaecc68d68bDarrick J. Wong retval = ext2fs_extent_open2(fs, ino, inode, &handle); 4213548bb64b5690608720120b56beeafaecc68d68bDarrick J. Wong if (retval) 4223548bb64b5690608720120b56beeafaecc68d68bDarrick J. Wong return retval; 4233548bb64b5690608720120b56beeafaecc68d68bDarrick J. Wong ext2fs_extent_free(handle); 42454e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu } 42554e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu inode->i_flags &= ~EXT4_INLINE_DATA_FL; 42654e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu inode->i_size = 0; 42754e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu retval = ext2fs_write_inode(fs, ino, inode); 42854e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (retval) 42954e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu return retval; 43054e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 43154e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu /* Write out the block buffer */ 43254e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu retval = ext2fs_file_open(fs, ino, EXT2_FILE_WRITE, &e2_file); 43354e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (retval) 43454e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu return retval; 43554e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu retval = ext2fs_file_write(e2_file, buf, size, 0); 43654e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu ext2fs_file_close(e2_file); 43754e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu return retval; 43854e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu} 43954e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 44046bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liuerrcode_t ext2fs_inline_data_expand(ext2_filsys fs, ext2_ino_t ino) 44146bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu{ 44246bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu struct ext2_inode inode; 44346bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu struct ext2_inline_data data; 44446bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu errcode_t retval; 44554e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu size_t inline_size; 44646bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu char *inline_buf = 0; 44746bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 44846bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); 44946bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 45046bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu retval = ext2fs_read_inode(fs, ino, &inode); 45146bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu if (retval) 45246bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu return retval; 45346bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 45446bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu if (!(inode.i_flags & EXT4_INLINE_DATA_FL)) 45546bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu return EXT2_ET_NO_INLINE_DATA; 45646bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 45746bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu data.fs = fs; 45846bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu data.ino = ino; 45946bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu retval = ext2fs_inline_data_ea_get(&data); 46046bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu if (retval) 46146bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu return retval; 46254e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu inline_size = data.ea_size + EXT4_MIN_INLINE_DATA_SIZE; 46354e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu retval = ext2fs_get_mem(inline_size, &inline_buf); 46446bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu if (retval) 46546bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu goto errout; 46646bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 46746bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu memcpy(inline_buf, (void *)inode.i_block, EXT4_MIN_INLINE_DATA_SIZE); 46846bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu if (data.ea_size > 0) { 46946bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu memcpy(inline_buf + EXT4_MIN_INLINE_DATA_SIZE, 47046bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu data.ea_data, data.ea_size); 47146bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu } 47246bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 47346bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu memset((void *)inode.i_block, 0, EXT4_MIN_INLINE_DATA_SIZE); 474179e3bd708251048980c845d0080de1ce79ef21aDarrick J. Wong /* 475179e3bd708251048980c845d0080de1ce79ef21aDarrick J. Wong * NOTE: We must do this write -> ea_remove -> read cycle here because 476179e3bd708251048980c845d0080de1ce79ef21aDarrick J. Wong * removing the inline data EA can free the EA block, which is a change 477179e3bd708251048980c845d0080de1ce79ef21aDarrick J. Wong * that our stack copy of the inode will never see. If that happens, 478179e3bd708251048980c845d0080de1ce79ef21aDarrick J. Wong * we can end up with the EA block and lblk 0 pointing to the same 479179e3bd708251048980c845d0080de1ce79ef21aDarrick J. Wong * pblk, which is bad news. 480179e3bd708251048980c845d0080de1ce79ef21aDarrick J. Wong */ 481179e3bd708251048980c845d0080de1ce79ef21aDarrick J. Wong retval = ext2fs_write_inode(fs, ino, &inode); 482179e3bd708251048980c845d0080de1ce79ef21aDarrick J. Wong if (retval) 483179e3bd708251048980c845d0080de1ce79ef21aDarrick J. Wong goto errout; 48446bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu retval = ext2fs_inline_data_ea_remove(fs, ino); 48546bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu if (retval) 48646bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu goto errout; 487179e3bd708251048980c845d0080de1ce79ef21aDarrick J. Wong retval = ext2fs_read_inode(fs, ino, &inode); 488179e3bd708251048980c845d0080de1ce79ef21aDarrick J. Wong if (retval) 489179e3bd708251048980c845d0080de1ce79ef21aDarrick J. Wong goto errout; 49046bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 49154e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (LINUX_S_ISDIR(inode.i_mode)) { 49254e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu retval = ext2fs_inline_data_dir_expand(fs, ino, &inode, 49354e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu inline_buf, inline_size); 49454e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu } else { 49554e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu retval = ext2fs_inline_data_file_expand(fs, ino, &inode, 49654e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu inline_buf, inline_size); 49754e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu } 49846bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu 49946bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liuerrout: 50046bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu if (inline_buf) 50146bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu ext2fs_free_mem(&inline_buf); 50246bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu ext2fs_free_mem(&data.ea_data); 50346bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu return retval; 50446bd6bdfc8c2e79336267f639b7963bea4487c42Zheng Liu} 50554e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 50654e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu/* 50754e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu * When caller uses this function to retrieve the inline data, it must 50854e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu * allocate a buffer which has the size of inline data. The size of 50954e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu * inline data can be know by ext2fs_inline_data_get_size(). 51054e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu */ 51154e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liuerrcode_t ext2fs_inline_data_get(ext2_filsys fs, ext2_ino_t ino, 51254e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu struct ext2_inode *inode, 51354e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu void *buf, size_t *size) 51454e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu{ 51554e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu struct ext2_inode inode_buf; 51654e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu struct ext2_inline_data data; 51754e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu errcode_t retval; 51854e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 51954e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (!inode) { 52054e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu retval = ext2fs_read_inode(fs, ino, &inode_buf); 52154e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (retval) 52254e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu return retval; 52354e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu inode = &inode_buf; 52454e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu } 52554e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 52654e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu data.fs = fs; 52754e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu data.ino = ino; 52854e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu retval = ext2fs_inline_data_ea_get(&data); 52954e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (retval) 53054e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu return retval; 53154e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 53254e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu memcpy(buf, (void *)inode->i_block, EXT4_MIN_INLINE_DATA_SIZE); 53354e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (data.ea_size > 0) 5348f8511aba07c47df779be94eeb5970f2b73000d8Theodore Ts'o memcpy((char *) buf + EXT4_MIN_INLINE_DATA_SIZE, 53554e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu data.ea_data, data.ea_size); 53654e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 53754e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (size) 53854e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu *size = EXT4_MIN_INLINE_DATA_SIZE + data.ea_size; 53954e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu ext2fs_free_mem(&data.ea_data); 54054e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu return 0; 54154e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu} 54254e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 54354e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liuerrcode_t ext2fs_inline_data_set(ext2_filsys fs, ext2_ino_t ino, 54454e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu struct ext2_inode *inode, 54554e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu void *buf, size_t size) 54654e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu{ 54754e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu struct ext2_inode inode_buf; 54854e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu struct ext2_inline_data data; 54954e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu errcode_t retval; 550cb803fc2caa45fe40f326dcf51f525a56e8af01bDarrick J. Wong size_t free_ea_size, existing_size, free_inode_size; 55154e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 55254e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (!inode) { 55354e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu retval = ext2fs_read_inode(fs, ino, &inode_buf); 55454e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (retval) 55554e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu return retval; 55654e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu inode = &inode_buf; 55754e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu } 55854e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 55954e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (size <= EXT4_MIN_INLINE_DATA_SIZE) { 560996999a1a45e1d36ff0e24925ee02fca87ad8283Darrick J. Wong retval = ext2fs_inline_data_ea_remove(fs, ino); 561996999a1a45e1d36ff0e24925ee02fca87ad8283Darrick J. Wong if (retval) 562996999a1a45e1d36ff0e24925ee02fca87ad8283Darrick J. Wong return retval; 56354e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu memcpy((void *)inode->i_block, buf, size); 56454e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu return ext2fs_write_inode(fs, ino, inode); 56554e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu } 56654e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 567cb803fc2caa45fe40f326dcf51f525a56e8af01bDarrick J. Wong retval = ext2fs_xattr_inode_max_size(fs, ino, &free_ea_size); 56854e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (retval) 56954e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu return retval; 57054e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 571cb803fc2caa45fe40f326dcf51f525a56e8af01bDarrick J. Wong retval = ext2fs_inline_data_size(fs, ino, &existing_size); 572cb803fc2caa45fe40f326dcf51f525a56e8af01bDarrick J. Wong if (retval) 573cb803fc2caa45fe40f326dcf51f525a56e8af01bDarrick J. Wong return retval; 574cb803fc2caa45fe40f326dcf51f525a56e8af01bDarrick J. Wong 575cb803fc2caa45fe40f326dcf51f525a56e8af01bDarrick J. Wong if (existing_size < EXT4_MIN_INLINE_DATA_SIZE) 576cb803fc2caa45fe40f326dcf51f525a56e8af01bDarrick J. Wong free_inode_size = EXT4_MIN_INLINE_DATA_SIZE - existing_size; 577cb803fc2caa45fe40f326dcf51f525a56e8af01bDarrick J. Wong else 578cb803fc2caa45fe40f326dcf51f525a56e8af01bDarrick J. Wong free_inode_size = 0; 579cb803fc2caa45fe40f326dcf51f525a56e8af01bDarrick J. Wong 580cffe0221eb53c2de739f483aeb368684206ad4a8Darrick J. Wong if (size != existing_size && 581cffe0221eb53c2de739f483aeb368684206ad4a8Darrick J. Wong size > existing_size + free_ea_size + free_inode_size) 58254e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu return EXT2_ET_INLINE_DATA_NO_SPACE; 58354e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu 58454e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu memcpy((void *)inode->i_block, buf, EXT4_MIN_INLINE_DATA_SIZE); 58554e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu retval = ext2fs_write_inode(fs, ino, inode); 58654e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu if (retval) 58754e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu return retval; 58854e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu data.fs = fs; 58954e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu data.ino = ino; 59054e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu data.ea_size = size - EXT4_MIN_INLINE_DATA_SIZE; 5918f8511aba07c47df779be94eeb5970f2b73000d8Theodore Ts'o data.ea_data = (char *) buf + EXT4_MIN_INLINE_DATA_SIZE; 59254e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu return ext2fs_inline_data_ea_set(&data); 59354e880b870f7fe98a6ea23013c18e2a71e28c01cZheng Liu} 59431253488385a62e4db53cad04f55188a2861b4bbZheng Liu 59531253488385a62e4db53cad04f55188a2861b4bbZheng Liu#ifdef DEBUG 59631253488385a62e4db53cad04f55188a2861b4bbZheng Liu#include "e2p/e2p.h" 59731253488385a62e4db53cad04f55188a2861b4bbZheng Liu 59831253488385a62e4db53cad04f55188a2861b4bbZheng Liu/* 59931253488385a62e4db53cad04f55188a2861b4bbZheng Liu * The length of buffer is set to 64 because in inode's i_block member it only 60031253488385a62e4db53cad04f55188a2861b4bbZheng Liu * can save 60 bytes. Thus this value can let the data being saved in extra 60131253488385a62e4db53cad04f55188a2861b4bbZheng Liu * space. 60231253488385a62e4db53cad04f55188a2861b4bbZheng Liu */ 60331253488385a62e4db53cad04f55188a2861b4bbZheng Liu#define BUFF_SIZE (64) 60431253488385a62e4db53cad04f55188a2861b4bbZheng Liu 60531253488385a62e4db53cad04f55188a2861b4bbZheng Liustatic errcode_t file_test(ext2_filsys fs) 60631253488385a62e4db53cad04f55188a2861b4bbZheng Liu{ 60731253488385a62e4db53cad04f55188a2861b4bbZheng Liu struct ext2_inode inode; 60831253488385a62e4db53cad04f55188a2861b4bbZheng Liu ext2_ino_t newfile; 60931253488385a62e4db53cad04f55188a2861b4bbZheng Liu errcode_t retval; 61031253488385a62e4db53cad04f55188a2861b4bbZheng Liu size_t size; 61131253488385a62e4db53cad04f55188a2861b4bbZheng Liu char *buf = 0, *cmpbuf = 0; 61231253488385a62e4db53cad04f55188a2861b4bbZheng Liu 61331253488385a62e4db53cad04f55188a2861b4bbZheng Liu /* create a new file */ 61431253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = ext2fs_new_inode(fs, 2, 010755, 0, &newfile); 61531253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (retval) { 61631253488385a62e4db53cad04f55188a2861b4bbZheng Liu com_err("file_test", retval, "while allocaing a new inode"); 61731253488385a62e4db53cad04f55188a2861b4bbZheng Liu return 1; 61831253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 61931253488385a62e4db53cad04f55188a2861b4bbZheng Liu 62031253488385a62e4db53cad04f55188a2861b4bbZheng Liu memset(&inode, 0, sizeof(inode)); 62131253488385a62e4db53cad04f55188a2861b4bbZheng Liu inode.i_flags |= EXT4_INLINE_DATA_FL; 62231253488385a62e4db53cad04f55188a2861b4bbZheng Liu inode.i_size = EXT4_MIN_INLINE_DATA_SIZE; 62331253488385a62e4db53cad04f55188a2861b4bbZheng Liu inode.i_mode = LINUX_S_IFREG; 62431253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = ext2fs_write_new_inode(fs, newfile, &inode); 62531253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (retval) { 62631253488385a62e4db53cad04f55188a2861b4bbZheng Liu com_err("file_test", retval, "while writting a new inode"); 62731253488385a62e4db53cad04f55188a2861b4bbZheng Liu return 1; 62831253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 62931253488385a62e4db53cad04f55188a2861b4bbZheng Liu 63031253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = ext2fs_inline_data_init(fs, newfile); 63131253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (retval) { 63231253488385a62e4db53cad04f55188a2861b4bbZheng Liu com_err("file_test", retval, "while init 'system.data'"); 63331253488385a62e4db53cad04f55188a2861b4bbZheng Liu return 1; 63431253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 63531253488385a62e4db53cad04f55188a2861b4bbZheng Liu 63631253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = ext2fs_inline_data_size(fs, newfile, &size); 63731253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (retval) { 63831253488385a62e4db53cad04f55188a2861b4bbZheng Liu com_err("file_test", retval, "while getting size"); 63931253488385a62e4db53cad04f55188a2861b4bbZheng Liu return 1; 64031253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 64131253488385a62e4db53cad04f55188a2861b4bbZheng Liu 64231253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (size != EXT4_MIN_INLINE_DATA_SIZE) { 64331253488385a62e4db53cad04f55188a2861b4bbZheng Liu fprintf(stderr, 64431253488385a62e4db53cad04f55188a2861b4bbZheng Liu "tst_inline_data: size of inline data is wrong\n"); 64531253488385a62e4db53cad04f55188a2861b4bbZheng Liu return 1; 64631253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 64731253488385a62e4db53cad04f55188a2861b4bbZheng Liu 64831253488385a62e4db53cad04f55188a2861b4bbZheng Liu ext2fs_get_mem(BUFF_SIZE, &buf); 64931253488385a62e4db53cad04f55188a2861b4bbZheng Liu memset(buf, 'a', BUFF_SIZE); 65031253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = ext2fs_inline_data_set(fs, newfile, 0, buf, BUFF_SIZE); 65131253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (retval) { 65231253488385a62e4db53cad04f55188a2861b4bbZheng Liu com_err("file_test", retval, 65331253488385a62e4db53cad04f55188a2861b4bbZheng Liu "while setting inline data %s", buf); 65431253488385a62e4db53cad04f55188a2861b4bbZheng Liu goto err; 65531253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 65631253488385a62e4db53cad04f55188a2861b4bbZheng Liu 65731253488385a62e4db53cad04f55188a2861b4bbZheng Liu ext2fs_get_mem(BUFF_SIZE, &cmpbuf); 65831253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = ext2fs_inline_data_get(fs, newfile, 0, cmpbuf, &size); 65931253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (retval) { 66031253488385a62e4db53cad04f55188a2861b4bbZheng Liu com_err("file_test", retval, "while getting inline data"); 66131253488385a62e4db53cad04f55188a2861b4bbZheng Liu goto err; 66231253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 66331253488385a62e4db53cad04f55188a2861b4bbZheng Liu 66431253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (size != BUFF_SIZE) { 66531253488385a62e4db53cad04f55188a2861b4bbZheng Liu fprintf(stderr, 666bbccc6f3c6a106721fb6f1ef4df6bc32c7986235Andreas Dilger "tst_inline_data: size %lu != buflen %u\n", 66731253488385a62e4db53cad04f55188a2861b4bbZheng Liu size, BUFF_SIZE); 66831253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = 1; 66931253488385a62e4db53cad04f55188a2861b4bbZheng Liu goto err; 67031253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 67131253488385a62e4db53cad04f55188a2861b4bbZheng Liu 67231253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (memcmp(buf, cmpbuf, BUFF_SIZE)) { 67331253488385a62e4db53cad04f55188a2861b4bbZheng Liu fprintf(stderr, "tst_inline_data: buf != cmpbuf\n"); 67431253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = 1; 67531253488385a62e4db53cad04f55188a2861b4bbZheng Liu goto err; 67631253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 67731253488385a62e4db53cad04f55188a2861b4bbZheng Liu 67831253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = ext2fs_punch(fs, newfile, 0, 0, 0, ~0ULL); 67931253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (retval) { 68031253488385a62e4db53cad04f55188a2861b4bbZheng Liu com_err("file_test", retval, "while truncating inode"); 68131253488385a62e4db53cad04f55188a2861b4bbZheng Liu goto err; 68231253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 68331253488385a62e4db53cad04f55188a2861b4bbZheng Liu 68431253488385a62e4db53cad04f55188a2861b4bbZheng Liu /* reload inode and check isize */ 68531253488385a62e4db53cad04f55188a2861b4bbZheng Liu ext2fs_read_inode(fs, newfile, &inode); 68631253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (inode.i_size != 0) { 68731253488385a62e4db53cad04f55188a2861b4bbZheng Liu fprintf(stderr, "tst_inline_data: i_size should be 0\n"); 68831253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = 1; 68931253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 69031253488385a62e4db53cad04f55188a2861b4bbZheng Liu 69131253488385a62e4db53cad04f55188a2861b4bbZheng Liuerr: 69231253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (cmpbuf) 69331253488385a62e4db53cad04f55188a2861b4bbZheng Liu ext2fs_free_mem(&cmpbuf); 69431253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (buf) 69531253488385a62e4db53cad04f55188a2861b4bbZheng Liu ext2fs_free_mem(&buf); 69631253488385a62e4db53cad04f55188a2861b4bbZheng Liu return retval; 69731253488385a62e4db53cad04f55188a2861b4bbZheng Liu} 69831253488385a62e4db53cad04f55188a2861b4bbZheng Liu 69931253488385a62e4db53cad04f55188a2861b4bbZheng Liustatic errcode_t dir_test(ext2_filsys fs) 70031253488385a62e4db53cad04f55188a2861b4bbZheng Liu{ 70131253488385a62e4db53cad04f55188a2861b4bbZheng Liu const char *dot_name = "."; 70231253488385a62e4db53cad04f55188a2861b4bbZheng Liu const char *stub_name = "stub"; 70331253488385a62e4db53cad04f55188a2861b4bbZheng Liu const char *parent_name = "test"; 70431253488385a62e4db53cad04f55188a2861b4bbZheng Liu ext2_ino_t parent, dir, tmp; 70531253488385a62e4db53cad04f55188a2861b4bbZheng Liu errcode_t retval; 70631253488385a62e4db53cad04f55188a2861b4bbZheng Liu char dirname[PATH_MAX]; 70731253488385a62e4db53cad04f55188a2861b4bbZheng Liu int i; 70831253488385a62e4db53cad04f55188a2861b4bbZheng Liu 70931253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = ext2fs_mkdir(fs, 11, 11, stub_name); 71031253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (retval) { 71131253488385a62e4db53cad04f55188a2861b4bbZheng Liu com_err("dir_test", retval, "while creating %s dir", stub_name); 71231253488385a62e4db53cad04f55188a2861b4bbZheng Liu return retval; 71331253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 71431253488385a62e4db53cad04f55188a2861b4bbZheng Liu 71531253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = ext2fs_mkdir(fs, 11, 0, parent_name); 71631253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (retval) { 71731253488385a62e4db53cad04f55188a2861b4bbZheng Liu com_err("dir_test", retval, 71831253488385a62e4db53cad04f55188a2861b4bbZheng Liu "while creating %s dir", parent_name); 71931253488385a62e4db53cad04f55188a2861b4bbZheng Liu return retval; 72031253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 72131253488385a62e4db53cad04f55188a2861b4bbZheng Liu 72231253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = ext2fs_lookup(fs, 11, parent_name, strlen(parent_name), 72331253488385a62e4db53cad04f55188a2861b4bbZheng Liu 0, &parent); 72431253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (retval) { 72531253488385a62e4db53cad04f55188a2861b4bbZheng Liu com_err("dir_test", retval, 72631253488385a62e4db53cad04f55188a2861b4bbZheng Liu "while looking up %s dir", parent_name); 72731253488385a62e4db53cad04f55188a2861b4bbZheng Liu return retval; 72831253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 72931253488385a62e4db53cad04f55188a2861b4bbZheng Liu 73031253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = ext2fs_lookup(fs, parent, dot_name, strlen(dot_name), 73131253488385a62e4db53cad04f55188a2861b4bbZheng Liu 0, &tmp); 73231253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (retval) { 73331253488385a62e4db53cad04f55188a2861b4bbZheng Liu com_err("dir_test", retval, 73431253488385a62e4db53cad04f55188a2861b4bbZheng Liu "while looking up %s dir", parent_name); 73531253488385a62e4db53cad04f55188a2861b4bbZheng Liu return retval; 73631253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 73731253488385a62e4db53cad04f55188a2861b4bbZheng Liu 73831253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (parent != tmp) { 739bbccc6f3c6a106721fb6f1ef4df6bc32c7986235Andreas Dilger fprintf(stderr, "tst_inline_data: parent (%u) != tmp (%u)\n", 74031253488385a62e4db53cad04f55188a2861b4bbZheng Liu parent, tmp); 74131253488385a62e4db53cad04f55188a2861b4bbZheng Liu return 1; 74231253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 74331253488385a62e4db53cad04f55188a2861b4bbZheng Liu 74431253488385a62e4db53cad04f55188a2861b4bbZheng Liu for (i = 0, dir = 13; i < 4; i++, dir++) { 74531253488385a62e4db53cad04f55188a2861b4bbZheng Liu tmp = 0; 746bbccc6f3c6a106721fb6f1ef4df6bc32c7986235Andreas Dilger snprintf(dirname, sizeof(dirname), "%d", i); 74731253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = ext2fs_mkdir(fs, parent, 0, dirname); 74831253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (retval) { 74931253488385a62e4db53cad04f55188a2861b4bbZheng Liu com_err("dir_test", retval, 75031253488385a62e4db53cad04f55188a2861b4bbZheng Liu "while creating %s dir", dirname); 75131253488385a62e4db53cad04f55188a2861b4bbZheng Liu return retval; 75231253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 75331253488385a62e4db53cad04f55188a2861b4bbZheng Liu 75431253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = ext2fs_lookup(fs, parent, dirname, strlen(dirname), 75531253488385a62e4db53cad04f55188a2861b4bbZheng Liu 0, &tmp); 75631253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (retval) { 75731253488385a62e4db53cad04f55188a2861b4bbZheng Liu com_err("dir_test", retval, 75831253488385a62e4db53cad04f55188a2861b4bbZheng Liu "while looking up %s dir", parent_name); 75931253488385a62e4db53cad04f55188a2861b4bbZheng Liu return retval; 76031253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 76131253488385a62e4db53cad04f55188a2861b4bbZheng Liu 76231253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (dir != tmp) { 763bbccc6f3c6a106721fb6f1ef4df6bc32c7986235Andreas Dilger fprintf(stderr, 764bbccc6f3c6a106721fb6f1ef4df6bc32c7986235Andreas Dilger "tst_inline_data: dir (%u) != tmp (%u)\n", 76531253488385a62e4db53cad04f55188a2861b4bbZheng Liu dir, tmp); 76631253488385a62e4db53cad04f55188a2861b4bbZheng Liu return 1; 76731253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 76831253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 76931253488385a62e4db53cad04f55188a2861b4bbZheng Liu 770bbccc6f3c6a106721fb6f1ef4df6bc32c7986235Andreas Dilger snprintf(dirname, sizeof(dirname), "%d", i); 77131253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = ext2fs_mkdir(fs, parent, 0, dirname); 77231253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (retval && retval != EXT2_ET_DIR_NO_SPACE) { 77331253488385a62e4db53cad04f55188a2861b4bbZheng Liu com_err("dir_test", retval, "while creating %s dir", dirname); 77431253488385a62e4db53cad04f55188a2861b4bbZheng Liu return retval; 77531253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 77631253488385a62e4db53cad04f55188a2861b4bbZheng Liu 77731253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = ext2fs_expand_dir(fs, parent); 77831253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (retval) { 77931253488385a62e4db53cad04f55188a2861b4bbZheng Liu com_err("dir_test", retval, "while expanding %s dir", parent_name); 78031253488385a62e4db53cad04f55188a2861b4bbZheng Liu return retval; 78131253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 78231253488385a62e4db53cad04f55188a2861b4bbZheng Liu 78331253488385a62e4db53cad04f55188a2861b4bbZheng Liu return 0; 78431253488385a62e4db53cad04f55188a2861b4bbZheng Liu} 78531253488385a62e4db53cad04f55188a2861b4bbZheng Liu 78631253488385a62e4db53cad04f55188a2861b4bbZheng Liuint main(int argc, char *argv[]) 78731253488385a62e4db53cad04f55188a2861b4bbZheng Liu{ 78831253488385a62e4db53cad04f55188a2861b4bbZheng Liu ext2_filsys fs; 78931253488385a62e4db53cad04f55188a2861b4bbZheng Liu struct ext2_super_block param; 79031253488385a62e4db53cad04f55188a2861b4bbZheng Liu errcode_t retval; 79131253488385a62e4db53cad04f55188a2861b4bbZheng Liu 79231253488385a62e4db53cad04f55188a2861b4bbZheng Liu /* setup */ 79331253488385a62e4db53cad04f55188a2861b4bbZheng Liu initialize_ext2_error_table(); 79431253488385a62e4db53cad04f55188a2861b4bbZheng Liu 79531253488385a62e4db53cad04f55188a2861b4bbZheng Liu memset(¶m, 0, sizeof(param)); 79631253488385a62e4db53cad04f55188a2861b4bbZheng Liu ext2fs_blocks_count_set(¶m, 32768); 79731253488385a62e4db53cad04f55188a2861b4bbZheng Liu param.s_inodes_count = 100; 79831253488385a62e4db53cad04f55188a2861b4bbZheng Liu 79931253488385a62e4db53cad04f55188a2861b4bbZheng Liu param.s_feature_incompat |= EXT4_FEATURE_INCOMPAT_INLINE_DATA; 80031253488385a62e4db53cad04f55188a2861b4bbZheng Liu param.s_rev_level = EXT2_DYNAMIC_REV; 80131253488385a62e4db53cad04f55188a2861b4bbZheng Liu param.s_inode_size = 256; 80231253488385a62e4db53cad04f55188a2861b4bbZheng Liu 80331253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = ext2fs_initialize("test fs", EXT2_FLAG_64BITS, ¶m, 80431253488385a62e4db53cad04f55188a2861b4bbZheng Liu test_io_manager, &fs); 80531253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (retval) { 80631253488385a62e4db53cad04f55188a2861b4bbZheng Liu com_err("setup", retval, 80731253488385a62e4db53cad04f55188a2861b4bbZheng Liu "while initializing filesystem"); 80831253488385a62e4db53cad04f55188a2861b4bbZheng Liu exit(1); 80931253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 81031253488385a62e4db53cad04f55188a2861b4bbZheng Liu 81131253488385a62e4db53cad04f55188a2861b4bbZheng Liu retval = ext2fs_allocate_tables(fs); 81231253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (retval) { 81331253488385a62e4db53cad04f55188a2861b4bbZheng Liu com_err("setup", retval, 81431253488385a62e4db53cad04f55188a2861b4bbZheng Liu "while allocating tables for test filesysmte"); 81531253488385a62e4db53cad04f55188a2861b4bbZheng Liu exit(1); 81631253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 81731253488385a62e4db53cad04f55188a2861b4bbZheng Liu 81831253488385a62e4db53cad04f55188a2861b4bbZheng Liu /* initialize inode cache */ 81931253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (!fs->icache) { 82031253488385a62e4db53cad04f55188a2861b4bbZheng Liu ext2_ino_t first_ino = EXT2_FIRST_INO(fs->super); 82131253488385a62e4db53cad04f55188a2861b4bbZheng Liu int i; 82231253488385a62e4db53cad04f55188a2861b4bbZheng Liu 82331253488385a62e4db53cad04f55188a2861b4bbZheng Liu /* we just want to init inode cache. So ignore error */ 82431253488385a62e4db53cad04f55188a2861b4bbZheng Liu ext2fs_create_inode_cache(fs, 16); 82531253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (!fs->icache) { 82631253488385a62e4db53cad04f55188a2861b4bbZheng Liu fprintf(stderr, 82731253488385a62e4db53cad04f55188a2861b4bbZheng Liu "tst_inline_data: init inode cache failed\n"); 82831253488385a62e4db53cad04f55188a2861b4bbZheng Liu exit(1); 82931253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 83031253488385a62e4db53cad04f55188a2861b4bbZheng Liu 83131253488385a62e4db53cad04f55188a2861b4bbZheng Liu /* setup inode cache */ 83231253488385a62e4db53cad04f55188a2861b4bbZheng Liu for (i = 0; i < fs->icache->cache_size; i++) 83331253488385a62e4db53cad04f55188a2861b4bbZheng Liu fs->icache->cache[i].ino = first_ino++; 83431253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 83531253488385a62e4db53cad04f55188a2861b4bbZheng Liu 83631253488385a62e4db53cad04f55188a2861b4bbZheng Liu /* test */ 83731253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (file_test(fs)) { 83831253488385a62e4db53cad04f55188a2861b4bbZheng Liu fprintf(stderr, "tst_inline_data(FILE): FAILED\n"); 83931253488385a62e4db53cad04f55188a2861b4bbZheng Liu return 1; 84031253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 84131253488385a62e4db53cad04f55188a2861b4bbZheng Liu printf("tst_inline_data(FILE): OK\n"); 84231253488385a62e4db53cad04f55188a2861b4bbZheng Liu 84331253488385a62e4db53cad04f55188a2861b4bbZheng Liu if (dir_test(fs)) { 84431253488385a62e4db53cad04f55188a2861b4bbZheng Liu fprintf(stderr, "tst_inline_data(DIR): FAILED\n"); 84531253488385a62e4db53cad04f55188a2861b4bbZheng Liu return 1; 84631253488385a62e4db53cad04f55188a2861b4bbZheng Liu } 84731253488385a62e4db53cad04f55188a2861b4bbZheng Liu printf("tst_inline_data(DIR): OK\n"); 84831253488385a62e4db53cad04f55188a2861b4bbZheng Liu 84931253488385a62e4db53cad04f55188a2861b4bbZheng Liu return 0; 85031253488385a62e4db53cad04f55188a2861b4bbZheng Liu} 85131253488385a62e4db53cad04f55188a2861b4bbZheng Liu#endif 852