dir.c revision 399368372ed9f3c396eadb5c2bbc98be8c774a39
10a8165d7c2cf1395059db20ab07665baf3758fcdJaegeuk Kim/* 26b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim * fs/f2fs/dir.c 36b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim * 46b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim * Copyright (c) 2012 Samsung Electronics Co., Ltd. 56b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim * http://www.samsung.com/ 66b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim * 76b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim * This program is free software; you can redistribute it and/or modify 86b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim * it under the terms of the GNU General Public License version 2 as 96b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim * published by the Free Software Foundation. 106b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim */ 116b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim#include <linux/fs.h> 126b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim#include <linux/f2fs_fs.h> 136b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim#include "f2fs.h" 14398b1ac5a57219823f942a8d3665b27ab99354deJaegeuk Kim#include "node.h" 156b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim#include "acl.h" 166b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 176b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimstatic unsigned long dir_blocks(struct inode *inode) 186b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 196b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return ((unsigned long long) (i_size_read(inode) + PAGE_CACHE_SIZE - 1)) 206b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim >> PAGE_CACHE_SHIFT; 216b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 226b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 236b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimstatic unsigned int dir_buckets(unsigned int level) 246b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 256b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (level < MAX_DIR_HASH_DEPTH / 2) 266b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return 1 << level; 276b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim else 286b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return 1 << ((MAX_DIR_HASH_DEPTH / 2) - 1); 296b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 306b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 316b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimstatic unsigned int bucket_blocks(unsigned int level) 326b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 336b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (level < MAX_DIR_HASH_DEPTH / 2) 346b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return 2; 356b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim else 366b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return 4; 376b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 386b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 396b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimstatic unsigned char f2fs_filetype_table[F2FS_FT_MAX] = { 406b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim [F2FS_FT_UNKNOWN] = DT_UNKNOWN, 416b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim [F2FS_FT_REG_FILE] = DT_REG, 426b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim [F2FS_FT_DIR] = DT_DIR, 436b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim [F2FS_FT_CHRDEV] = DT_CHR, 446b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim [F2FS_FT_BLKDEV] = DT_BLK, 456b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim [F2FS_FT_FIFO] = DT_FIFO, 466b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim [F2FS_FT_SOCK] = DT_SOCK, 476b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim [F2FS_FT_SYMLINK] = DT_LNK, 486b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim}; 496b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 506b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim#define S_SHIFT 12 516b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimstatic unsigned char f2fs_type_by_mode[S_IFMT >> S_SHIFT] = { 526b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim [S_IFREG >> S_SHIFT] = F2FS_FT_REG_FILE, 536b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim [S_IFDIR >> S_SHIFT] = F2FS_FT_DIR, 546b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim [S_IFCHR >> S_SHIFT] = F2FS_FT_CHRDEV, 556b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim [S_IFBLK >> S_SHIFT] = F2FS_FT_BLKDEV, 566b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim [S_IFIFO >> S_SHIFT] = F2FS_FT_FIFO, 576b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim [S_IFSOCK >> S_SHIFT] = F2FS_FT_SOCK, 586b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim [S_IFLNK >> S_SHIFT] = F2FS_FT_SYMLINK, 596b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim}; 606b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 616b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimstatic void set_de_type(struct f2fs_dir_entry *de, struct inode *inode) 626b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 636b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim mode_t mode = inode->i_mode; 646b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim de->file_type = f2fs_type_by_mode[(mode & S_IFMT) >> S_SHIFT]; 656b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 666b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 676b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimstatic unsigned long dir_block_index(unsigned int level, unsigned int idx) 686b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 696b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned long i; 706b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned long bidx = 0; 716b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 726b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim for (i = 0; i < level; i++) 736b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bidx += dir_buckets(i) * bucket_blocks(i); 746b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bidx += idx * bucket_blocks(level); 756b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return bidx; 766b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 776b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 789836b8b9499cb25ea32cad9fff640eef874c5431Leon Romanovskystatic bool early_match_name(const char *name, size_t namelen, 796b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_hash_t namehash, struct f2fs_dir_entry *de) 806b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 816b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (le16_to_cpu(de->name_len) != namelen) 826b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return false; 836b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 8425ca923b2a766b9c93b63777ead351137533a623Jaegeuk Kim if (de->hash_code != namehash) 856b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return false; 866b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 876b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return true; 886b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 896b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 906b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimstatic struct f2fs_dir_entry *find_in_block(struct page *dentry_page, 919836b8b9499cb25ea32cad9fff640eef874c5431Leon Romanovsky const char *name, size_t namelen, int *max_slots, 926b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_hash_t namehash, struct page **res_page) 936b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 946b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_dir_entry *de; 956b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned long bit_pos, end_pos, next_pos; 966b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_dentry_block *dentry_blk = kmap(dentry_page); 976b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim int slots; 986b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 996b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap, 1006b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim NR_DENTRY_IN_BLOCK, 0); 1016b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim while (bit_pos < NR_DENTRY_IN_BLOCK) { 1026b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim de = &dentry_blk->dentry[bit_pos]; 103457d08ee4fd91c8df17917ff2d32565e6adacbfcNamjae Jeon slots = GET_DENTRY_SLOTS(le16_to_cpu(de->name_len)); 1046b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 1056b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (early_match_name(name, namelen, namehash, de)) { 1066b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (!memcmp(dentry_blk->filename[bit_pos], 1076b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim name, namelen)) { 1086b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim *res_page = dentry_page; 1096b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim goto found; 1106b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 1116b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 1126b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim next_pos = bit_pos + slots; 1136b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap, 1146b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim NR_DENTRY_IN_BLOCK, next_pos); 1156b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (bit_pos >= NR_DENTRY_IN_BLOCK) 1166b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim end_pos = NR_DENTRY_IN_BLOCK; 1176b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim else 1186b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim end_pos = bit_pos; 1196b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (*max_slots < end_pos - next_pos) 1206b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim *max_slots = end_pos - next_pos; 1216b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 1226b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 1236b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim de = NULL; 1246b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim kunmap(dentry_page); 1256b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimfound: 1266b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return de; 1276b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 1286b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 1296b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimstatic struct f2fs_dir_entry *find_in_level(struct inode *dir, 1309836b8b9499cb25ea32cad9fff640eef874c5431Leon Romanovsky unsigned int level, const char *name, size_t namelen, 1316b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_hash_t namehash, struct page **res_page) 1326b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 133457d08ee4fd91c8df17917ff2d32565e6adacbfcNamjae Jeon int s = GET_DENTRY_SLOTS(namelen); 1346b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned int nbucket, nblock; 1356b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned int bidx, end_block; 1366b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct page *dentry_page; 1376b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_dir_entry *de = NULL; 1386b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bool room = false; 1396b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim int max_slots = 0; 1406b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 1416b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim BUG_ON(level > MAX_DIR_HASH_DEPTH); 1426b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 1436b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim nbucket = dir_buckets(level); 1446b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim nblock = bucket_blocks(level); 1456b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 14625ca923b2a766b9c93b63777ead351137533a623Jaegeuk Kim bidx = dir_block_index(level, le32_to_cpu(namehash) % nbucket); 1476b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim end_block = bidx + nblock; 1486b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 1496b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim for (; bidx < end_block; bidx++) { 1506b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim /* no need to allocate new dentry pages to all the indices */ 1516b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dentry_page = find_data_page(dir, bidx); 1526b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (IS_ERR(dentry_page)) { 1536b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim room = true; 1546b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim continue; 1556b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 1566b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 1576b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim de = find_in_block(dentry_page, name, namelen, 1586b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim &max_slots, namehash, res_page); 1596b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (de) 1606b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim break; 1616b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 1626b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (max_slots >= s) 1636b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim room = true; 1646b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_put_page(dentry_page, 0); 1656b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 1666b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 1676b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (!de && room && F2FS_I(dir)->chash != namehash) { 1686b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim F2FS_I(dir)->chash = namehash; 1696b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim F2FS_I(dir)->clevel = level; 1706b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 1716b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 1726b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return de; 1736b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 1746b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 1756b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim/* 1766b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim * Find an entry in the specified directory with the wanted name. 1776b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim * It returns the page where the entry was found (as a parameter - res_page), 1786b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim * and the entry itself. Page is returned mapped and unlocked. 1796b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim * Entry is guaranteed to be valid. 1806b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim */ 1816b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimstruct f2fs_dir_entry *f2fs_find_entry(struct inode *dir, 1826b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct qstr *child, struct page **res_page) 1836b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 1846b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim const char *name = child->name; 1859836b8b9499cb25ea32cad9fff640eef874c5431Leon Romanovsky size_t namelen = child->len; 1866b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned long npages = dir_blocks(dir); 1876b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_dir_entry *de = NULL; 1886b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_hash_t name_hash; 1896b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned int max_depth; 1906b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned int level; 1916b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 1925a20d339c785d98d8b050b9afc098e4184a6098cJaegeuk Kim if (namelen > F2FS_NAME_LEN) 1935a20d339c785d98d8b050b9afc098e4184a6098cJaegeuk Kim return NULL; 1945a20d339c785d98d8b050b9afc098e4184a6098cJaegeuk Kim 1956b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (npages == 0) 1966b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return NULL; 1976b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 1986b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim *res_page = NULL; 1996b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 2006b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim name_hash = f2fs_dentry_hash(name, namelen); 2016b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim max_depth = F2FS_I(dir)->i_current_depth; 2026b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 2036b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim for (level = 0; level < max_depth; level++) { 2046b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim de = find_in_level(dir, level, name, 2056b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim namelen, name_hash, res_page); 2066b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (de) 2076b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim break; 2086b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 2096b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (!de && F2FS_I(dir)->chash != name_hash) { 2106b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim F2FS_I(dir)->chash = name_hash; 2116b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim F2FS_I(dir)->clevel = level - 1; 2126b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 2136b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return de; 2146b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 2156b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 2166b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimstruct f2fs_dir_entry *f2fs_parent_dir(struct inode *dir, struct page **p) 2176b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 2186b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct page *page = NULL; 2196b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_dir_entry *de = NULL; 2206b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_dentry_block *dentry_blk = NULL; 2216b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 2226b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim page = get_lock_data_page(dir, 0); 2236b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (IS_ERR(page)) 2246b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return NULL; 2256b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 2266b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dentry_blk = kmap(page); 2276b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim de = &dentry_blk->dentry[1]; 2286b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim *p = page; 2296b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unlock_page(page); 2306b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return de; 2316b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 2326b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 2336b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimino_t f2fs_inode_by_name(struct inode *dir, struct qstr *qstr) 2346b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 2356b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim ino_t res = 0; 2366b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_dir_entry *de; 2376b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct page *page; 2386b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 2396b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim de = f2fs_find_entry(dir, qstr, &page); 2406b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (de) { 2416b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim res = le32_to_cpu(de->ino); 2426b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim kunmap(page); 2436b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_put_page(page, 0); 2446b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 2456b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 2466b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return res; 2476b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 2486b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 2496b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimvoid f2fs_set_link(struct inode *dir, struct f2fs_dir_entry *de, 2506b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct page *page, struct inode *inode) 2516b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 2526b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim lock_page(page); 2536b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim wait_on_page_writeback(page); 2546b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim de->ino = cpu_to_le32(inode->i_ino); 2556b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim set_de_type(de, inode); 2566b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim kunmap(page); 2576b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim set_page_dirty(page); 2586b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dir->i_mtime = dir->i_ctime = CURRENT_TIME; 2596b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim mark_inode_dirty(dir); 2606666e6aa9f36b2bfd6b30072c07b34f2a24becf1Jaegeuk Kim 2616666e6aa9f36b2bfd6b30072c07b34f2a24becf1Jaegeuk Kim /* update parent inode number before releasing dentry page */ 2626666e6aa9f36b2bfd6b30072c07b34f2a24becf1Jaegeuk Kim F2FS_I(inode)->i_pino = dir->i_ino; 2636666e6aa9f36b2bfd6b30072c07b34f2a24becf1Jaegeuk Kim 2646b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_put_page(page, 1); 2656b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 2666b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 26753dc9a67769d0a9733adb5156adfc07edcbc1ea3Al Virovoid init_dent_inode(const struct qstr *name, struct page *ipage) 2686b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 2696b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_node *rn; 2706b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 2716b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (IS_ERR(ipage)) 2726b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return; 2736b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 2746b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim wait_on_page_writeback(ipage); 2756b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 27653dc9a67769d0a9733adb5156adfc07edcbc1ea3Al Viro /* copy name info. to this inode page */ 2776b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim rn = (struct f2fs_node *)page_address(ipage); 27853dc9a67769d0a9733adb5156adfc07edcbc1ea3Al Viro rn->i.i_namelen = cpu_to_le32(name->len); 27953dc9a67769d0a9733adb5156adfc07edcbc1ea3Al Viro memcpy(rn->i.i_name, name->name, name->len); 2806b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim set_page_dirty(ipage); 2816b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 2826b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 283399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kimstatic int make_empty_dir(struct inode *inode, struct inode *parent) 284399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim{ 285399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim struct page *dentry_page; 286399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim struct f2fs_dentry_block *dentry_blk; 287399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim struct f2fs_dir_entry *de; 288399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim void *kaddr; 289399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim 290399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim dentry_page = get_new_data_page(inode, 0, true); 291399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim if (IS_ERR(dentry_page)) 292399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim return PTR_ERR(dentry_page); 293399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim 294399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim kaddr = kmap_atomic(dentry_page); 295399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim dentry_blk = (struct f2fs_dentry_block *)kaddr; 296399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim 297399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim de = &dentry_blk->dentry[0]; 298399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim de->name_len = cpu_to_le16(1); 299399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim de->hash_code = 0; 300399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim de->ino = cpu_to_le32(inode->i_ino); 301399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim memcpy(dentry_blk->filename[0], ".", 1); 302399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim set_de_type(de, inode); 303399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim 304399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim de = &dentry_blk->dentry[1]; 305399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim de->hash_code = 0; 306399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim de->name_len = cpu_to_le16(2); 307399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim de->ino = cpu_to_le32(parent->i_ino); 308399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim memcpy(dentry_blk->filename[1], "..", 2); 309399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim set_de_type(de, inode); 310399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim 311399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim test_and_set_bit_le(0, &dentry_blk->dentry_bitmap); 312399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim test_and_set_bit_le(1, &dentry_blk->dentry_bitmap); 313399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim kunmap_atomic(kaddr); 314399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim 315399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim set_page_dirty(dentry_page); 316399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim f2fs_put_page(dentry_page, 1); 317399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim return 0; 318399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim} 319399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim 32069f24eac55725859a89c440ee2d19f36fa09e8fcAl Virostatic int init_inode_metadata(struct inode *inode, 32169f24eac55725859a89c440ee2d19f36fa09e8fcAl Viro struct inode *dir, const struct qstr *name) 3226b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 3236b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (is_inode_flag_set(F2FS_I(inode), FI_NEW_INODE)) { 3246b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim int err; 32569f24eac55725859a89c440ee2d19f36fa09e8fcAl Viro err = new_inode_page(inode, name); 3266b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (err) 3276b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return err; 3286b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 3296b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (S_ISDIR(inode->i_mode)) { 330399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim err = make_empty_dir(inode, dir); 3316b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (err) { 3326b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim remove_inode_page(inode); 3336b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return err; 3346b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 3356b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 3366b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 3376b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim err = f2fs_init_acl(inode, dir); 3386b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (err) { 3396b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim remove_inode_page(inode); 3406b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return err; 3416b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 3426b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } else { 3436b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct page *ipage; 3446b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim ipage = get_node_page(F2FS_SB(dir->i_sb), inode->i_ino); 3456b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (IS_ERR(ipage)) 3466b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return PTR_ERR(ipage); 347398b1ac5a57219823f942a8d3665b27ab99354deJaegeuk Kim set_cold_node(inode, ipage); 34869f24eac55725859a89c440ee2d19f36fa09e8fcAl Viro init_dent_inode(name, ipage); 3496b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_put_page(ipage, 1); 3506b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 3516b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (is_inode_flag_set(F2FS_I(inode), FI_INC_LINK)) { 3526b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim inc_nlink(inode); 353399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim update_inode_page(inode); 3546b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 3556b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return 0; 3566b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 3576b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 3586b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimstatic void update_parent_metadata(struct inode *dir, struct inode *inode, 3596b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned int current_depth) 3606b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 3616b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bool need_dir_update = false; 3626b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 3636b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (is_inode_flag_set(F2FS_I(inode), FI_NEW_INODE)) { 3646b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (S_ISDIR(inode->i_mode)) { 3656b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim inc_nlink(dir); 3666b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim need_dir_update = true; 3676b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 3686b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim clear_inode_flag(F2FS_I(inode), FI_NEW_INODE); 3696b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 3706b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dir->i_mtime = dir->i_ctime = CURRENT_TIME; 3716b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (F2FS_I(dir)->i_current_depth != current_depth) { 3726b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim F2FS_I(dir)->i_current_depth = current_depth; 3736b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim need_dir_update = true; 3746b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 3756b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 3766b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (need_dir_update) 377399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim update_inode_page(dir); 3786b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim else 3796b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim mark_inode_dirty(dir); 3806b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 3816b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (is_inode_flag_set(F2FS_I(inode), FI_INC_LINK)) 3826b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim clear_inode_flag(F2FS_I(inode), FI_INC_LINK); 3836b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 3846b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 3856b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimstatic int room_for_filename(struct f2fs_dentry_block *dentry_blk, int slots) 3866b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 3876b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim int bit_start = 0; 3886b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim int zero_start, zero_end; 3896b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimnext: 3906b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim zero_start = find_next_zero_bit_le(&dentry_blk->dentry_bitmap, 3916b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim NR_DENTRY_IN_BLOCK, 3926b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_start); 3936b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (zero_start >= NR_DENTRY_IN_BLOCK) 3946b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return NR_DENTRY_IN_BLOCK; 3956b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 3966b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim zero_end = find_next_bit_le(&dentry_blk->dentry_bitmap, 3976b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim NR_DENTRY_IN_BLOCK, 3986b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim zero_start); 3996b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (zero_end - zero_start >= slots) 4006b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return zero_start; 4016b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 4026b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_start = zero_end + 1; 4036b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 4046b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (zero_end + 1 >= NR_DENTRY_IN_BLOCK) 4056b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return NR_DENTRY_IN_BLOCK; 4066b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim goto next; 4076b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 4086b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 409399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim/* 410399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim * Caller should grab and release a mutex by calling mutex_lock_op() and 411399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim * mutex_unlock_op(). 412399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim */ 413b7f7a5e0be94d13875a1c6c9aa65eeb11a46fc1bAl Viroint __f2fs_add_link(struct inode *dir, const struct qstr *name, struct inode *inode) 4146b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 4156b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned int bit_pos; 4166b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned int level; 4176b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned int current_depth; 4186b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned long bidx, block; 4196b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_hash_t dentry_hash; 4206b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_dir_entry *de; 4216b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned int nbucket, nblock; 422b7f7a5e0be94d13875a1c6c9aa65eeb11a46fc1bAl Viro size_t namelen = name->len; 4236b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct page *dentry_page = NULL; 4246b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_dentry_block *dentry_blk = NULL; 425457d08ee4fd91c8df17917ff2d32565e6adacbfcNamjae Jeon int slots = GET_DENTRY_SLOTS(namelen); 4266b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim int err = 0; 4276b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim int i; 4286b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 429b7f7a5e0be94d13875a1c6c9aa65eeb11a46fc1bAl Viro dentry_hash = f2fs_dentry_hash(name->name, name->len); 4306b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim level = 0; 4316b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim current_depth = F2FS_I(dir)->i_current_depth; 4326b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (F2FS_I(dir)->chash == dentry_hash) { 4336b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim level = F2FS_I(dir)->clevel; 4346b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim F2FS_I(dir)->chash = 0; 4356b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 4366b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 4376b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimstart: 4386b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (current_depth == MAX_DIR_HASH_DEPTH) 4396b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return -ENOSPC; 4406b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 4416b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim /* Increase the depth, if required */ 4426b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (level == current_depth) 4436b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim ++current_depth; 4446b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 4456b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim nbucket = dir_buckets(level); 4466b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim nblock = bucket_blocks(level); 4476b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 44825ca923b2a766b9c93b63777ead351137533a623Jaegeuk Kim bidx = dir_block_index(level, (le32_to_cpu(dentry_hash) % nbucket)); 4496b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 4506b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim for (block = bidx; block <= (bidx + nblock - 1); block++) { 4516b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dentry_page = get_new_data_page(dir, block, true); 452399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim if (IS_ERR(dentry_page)) 4536b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return PTR_ERR(dentry_page); 4546b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 4556b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dentry_blk = kmap(dentry_page); 4566b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_pos = room_for_filename(dentry_blk, slots); 4576b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (bit_pos < NR_DENTRY_IN_BLOCK) 4586b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim goto add_dentry; 4596b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 4606b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim kunmap(dentry_page); 4616b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_put_page(dentry_page, 1); 4626b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 4636b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 4646b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim /* Move to next level to find the empty slot for new dentry */ 4656b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim ++level; 4666b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim goto start; 4676b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimadd_dentry: 468b7f7a5e0be94d13875a1c6c9aa65eeb11a46fc1bAl Viro err = init_inode_metadata(inode, dir, name); 4696b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (err) 4706b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim goto fail; 4716b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 4726b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim wait_on_page_writeback(dentry_page); 4736b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 4746b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim de = &dentry_blk->dentry[bit_pos]; 47525ca923b2a766b9c93b63777ead351137533a623Jaegeuk Kim de->hash_code = dentry_hash; 4766b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim de->name_len = cpu_to_le16(namelen); 477b7f7a5e0be94d13875a1c6c9aa65eeb11a46fc1bAl Viro memcpy(dentry_blk->filename[bit_pos], name->name, name->len); 4786b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim de->ino = cpu_to_le32(inode->i_ino); 4796b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim set_de_type(de, inode); 4806b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim for (i = 0; i < slots; i++) 4816b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim test_and_set_bit_le(bit_pos + i, &dentry_blk->dentry_bitmap); 4826b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim set_page_dirty(dentry_page); 4836666e6aa9f36b2bfd6b30072c07b34f2a24becf1Jaegeuk Kim 4846b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim update_parent_metadata(dir, inode, current_depth); 4856666e6aa9f36b2bfd6b30072c07b34f2a24becf1Jaegeuk Kim 4866666e6aa9f36b2bfd6b30072c07b34f2a24becf1Jaegeuk Kim /* update parent inode number before releasing dentry page */ 4876666e6aa9f36b2bfd6b30072c07b34f2a24becf1Jaegeuk Kim F2FS_I(inode)->i_pino = dir->i_ino; 4886b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimfail: 4896b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim kunmap(dentry_page); 4906b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_put_page(dentry_page, 1); 4916b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return err; 4926b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 4936b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 4940a8165d7c2cf1395059db20ab07665baf3758fcdJaegeuk Kim/* 4956b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim * It only removes the dentry from the dentry page,corresponding name 4966b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim * entry in name page does not need to be touched during deletion. 4976b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim */ 4986b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimvoid f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page, 4996b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct inode *inode) 5006b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 5016b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_dentry_block *dentry_blk; 5026b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned int bit_pos; 5036b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct address_space *mapping = page->mapping; 5046b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct inode *dir = mapping->host; 5056b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb); 506457d08ee4fd91c8df17917ff2d32565e6adacbfcNamjae Jeon int slots = GET_DENTRY_SLOTS(le16_to_cpu(dentry->name_len)); 5076b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim void *kaddr = page_address(page); 5086b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim int i; 5096b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 5106b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim lock_page(page); 5116b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim wait_on_page_writeback(page); 5126b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 5136b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dentry_blk = (struct f2fs_dentry_block *)kaddr; 5146b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_pos = dentry - (struct f2fs_dir_entry *)dentry_blk->dentry; 5156b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim for (i = 0; i < slots; i++) 5166b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim test_and_clear_bit_le(bit_pos + i, &dentry_blk->dentry_bitmap); 5176b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 5186b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim /* Let's check and deallocate this dentry page */ 5196b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap, 5206b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim NR_DENTRY_IN_BLOCK, 5216b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 0); 5226b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim kunmap(page); /* kunmap - pair of f2fs_find_entry */ 5236b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim set_page_dirty(page); 5246b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 5256b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dir->i_ctime = dir->i_mtime = CURRENT_TIME; 5266b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 5276b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (inode && S_ISDIR(inode->i_mode)) { 5286b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim drop_nlink(dir); 529399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim update_inode_page(dir); 5306b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } else { 5316b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim mark_inode_dirty(dir); 5326b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 5336b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 5346b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (inode) { 535163799872b65b0cbf0091d82971233cc3d2425d3Namjae Jeon inode->i_ctime = CURRENT_TIME; 5366b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim drop_nlink(inode); 5376b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (S_ISDIR(inode->i_mode)) { 5386b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim drop_nlink(inode); 5396b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim i_size_write(inode, 0); 5406b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 541399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim update_inode_page(inode); 542399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim 5436b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (inode->i_nlink == 0) 5446b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim add_orphan_inode(sbi, inode->i_ino); 5456b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 5466b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 5476b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (bit_pos == NR_DENTRY_IN_BLOCK) { 5486b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim truncate_hole(dir, page->index, page->index + 1); 5496b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim clear_page_dirty_for_io(page); 5506b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim ClearPageUptodate(page); 5516b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dec_page_count(sbi, F2FS_DIRTY_DENTS); 5526b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim inode_dec_dirty_dents(dir); 5536b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 554508198be3c2f7f8929101bb0daeb8f0039c1dc7fNamjae Jeon f2fs_put_page(page, 1); 5556b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 5566b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 5576b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimbool f2fs_empty_dir(struct inode *dir) 5586b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 5596b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned long bidx; 5606b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct page *dentry_page; 5616b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned int bit_pos; 5626b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_dentry_block *dentry_blk; 5636b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned long nblock = dir_blocks(dir); 5646b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 5656b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim for (bidx = 0; bidx < nblock; bidx++) { 5666b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim void *kaddr; 5676b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dentry_page = get_lock_data_page(dir, bidx); 5686b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (IS_ERR(dentry_page)) { 5696b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (PTR_ERR(dentry_page) == -ENOENT) 5706b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim continue; 5716b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim else 5726b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return false; 5736b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 5746b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 5756b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim kaddr = kmap_atomic(dentry_page); 5766b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dentry_blk = (struct f2fs_dentry_block *)kaddr; 5776b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (bidx == 0) 5786b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_pos = 2; 5796b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim else 5806b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_pos = 0; 5816b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap, 5826b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim NR_DENTRY_IN_BLOCK, 5836b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_pos); 5846b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim kunmap_atomic(kaddr); 5856b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 5866b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_put_page(dentry_page, 1); 5876b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 5886b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (bit_pos < NR_DENTRY_IN_BLOCK) 5896b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return false; 5906b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 5916b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return true; 5926b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 5936b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 5946b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimstatic int f2fs_readdir(struct file *file, void *dirent, filldir_t filldir) 5956b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 5966b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned long pos = file->f_pos; 597496ad9aa8ef448058e36ca7a787c61f2e63f0f54Al Viro struct inode *inode = file_inode(file); 5986b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned long npages = dir_blocks(inode); 5996b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned char *types = NULL; 6006b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned int bit_pos = 0, start_bit_pos = 0; 6016b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim int over = 0; 6026b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_dentry_block *dentry_blk = NULL; 6036b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_dir_entry *de = NULL; 6046b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct page *dentry_page = NULL; 6056b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned int n = 0; 6066b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned char d_type = DT_UNKNOWN; 6076b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim int slots; 6086b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 6096b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim types = f2fs_filetype_table; 6106b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_pos = (pos % NR_DENTRY_IN_BLOCK); 6116b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim n = (pos / NR_DENTRY_IN_BLOCK); 6126b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 6136b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim for ( ; n < npages; n++) { 6146b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dentry_page = get_lock_data_page(inode, n); 6156b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (IS_ERR(dentry_page)) 6166b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim continue; 6176b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 6186b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim start_bit_pos = bit_pos; 6196b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dentry_blk = kmap(dentry_page); 6206b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim while (bit_pos < NR_DENTRY_IN_BLOCK) { 6216b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim d_type = DT_UNKNOWN; 6226b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap, 6236b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim NR_DENTRY_IN_BLOCK, 6246b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_pos); 6256b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (bit_pos >= NR_DENTRY_IN_BLOCK) 6266b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim break; 6276b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 6286b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim de = &dentry_blk->dentry[bit_pos]; 6296b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (types && de->file_type < F2FS_FT_MAX) 6306b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim d_type = types[de->file_type]; 6316b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 6326b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim over = filldir(dirent, 6336b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dentry_blk->filename[bit_pos], 6346b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim le16_to_cpu(de->name_len), 6356b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim (n * NR_DENTRY_IN_BLOCK) + bit_pos, 6366b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim le32_to_cpu(de->ino), d_type); 6376b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (over) { 6386b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim file->f_pos += bit_pos - start_bit_pos; 6396b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim goto success; 6406b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 641457d08ee4fd91c8df17917ff2d32565e6adacbfcNamjae Jeon slots = GET_DENTRY_SLOTS(le16_to_cpu(de->name_len)); 6426b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_pos += slots; 6436b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 6446b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_pos = 0; 6456b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim file->f_pos = (n + 1) * NR_DENTRY_IN_BLOCK; 6466b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim kunmap(dentry_page); 6476b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_put_page(dentry_page, 1); 6486b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dentry_page = NULL; 6496b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 6506b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimsuccess: 6516b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (dentry_page && !IS_ERR(dentry_page)) { 6526b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim kunmap(dentry_page); 6536b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_put_page(dentry_page, 1); 6546b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 6556b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 6566b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return 0; 6576b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 6586b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 6596b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimconst struct file_operations f2fs_dir_operations = { 6606b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim .llseek = generic_file_llseek, 6616b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim .read = generic_read_dir, 6626b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim .readdir = f2fs_readdir, 6636b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim .fsync = f2fs_sync_file, 6646b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim .unlocked_ioctl = f2fs_ioctl, 6656b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim}; 666