dir.c revision 69f24eac55725859a89c440ee2d19f36fa09e8fc
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 1926b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (npages == 0) 1936b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return NULL; 1946b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 1956b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim *res_page = NULL; 1966b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 1976b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim name_hash = f2fs_dentry_hash(name, namelen); 1986b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim max_depth = F2FS_I(dir)->i_current_depth; 1996b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 2006b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim for (level = 0; level < max_depth; level++) { 2016b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim de = find_in_level(dir, level, name, 2026b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim namelen, name_hash, res_page); 2036b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (de) 2046b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim break; 2056b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 2066b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (!de && F2FS_I(dir)->chash != name_hash) { 2076b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim F2FS_I(dir)->chash = name_hash; 2086b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim F2FS_I(dir)->clevel = level - 1; 2096b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 2106b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return de; 2116b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 2126b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 2136b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimstruct f2fs_dir_entry *f2fs_parent_dir(struct inode *dir, struct page **p) 2146b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 2156b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct page *page = NULL; 2166b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_dir_entry *de = NULL; 2176b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_dentry_block *dentry_blk = NULL; 2186b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 2196b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim page = get_lock_data_page(dir, 0); 2206b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (IS_ERR(page)) 2216b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return NULL; 2226b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 2236b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dentry_blk = kmap(page); 2246b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim de = &dentry_blk->dentry[1]; 2256b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim *p = page; 2266b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unlock_page(page); 2276b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return de; 2286b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 2296b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 2306b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimino_t f2fs_inode_by_name(struct inode *dir, struct qstr *qstr) 2316b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 2326b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim ino_t res = 0; 2336b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_dir_entry *de; 2346b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct page *page; 2356b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 2366b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim de = f2fs_find_entry(dir, qstr, &page); 2376b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (de) { 2386b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim res = le32_to_cpu(de->ino); 2396b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim kunmap(page); 2406b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_put_page(page, 0); 2416b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 2426b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 2436b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return res; 2446b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 2456b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 2466b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimvoid f2fs_set_link(struct inode *dir, struct f2fs_dir_entry *de, 2476b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct page *page, struct inode *inode) 2486b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 2496b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb); 2506b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 2516b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim mutex_lock_op(sbi, DENTRY_OPS); 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 mutex_unlock_op(sbi, DENTRY_OPS); 2666b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 2676b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 26853dc9a67769d0a9733adb5156adfc07edcbc1ea3Al Virovoid init_dent_inode(const struct qstr *name, struct page *ipage) 2696b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 2706b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_node *rn; 2716b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 2726b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (IS_ERR(ipage)) 2736b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return; 2746b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 2756b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim wait_on_page_writeback(ipage); 2766b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 27753dc9a67769d0a9733adb5156adfc07edcbc1ea3Al Viro /* copy name info. to this inode page */ 2786b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim rn = (struct f2fs_node *)page_address(ipage); 27953dc9a67769d0a9733adb5156adfc07edcbc1ea3Al Viro rn->i.i_namelen = cpu_to_le32(name->len); 28053dc9a67769d0a9733adb5156adfc07edcbc1ea3Al Viro memcpy(rn->i.i_name, name->name, name->len); 2816b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim set_page_dirty(ipage); 2826b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 2836b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 28469f24eac55725859a89c440ee2d19f36fa09e8fcAl Virostatic int init_inode_metadata(struct inode *inode, 28569f24eac55725859a89c440ee2d19f36fa09e8fcAl Viro struct inode *dir, const struct qstr *name) 2866b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 2876b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (is_inode_flag_set(F2FS_I(inode), FI_NEW_INODE)) { 2886b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim int err; 28969f24eac55725859a89c440ee2d19f36fa09e8fcAl Viro err = new_inode_page(inode, name); 2906b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (err) 2916b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return err; 2926b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 2936b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (S_ISDIR(inode->i_mode)) { 2946b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim err = f2fs_make_empty(inode, dir); 2956b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (err) { 2966b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim remove_inode_page(inode); 2976b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return err; 2986b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 2996b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 3006b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 3016b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim err = f2fs_init_acl(inode, dir); 3026b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (err) { 3036b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim remove_inode_page(inode); 3046b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return err; 3056b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 3066b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } else { 3076b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct page *ipage; 3086b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim ipage = get_node_page(F2FS_SB(dir->i_sb), inode->i_ino); 3096b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (IS_ERR(ipage)) 3106b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return PTR_ERR(ipage); 311398b1ac5a57219823f942a8d3665b27ab99354deJaegeuk Kim set_cold_node(inode, ipage); 31269f24eac55725859a89c440ee2d19f36fa09e8fcAl Viro init_dent_inode(name, ipage); 3136b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_put_page(ipage, 1); 3146b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 3156b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (is_inode_flag_set(F2FS_I(inode), FI_INC_LINK)) { 3166b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim inc_nlink(inode); 3176b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_write_inode(inode, NULL); 3186b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 3196b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return 0; 3206b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 3216b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 3226b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimstatic void update_parent_metadata(struct inode *dir, struct inode *inode, 3236b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned int current_depth) 3246b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 3256b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bool need_dir_update = false; 3266b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 3276b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (is_inode_flag_set(F2FS_I(inode), FI_NEW_INODE)) { 3286b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (S_ISDIR(inode->i_mode)) { 3296b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim inc_nlink(dir); 3306b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim need_dir_update = true; 3316b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 3326b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim clear_inode_flag(F2FS_I(inode), FI_NEW_INODE); 3336b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 3346b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dir->i_mtime = dir->i_ctime = CURRENT_TIME; 3356b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (F2FS_I(dir)->i_current_depth != current_depth) { 3366b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim F2FS_I(dir)->i_current_depth = current_depth; 3376b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim need_dir_update = true; 3386b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 3396b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 3406b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (need_dir_update) 3416b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_write_inode(dir, NULL); 3426b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim else 3436b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim mark_inode_dirty(dir); 3446b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 3456b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (is_inode_flag_set(F2FS_I(inode), FI_INC_LINK)) 3466b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim clear_inode_flag(F2FS_I(inode), FI_INC_LINK); 3476b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 3486b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 3496b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimstatic int room_for_filename(struct f2fs_dentry_block *dentry_blk, int slots) 3506b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 3516b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim int bit_start = 0; 3526b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim int zero_start, zero_end; 3536b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimnext: 3546b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim zero_start = find_next_zero_bit_le(&dentry_blk->dentry_bitmap, 3556b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim NR_DENTRY_IN_BLOCK, 3566b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_start); 3576b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (zero_start >= NR_DENTRY_IN_BLOCK) 3586b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return NR_DENTRY_IN_BLOCK; 3596b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 3606b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim zero_end = find_next_bit_le(&dentry_blk->dentry_bitmap, 3616b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim NR_DENTRY_IN_BLOCK, 3626b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim zero_start); 3636b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (zero_end - zero_start >= slots) 3646b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return zero_start; 3656b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 3666b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_start = zero_end + 1; 3676b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 3686b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (zero_end + 1 >= NR_DENTRY_IN_BLOCK) 3696b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return NR_DENTRY_IN_BLOCK; 3706b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim goto next; 3716b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 3726b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 3736b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimint f2fs_add_link(struct dentry *dentry, struct inode *inode) 3746b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 3756b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned int bit_pos; 3766b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned int level; 3776b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned int current_depth; 3786b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned long bidx, block; 3796b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_hash_t dentry_hash; 3806b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_dir_entry *de; 3816b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned int nbucket, nblock; 3826b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct inode *dir = dentry->d_parent->d_inode; 3836b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb); 3846b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim const char *name = dentry->d_name.name; 3859836b8b9499cb25ea32cad9fff640eef874c5431Leon Romanovsky size_t namelen = dentry->d_name.len; 3866b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct page *dentry_page = NULL; 3876b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_dentry_block *dentry_blk = NULL; 388457d08ee4fd91c8df17917ff2d32565e6adacbfcNamjae Jeon int slots = GET_DENTRY_SLOTS(namelen); 3896b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim int err = 0; 3906b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim int i; 3916b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 3926b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dentry_hash = f2fs_dentry_hash(name, dentry->d_name.len); 3936b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim level = 0; 3946b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim current_depth = F2FS_I(dir)->i_current_depth; 3956b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (F2FS_I(dir)->chash == dentry_hash) { 3966b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim level = F2FS_I(dir)->clevel; 3976b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim F2FS_I(dir)->chash = 0; 3986b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 3996b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 4006b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimstart: 4016b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (current_depth == MAX_DIR_HASH_DEPTH) 4026b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return -ENOSPC; 4036b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 4046b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim /* Increase the depth, if required */ 4056b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (level == current_depth) 4066b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim ++current_depth; 4076b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 4086b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim nbucket = dir_buckets(level); 4096b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim nblock = bucket_blocks(level); 4106b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 41125ca923b2a766b9c93b63777ead351137533a623Jaegeuk Kim bidx = dir_block_index(level, (le32_to_cpu(dentry_hash) % nbucket)); 4126b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 4136b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim for (block = bidx; block <= (bidx + nblock - 1); block++) { 4146b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim mutex_lock_op(sbi, DENTRY_OPS); 4156b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dentry_page = get_new_data_page(dir, block, true); 4166b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (IS_ERR(dentry_page)) { 4176b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim mutex_unlock_op(sbi, DENTRY_OPS); 4186b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return PTR_ERR(dentry_page); 4196b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 4206b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 4216b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dentry_blk = kmap(dentry_page); 4226b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_pos = room_for_filename(dentry_blk, slots); 4236b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (bit_pos < NR_DENTRY_IN_BLOCK) 4246b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim goto add_dentry; 4256b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 4266b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim kunmap(dentry_page); 4276b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_put_page(dentry_page, 1); 4286b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim mutex_unlock_op(sbi, DENTRY_OPS); 4296b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 4306b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 4316b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim /* Move to next level to find the empty slot for new dentry */ 4326b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim ++level; 4336b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim goto start; 4346b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimadd_dentry: 43569f24eac55725859a89c440ee2d19f36fa09e8fcAl Viro err = init_inode_metadata(inode, dir, &dentry->d_name); 4366b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (err) 4376b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim goto fail; 4386b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 4396b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim wait_on_page_writeback(dentry_page); 4406b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 4416b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim de = &dentry_blk->dentry[bit_pos]; 44225ca923b2a766b9c93b63777ead351137533a623Jaegeuk Kim de->hash_code = dentry_hash; 4436b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim de->name_len = cpu_to_le16(namelen); 4446b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim memcpy(dentry_blk->filename[bit_pos], name, namelen); 4456b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim de->ino = cpu_to_le32(inode->i_ino); 4466b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim set_de_type(de, inode); 4476b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim for (i = 0; i < slots; i++) 4486b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim test_and_set_bit_le(bit_pos + i, &dentry_blk->dentry_bitmap); 4496b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim set_page_dirty(dentry_page); 4506666e6aa9f36b2bfd6b30072c07b34f2a24becf1Jaegeuk Kim 4516b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim update_parent_metadata(dir, inode, current_depth); 4526666e6aa9f36b2bfd6b30072c07b34f2a24becf1Jaegeuk Kim 4536666e6aa9f36b2bfd6b30072c07b34f2a24becf1Jaegeuk Kim /* update parent inode number before releasing dentry page */ 4546666e6aa9f36b2bfd6b30072c07b34f2a24becf1Jaegeuk Kim F2FS_I(inode)->i_pino = dir->i_ino; 4556b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimfail: 4566b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim kunmap(dentry_page); 4576b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_put_page(dentry_page, 1); 4586b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim mutex_unlock_op(sbi, DENTRY_OPS); 4596b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return err; 4606b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 4616b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 4620a8165d7c2cf1395059db20ab07665baf3758fcdJaegeuk Kim/* 4636b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim * It only removes the dentry from the dentry page,corresponding name 4646b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim * entry in name page does not need to be touched during deletion. 4656b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim */ 4666b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimvoid f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page, 4676b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct inode *inode) 4686b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 4696b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_dentry_block *dentry_blk; 4706b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned int bit_pos; 4716b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct address_space *mapping = page->mapping; 4726b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct inode *dir = mapping->host; 4736b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb); 474457d08ee4fd91c8df17917ff2d32565e6adacbfcNamjae Jeon int slots = GET_DENTRY_SLOTS(le16_to_cpu(dentry->name_len)); 4756b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim void *kaddr = page_address(page); 4766b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim int i; 4776b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 4786b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim mutex_lock_op(sbi, DENTRY_OPS); 4796b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 4806b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim lock_page(page); 4816b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim wait_on_page_writeback(page); 4826b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 4836b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dentry_blk = (struct f2fs_dentry_block *)kaddr; 4846b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_pos = dentry - (struct f2fs_dir_entry *)dentry_blk->dentry; 4856b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim for (i = 0; i < slots; i++) 4866b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim test_and_clear_bit_le(bit_pos + i, &dentry_blk->dentry_bitmap); 4876b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 4886b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim /* Let's check and deallocate this dentry page */ 4896b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap, 4906b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim NR_DENTRY_IN_BLOCK, 4916b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 0); 4926b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim kunmap(page); /* kunmap - pair of f2fs_find_entry */ 4936b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim set_page_dirty(page); 4946b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 4956b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dir->i_ctime = dir->i_mtime = CURRENT_TIME; 4966b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 4976b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (inode && S_ISDIR(inode->i_mode)) { 4986b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim drop_nlink(dir); 4996b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_write_inode(dir, NULL); 5006b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } else { 5016b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim mark_inode_dirty(dir); 5026b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 5036b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 5046b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (inode) { 5056b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; 5066b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim drop_nlink(inode); 5076b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (S_ISDIR(inode->i_mode)) { 5086b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim drop_nlink(inode); 5096b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim i_size_write(inode, 0); 5106b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 5116b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_write_inode(inode, NULL); 5126b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (inode->i_nlink == 0) 5136b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim add_orphan_inode(sbi, inode->i_ino); 5146b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 5156b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 5166b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (bit_pos == NR_DENTRY_IN_BLOCK) { 5176b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim truncate_hole(dir, page->index, page->index + 1); 5186b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim clear_page_dirty_for_io(page); 5196b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim ClearPageUptodate(page); 5206b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dec_page_count(sbi, F2FS_DIRTY_DENTS); 5216b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim inode_dec_dirty_dents(dir); 5226b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 523508198be3c2f7f8929101bb0daeb8f0039c1dc7fNamjae Jeon f2fs_put_page(page, 1); 524508198be3c2f7f8929101bb0daeb8f0039c1dc7fNamjae Jeon 5256b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim mutex_unlock_op(sbi, DENTRY_OPS); 5266b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 5276b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 5286b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimint f2fs_make_empty(struct inode *inode, struct inode *parent) 5296b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 5306b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct page *dentry_page; 5316b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_dentry_block *dentry_blk; 5326b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_dir_entry *de; 5336b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim void *kaddr; 5346b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 5356b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dentry_page = get_new_data_page(inode, 0, true); 5366b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (IS_ERR(dentry_page)) 5376b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return PTR_ERR(dentry_page); 5386b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 5396b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim kaddr = kmap_atomic(dentry_page); 5406b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dentry_blk = (struct f2fs_dentry_block *)kaddr; 5416b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 5426b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim de = &dentry_blk->dentry[0]; 5436b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim de->name_len = cpu_to_le16(1); 54438e0abdcfb5e69aa61a1e9b474d434afc1c177a9Namjae Jeon de->hash_code = f2fs_dentry_hash(".", 1); 5456b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim de->ino = cpu_to_le32(inode->i_ino); 5466b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim memcpy(dentry_blk->filename[0], ".", 1); 5476b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim set_de_type(de, inode); 5486b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 5496b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim de = &dentry_blk->dentry[1]; 55038e0abdcfb5e69aa61a1e9b474d434afc1c177a9Namjae Jeon de->hash_code = f2fs_dentry_hash("..", 2); 5516b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim de->name_len = cpu_to_le16(2); 5526b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim de->ino = cpu_to_le32(parent->i_ino); 5536b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim memcpy(dentry_blk->filename[1], "..", 2); 5546b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim set_de_type(de, inode); 5556b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 5566b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim test_and_set_bit_le(0, &dentry_blk->dentry_bitmap); 5576b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim test_and_set_bit_le(1, &dentry_blk->dentry_bitmap); 5586b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim kunmap_atomic(kaddr); 5596b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 5606b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim set_page_dirty(dentry_page); 5616b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_put_page(dentry_page, 1); 5626b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return 0; 5636b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 5646b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 5656b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimbool f2fs_empty_dir(struct inode *dir) 5666b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 5676b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned long bidx; 5686b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct page *dentry_page; 5696b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned int bit_pos; 5706b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_dentry_block *dentry_blk; 5716b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned long nblock = dir_blocks(dir); 5726b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 5736b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim for (bidx = 0; bidx < nblock; bidx++) { 5746b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim void *kaddr; 5756b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dentry_page = get_lock_data_page(dir, bidx); 5766b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (IS_ERR(dentry_page)) { 5776b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (PTR_ERR(dentry_page) == -ENOENT) 5786b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim continue; 5796b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim else 5806b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return false; 5816b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 5826b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 5836b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim kaddr = kmap_atomic(dentry_page); 5846b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dentry_blk = (struct f2fs_dentry_block *)kaddr; 5856b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (bidx == 0) 5866b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_pos = 2; 5876b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim else 5886b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_pos = 0; 5896b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap, 5906b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim NR_DENTRY_IN_BLOCK, 5916b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_pos); 5926b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim kunmap_atomic(kaddr); 5936b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 5946b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_put_page(dentry_page, 1); 5956b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 5966b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (bit_pos < NR_DENTRY_IN_BLOCK) 5976b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return false; 5986b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 5996b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return true; 6006b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 6016b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 6026b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimstatic int f2fs_readdir(struct file *file, void *dirent, filldir_t filldir) 6036b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 6046b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned long pos = file->f_pos; 6056b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct inode *inode = file->f_dentry->d_inode; 6066b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned long npages = dir_blocks(inode); 6076b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned char *types = NULL; 6086b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned int bit_pos = 0, start_bit_pos = 0; 6096b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim int over = 0; 6106b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_dentry_block *dentry_blk = NULL; 6116b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_dir_entry *de = NULL; 6126b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct page *dentry_page = NULL; 6136b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned int n = 0; 6146b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned char d_type = DT_UNKNOWN; 6156b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim int slots; 6166b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 6176b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim types = f2fs_filetype_table; 6186b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_pos = (pos % NR_DENTRY_IN_BLOCK); 6196b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim n = (pos / NR_DENTRY_IN_BLOCK); 6206b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 6216b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim for ( ; n < npages; n++) { 6226b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dentry_page = get_lock_data_page(inode, n); 6236b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (IS_ERR(dentry_page)) 6246b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim continue; 6256b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 6266b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim start_bit_pos = bit_pos; 6276b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dentry_blk = kmap(dentry_page); 6286b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim while (bit_pos < NR_DENTRY_IN_BLOCK) { 6296b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim d_type = DT_UNKNOWN; 6306b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap, 6316b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim NR_DENTRY_IN_BLOCK, 6326b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_pos); 6336b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (bit_pos >= NR_DENTRY_IN_BLOCK) 6346b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim break; 6356b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 6366b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim de = &dentry_blk->dentry[bit_pos]; 6376b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (types && de->file_type < F2FS_FT_MAX) 6386b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim d_type = types[de->file_type]; 6396b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 6406b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim over = filldir(dirent, 6416b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dentry_blk->filename[bit_pos], 6426b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim le16_to_cpu(de->name_len), 6436b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim (n * NR_DENTRY_IN_BLOCK) + bit_pos, 6446b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim le32_to_cpu(de->ino), d_type); 6456b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (over) { 6466b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim file->f_pos += bit_pos - start_bit_pos; 6476b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim goto success; 6486b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 649457d08ee4fd91c8df17917ff2d32565e6adacbfcNamjae Jeon slots = GET_DENTRY_SLOTS(le16_to_cpu(de->name_len)); 6506b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_pos += slots; 6516b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 6526b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_pos = 0; 6536b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim file->f_pos = (n + 1) * NR_DENTRY_IN_BLOCK; 6546b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim kunmap(dentry_page); 6556b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_put_page(dentry_page, 1); 6566b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dentry_page = NULL; 6576b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 6586b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimsuccess: 6596b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (dentry_page && !IS_ERR(dentry_page)) { 6606b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim kunmap(dentry_page); 6616b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_put_page(dentry_page, 1); 6626b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 6636b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 6646b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return 0; 6656b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 6666b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 6676b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimconst struct file_operations f2fs_dir_operations = { 6686b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim .llseek = generic_file_llseek, 6696b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim .read = generic_read_dir, 6706b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim .readdir = f2fs_readdir, 6716b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim .fsync = f2fs_sync_file, 6726b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim .unlocked_ioctl = f2fs_ioctl, 6736b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim}; 674