aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/namei.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/namei.c')
-rw-r--r--fs/ext4/namei.c531
1 files changed, 356 insertions, 175 deletions
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 6d600a69fc9d..cac448282331 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -202,13 +202,8 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
202 struct inode *inode); 202 struct inode *inode);
203 203
204/* checksumming functions */ 204/* checksumming functions */
205#define EXT4_DIRENT_TAIL(block, blocksize) \ 205void initialize_dirent_tail(struct ext4_dir_entry_tail *t,
206 ((struct ext4_dir_entry_tail *)(((void *)(block)) + \ 206 unsigned int blocksize)
207 ((blocksize) - \
208 sizeof(struct ext4_dir_entry_tail))))
209
210static void initialize_dirent_tail(struct ext4_dir_entry_tail *t,
211 unsigned int blocksize)
212{ 207{
213 memset(t, 0, sizeof(struct ext4_dir_entry_tail)); 208 memset(t, 0, sizeof(struct ext4_dir_entry_tail));
214 t->det_rec_len = ext4_rec_len_to_disk( 209 t->det_rec_len = ext4_rec_len_to_disk(
@@ -261,6 +256,12 @@ static __le32 ext4_dirent_csum(struct inode *inode,
261 return cpu_to_le32(csum); 256 return cpu_to_le32(csum);
262} 257}
263 258
259static void warn_no_space_for_csum(struct inode *inode)
260{
261 ext4_warning(inode->i_sb, "no space in directory inode %lu leaf for "
262 "checksum. Please run e2fsck -D.", inode->i_ino);
263}
264
264int ext4_dirent_csum_verify(struct inode *inode, struct ext4_dir_entry *dirent) 265int ext4_dirent_csum_verify(struct inode *inode, struct ext4_dir_entry *dirent)
265{ 266{
266 struct ext4_dir_entry_tail *t; 267 struct ext4_dir_entry_tail *t;
@@ -271,8 +272,7 @@ int ext4_dirent_csum_verify(struct inode *inode, struct ext4_dir_entry *dirent)
271 272
272 t = get_dirent_tail(inode, dirent); 273 t = get_dirent_tail(inode, dirent);
273 if (!t) { 274 if (!t) {
274 EXT4_ERROR_INODE(inode, "metadata_csum set but no space in dir " 275 warn_no_space_for_csum(inode);
275 "leaf for checksum. Please run e2fsck -D.");
276 return 0; 276 return 0;
277 } 277 }
278 278
@@ -294,8 +294,7 @@ static void ext4_dirent_csum_set(struct inode *inode,
294 294
295 t = get_dirent_tail(inode, dirent); 295 t = get_dirent_tail(inode, dirent);
296 if (!t) { 296 if (!t) {
297 EXT4_ERROR_INODE(inode, "metadata_csum set but no space in dir " 297 warn_no_space_for_csum(inode);
298 "leaf for checksum. Please run e2fsck -D.");
299 return; 298 return;
300 } 299 }
301 300
@@ -303,9 +302,9 @@ static void ext4_dirent_csum_set(struct inode *inode,
303 (void *)t - (void *)dirent); 302 (void *)t - (void *)dirent);
304} 303}
305 304
306static inline int ext4_handle_dirty_dirent_node(handle_t *handle, 305int ext4_handle_dirty_dirent_node(handle_t *handle,
307 struct inode *inode, 306 struct inode *inode,
308 struct buffer_head *bh) 307 struct buffer_head *bh)
309{ 308{
310 ext4_dirent_csum_set(inode, (struct ext4_dir_entry *)bh->b_data); 309 ext4_dirent_csum_set(inode, (struct ext4_dir_entry *)bh->b_data);
311 return ext4_handle_dirty_metadata(handle, inode, bh); 310 return ext4_handle_dirty_metadata(handle, inode, bh);
@@ -377,8 +376,7 @@ static int ext4_dx_csum_verify(struct inode *inode,
377 count = le16_to_cpu(c->count); 376 count = le16_to_cpu(c->count);
378 if (count_offset + (limit * sizeof(struct dx_entry)) > 377 if (count_offset + (limit * sizeof(struct dx_entry)) >
379 EXT4_BLOCK_SIZE(inode->i_sb) - sizeof(struct dx_tail)) { 378 EXT4_BLOCK_SIZE(inode->i_sb) - sizeof(struct dx_tail)) {
380 EXT4_ERROR_INODE(inode, "metadata_csum set but no space for " 379 warn_no_space_for_csum(inode);
381 "tree checksum found. Run e2fsck -D.");
382 return 1; 380 return 1;
383 } 381 }
384 t = (struct dx_tail *)(((struct dx_entry *)c) + limit); 382 t = (struct dx_tail *)(((struct dx_entry *)c) + limit);
@@ -408,8 +406,7 @@ static void ext4_dx_csum_set(struct inode *inode, struct ext4_dir_entry *dirent)
408 count = le16_to_cpu(c->count); 406 count = le16_to_cpu(c->count);
409 if (count_offset + (limit * sizeof(struct dx_entry)) > 407 if (count_offset + (limit * sizeof(struct dx_entry)) >
410 EXT4_BLOCK_SIZE(inode->i_sb) - sizeof(struct dx_tail)) { 408 EXT4_BLOCK_SIZE(inode->i_sb) - sizeof(struct dx_tail)) {
411 EXT4_ERROR_INODE(inode, "metadata_csum set but no space for " 409 warn_no_space_for_csum(inode);
412 "tree checksum. Run e2fsck -D.");
413 return; 410 return;
414 } 411 }
415 t = (struct dx_tail *)(((struct dx_entry *)c) + limit); 412 t = (struct dx_tail *)(((struct dx_entry *)c) + limit);
@@ -890,6 +887,7 @@ static int htree_dirblock_to_tree(struct file *dir_file,
890 EXT4_DIR_REC_LEN(0)); 887 EXT4_DIR_REC_LEN(0));
891 for (; de < top; de = ext4_next_entry(de, dir->i_sb->s_blocksize)) { 888 for (; de < top; de = ext4_next_entry(de, dir->i_sb->s_blocksize)) {
892 if (ext4_check_dir_entry(dir, NULL, de, bh, 889 if (ext4_check_dir_entry(dir, NULL, de, bh,
890 bh->b_data, bh->b_size,
893 (block<<EXT4_BLOCK_SIZE_BITS(dir->i_sb)) 891 (block<<EXT4_BLOCK_SIZE_BITS(dir->i_sb))
894 + ((char *)de - bh->b_data))) { 892 + ((char *)de - bh->b_data))) {
895 /* On error, skip the f_pos to the next block. */ 893 /* On error, skip the f_pos to the next block. */
@@ -1007,6 +1005,15 @@ errout:
1007 return (err); 1005 return (err);
1008} 1006}
1009 1007
1008static inline int search_dirblock(struct buffer_head *bh,
1009 struct inode *dir,
1010 const struct qstr *d_name,
1011 unsigned int offset,
1012 struct ext4_dir_entry_2 **res_dir)
1013{
1014 return search_dir(bh, bh->b_data, dir->i_sb->s_blocksize, dir,
1015 d_name, offset, res_dir);
1016}
1010 1017
1011/* 1018/*
1012 * Directory block splitting, compacting 1019 * Directory block splitting, compacting
@@ -1081,13 +1088,6 @@ static void dx_insert_block(struct dx_frame *frame, u32 hash, ext4_lblk_t block)
1081 dx_set_count(entries, count + 1); 1088 dx_set_count(entries, count + 1);
1082} 1089}
1083 1090
1084static void ext4_update_dx_flag(struct inode *inode)
1085{
1086 if (!EXT4_HAS_COMPAT_FEATURE(inode->i_sb,
1087 EXT4_FEATURE_COMPAT_DIR_INDEX))
1088 ext4_clear_inode_flag(inode, EXT4_INODE_INDEX);
1089}
1090
1091/* 1091/*
1092 * NOTE! unlike strncmp, ext4_match returns 1 for success, 0 for failure. 1092 * NOTE! unlike strncmp, ext4_match returns 1 for success, 0 for failure.
1093 * 1093 *
@@ -1107,11 +1107,13 @@ static inline int ext4_match (int len, const char * const name,
1107/* 1107/*
1108 * Returns 0 if not found, -1 on failure, and 1 on success 1108 * Returns 0 if not found, -1 on failure, and 1 on success
1109 */ 1109 */
1110static inline int search_dirblock(struct buffer_head *bh, 1110int search_dir(struct buffer_head *bh,
1111 struct inode *dir, 1111 char *search_buf,
1112 const struct qstr *d_name, 1112 int buf_size,
1113 unsigned int offset, 1113 struct inode *dir,
1114 struct ext4_dir_entry_2 ** res_dir) 1114 const struct qstr *d_name,
1115 unsigned int offset,
1116 struct ext4_dir_entry_2 **res_dir)
1115{ 1117{
1116 struct ext4_dir_entry_2 * de; 1118 struct ext4_dir_entry_2 * de;
1117 char * dlimit; 1119 char * dlimit;
@@ -1119,8 +1121,8 @@ static inline int search_dirblock(struct buffer_head *bh,
1119 const char *name = d_name->name; 1121 const char *name = d_name->name;
1120 int namelen = d_name->len; 1122 int namelen = d_name->len;
1121 1123
1122 de = (struct ext4_dir_entry_2 *) bh->b_data; 1124 de = (struct ext4_dir_entry_2 *)search_buf;
1123 dlimit = bh->b_data + dir->i_sb->s_blocksize; 1125 dlimit = search_buf + buf_size;
1124 while ((char *) de < dlimit) { 1126 while ((char *) de < dlimit) {
1125 /* this code is executed quadratically often */ 1127 /* this code is executed quadratically often */
1126 /* do minimal checking `by hand' */ 1128 /* do minimal checking `by hand' */
@@ -1128,7 +1130,8 @@ static inline int search_dirblock(struct buffer_head *bh,
1128 if ((char *) de + namelen <= dlimit && 1130 if ((char *) de + namelen <= dlimit &&
1129 ext4_match (namelen, name, de)) { 1131 ext4_match (namelen, name, de)) {
1130 /* found a match - just to be sure, do a full check */ 1132 /* found a match - just to be sure, do a full check */
1131 if (ext4_check_dir_entry(dir, NULL, de, bh, offset)) 1133 if (ext4_check_dir_entry(dir, NULL, de, bh, bh->b_data,
1134 bh->b_size, offset))
1132 return -1; 1135 return -1;
1133 *res_dir = de; 1136 *res_dir = de;
1134 return 1; 1137 return 1;
@@ -1144,6 +1147,21 @@ static inline int search_dirblock(struct buffer_head *bh,
1144 return 0; 1147 return 0;
1145} 1148}
1146 1149
1150static int is_dx_internal_node(struct inode *dir, ext4_lblk_t block,
1151 struct ext4_dir_entry *de)
1152{
1153 struct super_block *sb = dir->i_sb;
1154
1155 if (!is_dx(dir))
1156 return 0;
1157 if (block == 0)
1158 return 1;
1159 if (de->inode == 0 &&
1160 ext4_rec_len_from_disk(de->rec_len, sb->s_blocksize) ==
1161 sb->s_blocksize)
1162 return 1;
1163 return 0;
1164}
1147 1165
1148/* 1166/*
1149 * ext4_find_entry() 1167 * ext4_find_entry()
@@ -1158,7 +1176,8 @@ static inline int search_dirblock(struct buffer_head *bh,
1158 */ 1176 */
1159static struct buffer_head * ext4_find_entry (struct inode *dir, 1177static struct buffer_head * ext4_find_entry (struct inode *dir,
1160 const struct qstr *d_name, 1178 const struct qstr *d_name,
1161 struct ext4_dir_entry_2 ** res_dir) 1179 struct ext4_dir_entry_2 **res_dir,
1180 int *inlined)
1162{ 1181{
1163 struct super_block *sb; 1182 struct super_block *sb;
1164 struct buffer_head *bh_use[NAMEI_RA_SIZE]; 1183 struct buffer_head *bh_use[NAMEI_RA_SIZE];
@@ -1179,6 +1198,18 @@ static struct buffer_head * ext4_find_entry (struct inode *dir,
1179 namelen = d_name->len; 1198 namelen = d_name->len;
1180 if (namelen > EXT4_NAME_LEN) 1199 if (namelen > EXT4_NAME_LEN)
1181 return NULL; 1200 return NULL;
1201
1202 if (ext4_has_inline_data(dir)) {
1203 int has_inline_data = 1;
1204 ret = ext4_find_inline_entry(dir, d_name, res_dir,
1205 &has_inline_data);
1206 if (has_inline_data) {
1207 if (inlined)
1208 *inlined = 1;
1209 return ret;
1210 }
1211 }
1212
1182 if ((namelen <= 2) && (name[0] == '.') && 1213 if ((namelen <= 2) && (name[0] == '.') &&
1183 (name[1] == '.' || name[1] == '\0')) { 1214 (name[1] == '.' || name[1] == '\0')) {
1184 /* 1215 /*
@@ -1244,6 +1275,8 @@ restart:
1244 goto next; 1275 goto next;
1245 } 1276 }
1246 if (!buffer_verified(bh) && 1277 if (!buffer_verified(bh) &&
1278 !is_dx_internal_node(dir, block,
1279 (struct ext4_dir_entry *)bh->b_data) &&
1247 !ext4_dirent_csum_verify(dir, 1280 !ext4_dirent_csum_verify(dir,
1248 (struct ext4_dir_entry *)bh->b_data)) { 1281 (struct ext4_dir_entry *)bh->b_data)) {
1249 EXT4_ERROR_INODE(dir, "checksumming directory " 1282 EXT4_ERROR_INODE(dir, "checksumming directory "
@@ -1361,7 +1394,7 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, unsi
1361 if (dentry->d_name.len > EXT4_NAME_LEN) 1394 if (dentry->d_name.len > EXT4_NAME_LEN)
1362 return ERR_PTR(-ENAMETOOLONG); 1395 return ERR_PTR(-ENAMETOOLONG);
1363 1396
1364 bh = ext4_find_entry(dir, &dentry->d_name, &de); 1397 bh = ext4_find_entry(dir, &dentry->d_name, &de, NULL);
1365 inode = NULL; 1398 inode = NULL;
1366 if (bh) { 1399 if (bh) {
1367 __u32 ino = le32_to_cpu(de->inode); 1400 __u32 ino = le32_to_cpu(de->inode);
@@ -1395,7 +1428,7 @@ struct dentry *ext4_get_parent(struct dentry *child)
1395 struct ext4_dir_entry_2 * de; 1428 struct ext4_dir_entry_2 * de;
1396 struct buffer_head *bh; 1429 struct buffer_head *bh;
1397 1430
1398 bh = ext4_find_entry(child->d_inode, &dotdot, &de); 1431 bh = ext4_find_entry(child->d_inode, &dotdot, &de, NULL);
1399 if (!bh) 1432 if (!bh)
1400 return ERR_PTR(-ENOENT); 1433 return ERR_PTR(-ENOENT);
1401 ino = le32_to_cpu(de->inode); 1434 ino = le32_to_cpu(de->inode);
@@ -1593,6 +1626,63 @@ errout:
1593 return NULL; 1626 return NULL;
1594} 1627}
1595 1628
1629int ext4_find_dest_de(struct inode *dir, struct inode *inode,
1630 struct buffer_head *bh,
1631 void *buf, int buf_size,
1632 const char *name, int namelen,
1633 struct ext4_dir_entry_2 **dest_de)
1634{
1635 struct ext4_dir_entry_2 *de;
1636 unsigned short reclen = EXT4_DIR_REC_LEN(namelen);
1637 int nlen, rlen;
1638 unsigned int offset = 0;
1639 char *top;
1640
1641 de = (struct ext4_dir_entry_2 *)buf;
1642 top = buf + buf_size - reclen;
1643 while ((char *) de <= top) {
1644 if (ext4_check_dir_entry(dir, NULL, de, bh,
1645 buf, buf_size, offset))
1646 return -EIO;
1647 if (ext4_match(namelen, name, de))
1648 return -EEXIST;
1649 nlen = EXT4_DIR_REC_LEN(de->name_len);
1650 rlen = ext4_rec_len_from_disk(de->rec_len, buf_size);
1651 if ((de->inode ? rlen - nlen : rlen) >= reclen)
1652 break;
1653 de = (struct ext4_dir_entry_2 *)((char *)de + rlen);
1654 offset += rlen;
1655 }
1656 if ((char *) de > top)
1657 return -ENOSPC;
1658
1659 *dest_de = de;
1660 return 0;
1661}
1662
1663void ext4_insert_dentry(struct inode *inode,
1664 struct ext4_dir_entry_2 *de,
1665 int buf_size,
1666 const char *name, int namelen)
1667{
1668
1669 int nlen, rlen;
1670
1671 nlen = EXT4_DIR_REC_LEN(de->name_len);
1672 rlen = ext4_rec_len_from_disk(de->rec_len, buf_size);
1673 if (de->inode) {
1674 struct ext4_dir_entry_2 *de1 =
1675 (struct ext4_dir_entry_2 *)((char *)de + nlen);
1676 de1->rec_len = ext4_rec_len_to_disk(rlen - nlen, buf_size);
1677 de->rec_len = ext4_rec_len_to_disk(nlen, buf_size);
1678 de = de1;
1679 }
1680 de->file_type = EXT4_FT_UNKNOWN;
1681 de->inode = cpu_to_le32(inode->i_ino);
1682 ext4_set_de_type(inode->i_sb, de, inode->i_mode);
1683 de->name_len = namelen;
1684 memcpy(de->name, name, namelen);
1685}
1596/* 1686/*
1597 * Add a new entry into a directory (leaf) block. If de is non-NULL, 1687 * Add a new entry into a directory (leaf) block. If de is non-NULL,
1598 * it points to a directory entry which is guaranteed to be large 1688 * it points to a directory entry which is guaranteed to be large
@@ -1608,12 +1698,10 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
1608 struct inode *dir = dentry->d_parent->d_inode; 1698 struct inode *dir = dentry->d_parent->d_inode;
1609 const char *name = dentry->d_name.name; 1699 const char *name = dentry->d_name.name;
1610 int namelen = dentry->d_name.len; 1700 int namelen = dentry->d_name.len;
1611 unsigned int offset = 0;
1612 unsigned int blocksize = dir->i_sb->s_blocksize; 1701 unsigned int blocksize = dir->i_sb->s_blocksize;
1613 unsigned short reclen; 1702 unsigned short reclen;
1614 int nlen, rlen, err;
1615 char *top;
1616 int csum_size = 0; 1703 int csum_size = 0;
1704 int err;
1617 1705
1618 if (EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb, 1706 if (EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
1619 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 1707 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
@@ -1621,22 +1709,11 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
1621 1709
1622 reclen = EXT4_DIR_REC_LEN(namelen); 1710 reclen = EXT4_DIR_REC_LEN(namelen);
1623 if (!de) { 1711 if (!de) {
1624 de = (struct ext4_dir_entry_2 *)bh->b_data; 1712 err = ext4_find_dest_de(dir, inode,
1625 top = bh->b_data + (blocksize - csum_size) - reclen; 1713 bh, bh->b_data, blocksize - csum_size,
1626 while ((char *) de <= top) { 1714 name, namelen, &de);
1627 if (ext4_check_dir_entry(dir, NULL, de, bh, offset)) 1715 if (err)
1628 return -EIO; 1716 return err;
1629 if (ext4_match(namelen, name, de))
1630 return -EEXIST;
1631 nlen = EXT4_DIR_REC_LEN(de->name_len);
1632 rlen = ext4_rec_len_from_disk(de->rec_len, blocksize);
1633 if ((de->inode? rlen - nlen: rlen) >= reclen)
1634 break;
1635 de = (struct ext4_dir_entry_2 *)((char *)de + rlen);
1636 offset += rlen;
1637 }
1638 if ((char *) de > top)
1639 return -ENOSPC;
1640 } 1717 }
1641 BUFFER_TRACE(bh, "get_write_access"); 1718 BUFFER_TRACE(bh, "get_write_access");
1642 err = ext4_journal_get_write_access(handle, bh); 1719 err = ext4_journal_get_write_access(handle, bh);
@@ -1646,19 +1723,8 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
1646 } 1723 }
1647 1724
1648 /* By now the buffer is marked for journaling */ 1725 /* By now the buffer is marked for journaling */
1649 nlen = EXT4_DIR_REC_LEN(de->name_len); 1726 ext4_insert_dentry(inode, de, blocksize, name, namelen);
1650 rlen = ext4_rec_len_from_disk(de->rec_len, blocksize); 1727
1651 if (de->inode) {
1652 struct ext4_dir_entry_2 *de1 = (struct ext4_dir_entry_2 *)((char *)de + nlen);
1653 de1->rec_len = ext4_rec_len_to_disk(rlen - nlen, blocksize);
1654 de->rec_len = ext4_rec_len_to_disk(nlen, blocksize);
1655 de = de1;
1656 }
1657 de->file_type = EXT4_FT_UNKNOWN;
1658 de->inode = cpu_to_le32(inode->i_ino);
1659 ext4_set_de_type(dir->i_sb, de, inode->i_mode);
1660 de->name_len = namelen;
1661 memcpy(de->name, name, namelen);
1662 /* 1728 /*
1663 * XXX shouldn't update any times until successful 1729 * XXX shouldn't update any times until successful
1664 * completion of syscall, but too many callers depend 1730 * completion of syscall, but too many callers depend
@@ -1831,6 +1897,17 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
1831 blocksize = sb->s_blocksize; 1897 blocksize = sb->s_blocksize;
1832 if (!dentry->d_name.len) 1898 if (!dentry->d_name.len)
1833 return -EINVAL; 1899 return -EINVAL;
1900
1901 if (ext4_has_inline_data(dir)) {
1902 retval = ext4_try_add_inline_entry(handle, dentry, inode);
1903 if (retval < 0)
1904 return retval;
1905 if (retval == 1) {
1906 retval = 0;
1907 return retval;
1908 }
1909 }
1910
1834 if (is_dx(dir)) { 1911 if (is_dx(dir)) {
1835 retval = ext4_dx_add_entry(handle, dentry, inode); 1912 retval = ext4_dx_add_entry(handle, dentry, inode);
1836 if (!retval || (retval != ERR_BAD_DX_DIR)) 1913 if (!retval || (retval != ERR_BAD_DX_DIR))
@@ -2036,36 +2113,29 @@ cleanup:
2036} 2113}
2037 2114
2038/* 2115/*
2039 * ext4_delete_entry deletes a directory entry by merging it with the 2116 * ext4_generic_delete_entry deletes a directory entry by merging it
2040 * previous entry 2117 * with the previous entry
2041 */ 2118 */
2042static int ext4_delete_entry(handle_t *handle, 2119int ext4_generic_delete_entry(handle_t *handle,
2043 struct inode *dir, 2120 struct inode *dir,
2044 struct ext4_dir_entry_2 *de_del, 2121 struct ext4_dir_entry_2 *de_del,
2045 struct buffer_head *bh) 2122 struct buffer_head *bh,
2123 void *entry_buf,
2124 int buf_size,
2125 int csum_size)
2046{ 2126{
2047 struct ext4_dir_entry_2 *de, *pde; 2127 struct ext4_dir_entry_2 *de, *pde;
2048 unsigned int blocksize = dir->i_sb->s_blocksize; 2128 unsigned int blocksize = dir->i_sb->s_blocksize;
2049 int csum_size = 0; 2129 int i;
2050 int i, err;
2051
2052 if (EXT4_HAS_RO_COMPAT_FEATURE(dir->i_sb,
2053 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
2054 csum_size = sizeof(struct ext4_dir_entry_tail);
2055 2130
2056 i = 0; 2131 i = 0;
2057 pde = NULL; 2132 pde = NULL;
2058 de = (struct ext4_dir_entry_2 *) bh->b_data; 2133 de = (struct ext4_dir_entry_2 *)entry_buf;
2059 while (i < bh->b_size - csum_size) { 2134 while (i < buf_size - csum_size) {
2060 if (ext4_check_dir_entry(dir, NULL, de, bh, i)) 2135 if (ext4_check_dir_entry(dir, NULL, de, bh,
2136 bh->b_data, bh->b_size, i))
2061 return -EIO; 2137 return -EIO;
2062 if (de == de_del) { 2138 if (de == de_del) {
2063 BUFFER_TRACE(bh, "get_write_access");
2064 err = ext4_journal_get_write_access(handle, bh);
2065 if (unlikely(err)) {
2066 ext4_std_error(dir->i_sb, err);
2067 return err;
2068 }
2069 if (pde) 2139 if (pde)
2070 pde->rec_len = ext4_rec_len_to_disk( 2140 pde->rec_len = ext4_rec_len_to_disk(
2071 ext4_rec_len_from_disk(pde->rec_len, 2141 ext4_rec_len_from_disk(pde->rec_len,
@@ -2076,12 +2146,6 @@ static int ext4_delete_entry(handle_t *handle,
2076 else 2146 else
2077 de->inode = 0; 2147 de->inode = 0;
2078 dir->i_version++; 2148 dir->i_version++;
2079 BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata");
2080 err = ext4_handle_dirty_dirent_node(handle, dir, bh);
2081 if (unlikely(err)) {
2082 ext4_std_error(dir->i_sb, err);
2083 return err;
2084 }
2085 return 0; 2149 return 0;
2086 } 2150 }
2087 i += ext4_rec_len_from_disk(de->rec_len, blocksize); 2151 i += ext4_rec_len_from_disk(de->rec_len, blocksize);
@@ -2091,6 +2155,48 @@ static int ext4_delete_entry(handle_t *handle,
2091 return -ENOENT; 2155 return -ENOENT;
2092} 2156}
2093 2157
2158static int ext4_delete_entry(handle_t *handle,
2159 struct inode *dir,
2160 struct ext4_dir_entry_2 *de_del,
2161 struct buffer_head *bh)
2162{
2163 int err, csum_size = 0;
2164
2165 if (ext4_has_inline_data(dir)) {
2166 int has_inline_data = 1;
2167 err = ext4_delete_inline_entry(handle, dir, de_del, bh,
2168 &has_inline_data);
2169 if (has_inline_data)
2170 return err;
2171 }
2172
2173 if (EXT4_HAS_RO_COMPAT_FEATURE(dir->i_sb,
2174 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
2175 csum_size = sizeof(struct ext4_dir_entry_tail);
2176
2177 BUFFER_TRACE(bh, "get_write_access");
2178 err = ext4_journal_get_write_access(handle, bh);
2179 if (unlikely(err))
2180 goto out;
2181
2182 err = ext4_generic_delete_entry(handle, dir, de_del,
2183 bh, bh->b_data,
2184 dir->i_sb->s_blocksize, csum_size);
2185 if (err)
2186 goto out;
2187
2188 BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata");
2189 err = ext4_handle_dirty_dirent_node(handle, dir, bh);
2190 if (unlikely(err))
2191 goto out;
2192
2193 return 0;
2194out:
2195 if (err != -ENOENT)
2196 ext4_std_error(dir->i_sb, err);
2197 return err;
2198}
2199
2094/* 2200/*
2095 * DIR_NLINK feature is set if 1) nlinks > EXT4_LINK_MAX or 2) nlinks == 2, 2201 * DIR_NLINK feature is set if 1) nlinks > EXT4_LINK_MAX or 2) nlinks == 2,
2096 * since this indicates that nlinks count was previously 1. 2202 * since this indicates that nlinks count was previously 1.
@@ -2211,21 +2317,95 @@ retry:
2211 return err; 2317 return err;
2212} 2318}
2213 2319
2214static int ext4_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) 2320struct ext4_dir_entry_2 *ext4_init_dot_dotdot(struct inode *inode,
2321 struct ext4_dir_entry_2 *de,
2322 int blocksize, int csum_size,
2323 unsigned int parent_ino, int dotdot_real_len)
2324{
2325 de->inode = cpu_to_le32(inode->i_ino);
2326 de->name_len = 1;
2327 de->rec_len = ext4_rec_len_to_disk(EXT4_DIR_REC_LEN(de->name_len),
2328 blocksize);
2329 strcpy(de->name, ".");
2330 ext4_set_de_type(inode->i_sb, de, S_IFDIR);
2331
2332 de = ext4_next_entry(de, blocksize);
2333 de->inode = cpu_to_le32(parent_ino);
2334 de->name_len = 2;
2335 if (!dotdot_real_len)
2336 de->rec_len = ext4_rec_len_to_disk(blocksize -
2337 (csum_size + EXT4_DIR_REC_LEN(1)),
2338 blocksize);
2339 else
2340 de->rec_len = ext4_rec_len_to_disk(
2341 EXT4_DIR_REC_LEN(de->name_len), blocksize);
2342 strcpy(de->name, "..");
2343 ext4_set_de_type(inode->i_sb, de, S_IFDIR);
2344
2345 return ext4_next_entry(de, blocksize);
2346}
2347
2348static int ext4_init_new_dir(handle_t *handle, struct inode *dir,
2349 struct inode *inode)
2215{ 2350{
2216 handle_t *handle;
2217 struct inode *inode;
2218 struct buffer_head *dir_block = NULL; 2351 struct buffer_head *dir_block = NULL;
2219 struct ext4_dir_entry_2 *de; 2352 struct ext4_dir_entry_2 *de;
2220 struct ext4_dir_entry_tail *t; 2353 struct ext4_dir_entry_tail *t;
2221 unsigned int blocksize = dir->i_sb->s_blocksize; 2354 unsigned int blocksize = dir->i_sb->s_blocksize;
2222 int csum_size = 0; 2355 int csum_size = 0;
2223 int err, retries = 0; 2356 int err;
2224 2357
2225 if (EXT4_HAS_RO_COMPAT_FEATURE(dir->i_sb, 2358 if (EXT4_HAS_RO_COMPAT_FEATURE(dir->i_sb,
2226 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 2359 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
2227 csum_size = sizeof(struct ext4_dir_entry_tail); 2360 csum_size = sizeof(struct ext4_dir_entry_tail);
2228 2361
2362 if (ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA)) {
2363 err = ext4_try_create_inline_dir(handle, dir, inode);
2364 if (err < 0 && err != -ENOSPC)
2365 goto out;
2366 if (!err)
2367 goto out;
2368 }
2369
2370 inode->i_size = EXT4_I(inode)->i_disksize = blocksize;
2371 dir_block = ext4_bread(handle, inode, 0, 1, &err);
2372 if (!(dir_block = ext4_bread(handle, inode, 0, 1, &err))) {
2373 if (!err) {
2374 err = -EIO;
2375 ext4_error(inode->i_sb,
2376 "Directory hole detected on inode %lu\n",
2377 inode->i_ino);
2378 }
2379 goto out;
2380 }
2381 BUFFER_TRACE(dir_block, "get_write_access");
2382 err = ext4_journal_get_write_access(handle, dir_block);
2383 if (err)
2384 goto out;
2385 de = (struct ext4_dir_entry_2 *)dir_block->b_data;
2386 ext4_init_dot_dotdot(inode, de, blocksize, csum_size, dir->i_ino, 0);
2387 set_nlink(inode, 2);
2388 if (csum_size) {
2389 t = EXT4_DIRENT_TAIL(dir_block->b_data, blocksize);
2390 initialize_dirent_tail(t, blocksize);
2391 }
2392
2393 BUFFER_TRACE(dir_block, "call ext4_handle_dirty_metadata");
2394 err = ext4_handle_dirty_dirent_node(handle, inode, dir_block);
2395 if (err)
2396 goto out;
2397 set_buffer_verified(dir_block);
2398out:
2399 brelse(dir_block);
2400 return err;
2401}
2402
2403static int ext4_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
2404{
2405 handle_t *handle;
2406 struct inode *inode;
2407 int err, retries = 0;
2408
2229 if (EXT4_DIR_LINK_MAX(dir)) 2409 if (EXT4_DIR_LINK_MAX(dir))
2230 return -EMLINK; 2410 return -EMLINK;
2231 2411
@@ -2249,47 +2429,9 @@ retry:
2249 2429
2250 inode->i_op = &ext4_dir_inode_operations; 2430 inode->i_op = &ext4_dir_inode_operations;
2251 inode->i_fop = &ext4_dir_operations; 2431 inode->i_fop = &ext4_dir_operations;
2252 inode->i_size = EXT4_I(inode)->i_disksize = inode->i_sb->s_blocksize; 2432 err = ext4_init_new_dir(handle, dir, inode);
2253 if (!(dir_block = ext4_bread(handle, inode, 0, 1, &err))) {
2254 if (!err) {
2255 err = -EIO;
2256 ext4_error(inode->i_sb,
2257 "Directory hole detected on inode %lu\n",
2258 inode->i_ino);
2259 }
2260 goto out_clear_inode;
2261 }
2262 BUFFER_TRACE(dir_block, "get_write_access");
2263 err = ext4_journal_get_write_access(handle, dir_block);
2264 if (err)
2265 goto out_clear_inode;
2266 de = (struct ext4_dir_entry_2 *) dir_block->b_data;
2267 de->inode = cpu_to_le32(inode->i_ino);
2268 de->name_len = 1;
2269 de->rec_len = ext4_rec_len_to_disk(EXT4_DIR_REC_LEN(de->name_len),
2270 blocksize);
2271 strcpy(de->name, ".");
2272 ext4_set_de_type(dir->i_sb, de, S_IFDIR);
2273 de = ext4_next_entry(de, blocksize);
2274 de->inode = cpu_to_le32(dir->i_ino);
2275 de->rec_len = ext4_rec_len_to_disk(blocksize -
2276 (csum_size + EXT4_DIR_REC_LEN(1)),
2277 blocksize);
2278 de->name_len = 2;
2279 strcpy(de->name, "..");
2280 ext4_set_de_type(dir->i_sb, de, S_IFDIR);
2281 set_nlink(inode, 2);
2282
2283 if (csum_size) {
2284 t = EXT4_DIRENT_TAIL(dir_block->b_data, blocksize);
2285 initialize_dirent_tail(t, blocksize);
2286 }
2287
2288 BUFFER_TRACE(dir_block, "call ext4_handle_dirty_metadata");
2289 err = ext4_handle_dirty_dirent_node(handle, inode, dir_block);
2290 if (err) 2433 if (err)
2291 goto out_clear_inode; 2434 goto out_clear_inode;
2292 set_buffer_verified(dir_block);
2293 err = ext4_mark_inode_dirty(handle, inode); 2435 err = ext4_mark_inode_dirty(handle, inode);
2294 if (!err) 2436 if (!err)
2295 err = ext4_add_entry(handle, dentry, inode); 2437 err = ext4_add_entry(handle, dentry, inode);
@@ -2309,7 +2451,6 @@ out_clear_inode:
2309 unlock_new_inode(inode); 2451 unlock_new_inode(inode);
2310 d_instantiate(dentry, inode); 2452 d_instantiate(dentry, inode);
2311out_stop: 2453out_stop:
2312 brelse(dir_block);
2313 ext4_journal_stop(handle); 2454 ext4_journal_stop(handle);
2314 if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries)) 2455 if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries))
2315 goto retry; 2456 goto retry;
@@ -2327,6 +2468,14 @@ static int empty_dir(struct inode *inode)
2327 struct super_block *sb; 2468 struct super_block *sb;
2328 int err = 0; 2469 int err = 0;
2329 2470
2471 if (ext4_has_inline_data(inode)) {
2472 int has_inline_data = 1;
2473
2474 err = empty_inline_dir(inode, &has_inline_data);
2475 if (has_inline_data)
2476 return err;
2477 }
2478
2330 sb = inode->i_sb; 2479 sb = inode->i_sb;
2331 if (inode->i_size < EXT4_DIR_REC_LEN(1) + EXT4_DIR_REC_LEN(2) || 2480 if (inode->i_size < EXT4_DIR_REC_LEN(1) + EXT4_DIR_REC_LEN(2) ||
2332 !(bh = ext4_bread(NULL, inode, 0, 0, &err))) { 2481 !(bh = ext4_bread(NULL, inode, 0, 0, &err))) {
@@ -2393,7 +2542,8 @@ static int empty_dir(struct inode *inode)
2393 set_buffer_verified(bh); 2542 set_buffer_verified(bh);
2394 de = (struct ext4_dir_entry_2 *) bh->b_data; 2543 de = (struct ext4_dir_entry_2 *) bh->b_data;
2395 } 2544 }
2396 if (ext4_check_dir_entry(inode, NULL, de, bh, offset)) { 2545 if (ext4_check_dir_entry(inode, NULL, de, bh,
2546 bh->b_data, bh->b_size, offset)) {
2397 de = (struct ext4_dir_entry_2 *)(bh->b_data + 2547 de = (struct ext4_dir_entry_2 *)(bh->b_data +
2398 sb->s_blocksize); 2548 sb->s_blocksize);
2399 offset = (offset | (sb->s_blocksize - 1)) + 1; 2549 offset = (offset | (sb->s_blocksize - 1)) + 1;
@@ -2579,7 +2729,7 @@ static int ext4_rmdir(struct inode *dir, struct dentry *dentry)
2579 return PTR_ERR(handle); 2729 return PTR_ERR(handle);
2580 2730
2581 retval = -ENOENT; 2731 retval = -ENOENT;
2582 bh = ext4_find_entry(dir, &dentry->d_name, &de); 2732 bh = ext4_find_entry(dir, &dentry->d_name, &de, NULL);
2583 if (!bh) 2733 if (!bh)
2584 goto end_rmdir; 2734 goto end_rmdir;
2585 2735
@@ -2644,7 +2794,7 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry)
2644 ext4_handle_sync(handle); 2794 ext4_handle_sync(handle);
2645 2795
2646 retval = -ENOENT; 2796 retval = -ENOENT;
2647 bh = ext4_find_entry(dir, &dentry->d_name, &de); 2797 bh = ext4_find_entry(dir, &dentry->d_name, &de, NULL);
2648 if (!bh) 2798 if (!bh)
2649 goto end_unlink; 2799 goto end_unlink;
2650 2800
@@ -2826,8 +2976,39 @@ retry:
2826 return err; 2976 return err;
2827} 2977}
2828 2978
2829#define PARENT_INO(buffer, size) \ 2979
2830 (ext4_next_entry((struct ext4_dir_entry_2 *)(buffer), size)->inode) 2980/*
2981 * Try to find buffer head where contains the parent block.
2982 * It should be the inode block if it is inlined or the 1st block
2983 * if it is a normal dir.
2984 */
2985static struct buffer_head *ext4_get_first_dir_block(handle_t *handle,
2986 struct inode *inode,
2987 int *retval,
2988 struct ext4_dir_entry_2 **parent_de,
2989 int *inlined)
2990{
2991 struct buffer_head *bh;
2992
2993 if (!ext4_has_inline_data(inode)) {
2994 if (!(bh = ext4_bread(handle, inode, 0, 0, retval))) {
2995 if (!*retval) {
2996 *retval = -EIO;
2997 ext4_error(inode->i_sb,
2998 "Directory hole detected on inode %lu\n",
2999 inode->i_ino);
3000 }
3001 return NULL;
3002 }
3003 *parent_de = ext4_next_entry(
3004 (struct ext4_dir_entry_2 *)bh->b_data,
3005 inode->i_sb->s_blocksize);
3006 return bh;
3007 }
3008
3009 *inlined = 1;
3010 return ext4_get_first_inline_block(inode, parent_de, retval);
3011}
2831 3012
2832/* 3013/*
2833 * Anybody can rename anything with this: the permission checks are left to the 3014 * Anybody can rename anything with this: the permission checks are left to the
@@ -2841,6 +3022,8 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
2841 struct buffer_head *old_bh, *new_bh, *dir_bh; 3022 struct buffer_head *old_bh, *new_bh, *dir_bh;
2842 struct ext4_dir_entry_2 *old_de, *new_de; 3023 struct ext4_dir_entry_2 *old_de, *new_de;
2843 int retval, force_da_alloc = 0; 3024 int retval, force_da_alloc = 0;
3025 int inlined = 0, new_inlined = 0;
3026 struct ext4_dir_entry_2 *parent_de;
2844 3027
2845 dquot_initialize(old_dir); 3028 dquot_initialize(old_dir);
2846 dquot_initialize(new_dir); 3029 dquot_initialize(new_dir);
@@ -2860,7 +3043,7 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
2860 if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir)) 3043 if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir))
2861 ext4_handle_sync(handle); 3044 ext4_handle_sync(handle);
2862 3045
2863 old_bh = ext4_find_entry(old_dir, &old_dentry->d_name, &old_de); 3046 old_bh = ext4_find_entry(old_dir, &old_dentry->d_name, &old_de, NULL);
2864 /* 3047 /*
2865 * Check for inode number is _not_ due to possible IO errors. 3048 * Check for inode number is _not_ due to possible IO errors.
2866 * We might rmdir the source, keep it as pwd of some process 3049 * We might rmdir the source, keep it as pwd of some process
@@ -2873,7 +3056,8 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
2873 goto end_rename; 3056 goto end_rename;
2874 3057
2875 new_inode = new_dentry->d_inode; 3058 new_inode = new_dentry->d_inode;
2876 new_bh = ext4_find_entry(new_dir, &new_dentry->d_name, &new_de); 3059 new_bh = ext4_find_entry(new_dir, &new_dentry->d_name,
3060 &new_de, &new_inlined);
2877 if (new_bh) { 3061 if (new_bh) {
2878 if (!new_inode) { 3062 if (!new_inode) {
2879 brelse(new_bh); 3063 brelse(new_bh);
@@ -2887,22 +3071,17 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
2887 goto end_rename; 3071 goto end_rename;
2888 } 3072 }
2889 retval = -EIO; 3073 retval = -EIO;
2890 if (!(dir_bh = ext4_bread(handle, old_inode, 0, 0, &retval))) { 3074 dir_bh = ext4_get_first_dir_block(handle, old_inode,
2891 if (!retval) { 3075 &retval, &parent_de,
2892 retval = -EIO; 3076 &inlined);
2893 ext4_error(old_inode->i_sb, 3077 if (!dir_bh)
2894 "Directory hole detected on inode %lu\n",
2895 old_inode->i_ino);
2896 }
2897 goto end_rename; 3078 goto end_rename;
2898 } 3079 if (!inlined && !buffer_verified(dir_bh) &&
2899 if (!buffer_verified(dir_bh) &&
2900 !ext4_dirent_csum_verify(old_inode, 3080 !ext4_dirent_csum_verify(old_inode,
2901 (struct ext4_dir_entry *)dir_bh->b_data)) 3081 (struct ext4_dir_entry *)dir_bh->b_data))
2902 goto end_rename; 3082 goto end_rename;
2903 set_buffer_verified(dir_bh); 3083 set_buffer_verified(dir_bh);
2904 if (le32_to_cpu(PARENT_INO(dir_bh->b_data, 3084 if (le32_to_cpu(parent_de->inode) != old_dir->i_ino)
2905 old_dir->i_sb->s_blocksize)) != old_dir->i_ino)
2906 goto end_rename; 3085 goto end_rename;
2907 retval = -EMLINK; 3086 retval = -EMLINK;
2908 if (!new_inode && new_dir != old_dir && 3087 if (!new_inode && new_dir != old_dir &&
@@ -2931,10 +3110,13 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
2931 ext4_current_time(new_dir); 3110 ext4_current_time(new_dir);
2932 ext4_mark_inode_dirty(handle, new_dir); 3111 ext4_mark_inode_dirty(handle, new_dir);
2933 BUFFER_TRACE(new_bh, "call ext4_handle_dirty_metadata"); 3112 BUFFER_TRACE(new_bh, "call ext4_handle_dirty_metadata");
2934 retval = ext4_handle_dirty_dirent_node(handle, new_dir, new_bh); 3113 if (!new_inlined) {
2935 if (unlikely(retval)) { 3114 retval = ext4_handle_dirty_dirent_node(handle,
2936 ext4_std_error(new_dir->i_sb, retval); 3115 new_dir, new_bh);
2937 goto end_rename; 3116 if (unlikely(retval)) {
3117 ext4_std_error(new_dir->i_sb, retval);
3118 goto end_rename;
3119 }
2938 } 3120 }
2939 brelse(new_bh); 3121 brelse(new_bh);
2940 new_bh = NULL; 3122 new_bh = NULL;
@@ -2962,7 +3144,8 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
2962 struct buffer_head *old_bh2; 3144 struct buffer_head *old_bh2;
2963 struct ext4_dir_entry_2 *old_de2; 3145 struct ext4_dir_entry_2 *old_de2;
2964 3146
2965 old_bh2 = ext4_find_entry(old_dir, &old_dentry->d_name, &old_de2); 3147 old_bh2 = ext4_find_entry(old_dir, &old_dentry->d_name,
3148 &old_de2, NULL);
2966 if (old_bh2) { 3149 if (old_bh2) {
2967 retval = ext4_delete_entry(handle, old_dir, 3150 retval = ext4_delete_entry(handle, old_dir,
2968 old_de2, old_bh2); 3151 old_de2, old_bh2);
@@ -2982,17 +3165,19 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
2982 old_dir->i_ctime = old_dir->i_mtime = ext4_current_time(old_dir); 3165 old_dir->i_ctime = old_dir->i_mtime = ext4_current_time(old_dir);
2983 ext4_update_dx_flag(old_dir); 3166 ext4_update_dx_flag(old_dir);
2984 if (dir_bh) { 3167 if (dir_bh) {
2985 PARENT_INO(dir_bh->b_data, new_dir->i_sb->s_blocksize) = 3168 parent_de->inode = cpu_to_le32(new_dir->i_ino);
2986 cpu_to_le32(new_dir->i_ino);
2987 BUFFER_TRACE(dir_bh, "call ext4_handle_dirty_metadata"); 3169 BUFFER_TRACE(dir_bh, "call ext4_handle_dirty_metadata");
2988 if (is_dx(old_inode)) { 3170 if (!inlined) {
2989 retval = ext4_handle_dirty_dx_node(handle, 3171 if (is_dx(old_inode)) {
2990 old_inode, 3172 retval = ext4_handle_dirty_dx_node(handle,
2991 dir_bh); 3173 old_inode,
3174 dir_bh);
3175 } else {
3176 retval = ext4_handle_dirty_dirent_node(handle,
3177 old_inode, dir_bh);
3178 }
2992 } else { 3179 } else {
2993 retval = ext4_handle_dirty_dirent_node(handle, 3180 retval = ext4_mark_inode_dirty(handle, old_inode);
2994 old_inode,
2995 dir_bh);
2996 } 3181 }
2997 if (retval) { 3182 if (retval) {
2998 ext4_std_error(old_dir->i_sb, retval); 3183 ext4_std_error(old_dir->i_sb, retval);
@@ -3043,23 +3228,19 @@ const struct inode_operations ext4_dir_inode_operations = {
3043 .mknod = ext4_mknod, 3228 .mknod = ext4_mknod,
3044 .rename = ext4_rename, 3229 .rename = ext4_rename,
3045 .setattr = ext4_setattr, 3230 .setattr = ext4_setattr,
3046#ifdef CONFIG_EXT4_FS_XATTR
3047 .setxattr = generic_setxattr, 3231 .setxattr = generic_setxattr,
3048 .getxattr = generic_getxattr, 3232 .getxattr = generic_getxattr,
3049 .listxattr = ext4_listxattr, 3233 .listxattr = ext4_listxattr,
3050 .removexattr = generic_removexattr, 3234 .removexattr = generic_removexattr,
3051#endif
3052 .get_acl = ext4_get_acl, 3235 .get_acl = ext4_get_acl,
3053 .fiemap = ext4_fiemap, 3236 .fiemap = ext4_fiemap,
3054}; 3237};
3055 3238
3056const struct inode_operations ext4_special_inode_operations = { 3239const struct inode_operations ext4_special_inode_operations = {
3057 .setattr = ext4_setattr, 3240 .setattr = ext4_setattr,
3058#ifdef CONFIG_EXT4_FS_XATTR
3059 .setxattr = generic_setxattr, 3241 .setxattr = generic_setxattr,
3060 .getxattr = generic_getxattr, 3242 .getxattr = generic_getxattr,
3061 .listxattr = ext4_listxattr, 3243 .listxattr = ext4_listxattr,
3062 .removexattr = generic_removexattr, 3244 .removexattr = generic_removexattr,
3063#endif
3064 .get_acl = ext4_get_acl, 3245 .get_acl = ext4_get_acl,
3065}; 3246};