dir.c revision 924a2ddbd0c2829ebca9ac899522cbb16a9b6d8c
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" 168ae8f1627f39bae505b90cade50cd8a911b8bda6Jaegeuk Kim#include "xattr.h" 176b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 186b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimstatic unsigned long dir_blocks(struct inode *inode) 196b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 206b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return ((unsigned long long) (i_size_read(inode) + PAGE_CACHE_SIZE - 1)) 216b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim >> PAGE_CACHE_SHIFT; 226b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 236b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 246b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimstatic unsigned int dir_buckets(unsigned int level) 256b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 266b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (level < MAX_DIR_HASH_DEPTH / 2) 276b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return 1 << level; 286b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim else 296b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return 1 << ((MAX_DIR_HASH_DEPTH / 2) - 1); 306b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 316b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 326b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimstatic unsigned int bucket_blocks(unsigned int level) 336b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 346b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (level < MAX_DIR_HASH_DEPTH / 2) 356b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return 2; 366b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim else 376b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return 4; 386b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 396b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 406b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimstatic unsigned char f2fs_filetype_table[F2FS_FT_MAX] = { 416b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim [F2FS_FT_UNKNOWN] = DT_UNKNOWN, 426b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim [F2FS_FT_REG_FILE] = DT_REG, 436b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim [F2FS_FT_DIR] = DT_DIR, 446b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim [F2FS_FT_CHRDEV] = DT_CHR, 456b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim [F2FS_FT_BLKDEV] = DT_BLK, 466b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim [F2FS_FT_FIFO] = DT_FIFO, 476b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim [F2FS_FT_SOCK] = DT_SOCK, 486b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim [F2FS_FT_SYMLINK] = DT_LNK, 496b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim}; 506b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 516b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim#define S_SHIFT 12 526b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimstatic unsigned char f2fs_type_by_mode[S_IFMT >> S_SHIFT] = { 536b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim [S_IFREG >> S_SHIFT] = F2FS_FT_REG_FILE, 546b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim [S_IFDIR >> S_SHIFT] = F2FS_FT_DIR, 556b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim [S_IFCHR >> S_SHIFT] = F2FS_FT_CHRDEV, 566b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim [S_IFBLK >> S_SHIFT] = F2FS_FT_BLKDEV, 576b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim [S_IFIFO >> S_SHIFT] = F2FS_FT_FIFO, 586b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim [S_IFSOCK >> S_SHIFT] = F2FS_FT_SOCK, 596b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim [S_IFLNK >> S_SHIFT] = F2FS_FT_SYMLINK, 606b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim}; 616b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 626b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimstatic void set_de_type(struct f2fs_dir_entry *de, struct inode *inode) 636b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 640ecc833bac594099505a090cbca6ccd5b83d5975Al Viro umode_t mode = inode->i_mode; 656b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim de->file_type = f2fs_type_by_mode[(mode & S_IFMT) >> S_SHIFT]; 666b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 676b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 686b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimstatic unsigned long dir_block_index(unsigned int level, unsigned int idx) 696b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 706b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned long i; 716b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned long bidx = 0; 726b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 736b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim for (i = 0; i < level; i++) 746b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bidx += dir_buckets(i) * bucket_blocks(i); 756b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bidx += idx * bucket_blocks(level); 766b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return bidx; 776b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 786b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 799836b8b9499cb25ea32cad9fff640eef874c5431Leon Romanovskystatic bool early_match_name(const char *name, size_t namelen, 806b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_hash_t namehash, struct f2fs_dir_entry *de) 816b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 826b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (le16_to_cpu(de->name_len) != namelen) 836b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return false; 846b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 8525ca923b2a766b9c93b63777ead351137533a623Jaegeuk Kim if (de->hash_code != namehash) 866b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return false; 876b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 886b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return true; 896b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 906b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 916b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimstatic struct f2fs_dir_entry *find_in_block(struct page *dentry_page, 929836b8b9499cb25ea32cad9fff640eef874c5431Leon Romanovsky const char *name, size_t namelen, int *max_slots, 936b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_hash_t namehash, struct page **res_page) 946b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 956b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_dir_entry *de; 966b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned long bit_pos, end_pos, next_pos; 976b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_dentry_block *dentry_blk = kmap(dentry_page); 986b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim int slots; 996b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 1006b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap, 1016b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim NR_DENTRY_IN_BLOCK, 0); 1026b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim while (bit_pos < NR_DENTRY_IN_BLOCK) { 1036b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim de = &dentry_blk->dentry[bit_pos]; 104457d08ee4fd91c8df17917ff2d32565e6adacbfcNamjae Jeon slots = GET_DENTRY_SLOTS(le16_to_cpu(de->name_len)); 1056b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 1066b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (early_match_name(name, namelen, namehash, de)) { 1076b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (!memcmp(dentry_blk->filename[bit_pos], 1086b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim name, namelen)) { 1096b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim *res_page = dentry_page; 1106b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim goto found; 1116b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 1126b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 1136b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim next_pos = bit_pos + slots; 1146b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap, 1156b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim NR_DENTRY_IN_BLOCK, next_pos); 1166b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (bit_pos >= NR_DENTRY_IN_BLOCK) 1176b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim end_pos = NR_DENTRY_IN_BLOCK; 1186b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim else 1196b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim end_pos = bit_pos; 1206b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (*max_slots < end_pos - next_pos) 1216b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim *max_slots = end_pos - next_pos; 1226b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 1236b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 1246b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim de = NULL; 1256b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim kunmap(dentry_page); 1266b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimfound: 1276b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return de; 1286b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 1296b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 1306b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimstatic struct f2fs_dir_entry *find_in_level(struct inode *dir, 1319836b8b9499cb25ea32cad9fff640eef874c5431Leon Romanovsky unsigned int level, const char *name, size_t namelen, 1326b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_hash_t namehash, struct page **res_page) 1336b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 134457d08ee4fd91c8df17917ff2d32565e6adacbfcNamjae Jeon int s = GET_DENTRY_SLOTS(namelen); 1356b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned int nbucket, nblock; 1366b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned int bidx, end_block; 1376b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct page *dentry_page; 1386b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_dir_entry *de = NULL; 1396b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bool room = false; 1406b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim int max_slots = 0; 1416b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 1425d56b6718a0f4e5c58cdd3cb6b7a472d7c5671b9Jaegeuk Kim f2fs_bug_on(level > MAX_DIR_HASH_DEPTH); 1436b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 1446b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim nbucket = dir_buckets(level); 1456b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim nblock = bucket_blocks(level); 1466b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 14725ca923b2a766b9c93b63777ead351137533a623Jaegeuk Kim bidx = dir_block_index(level, le32_to_cpu(namehash) % nbucket); 1486b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim end_block = bidx + nblock; 1496b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 1506b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim for (; bidx < end_block; bidx++) { 1516b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim /* no need to allocate new dentry pages to all the indices */ 152c718379b6b0954a04a153d7e5dc8b3136a301ee6Jaegeuk Kim dentry_page = find_data_page(dir, bidx, true); 1536b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (IS_ERR(dentry_page)) { 1546b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim room = true; 1556b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim continue; 1566b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 1576b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 1586b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim de = find_in_block(dentry_page, name, namelen, 1596b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim &max_slots, namehash, res_page); 1606b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (de) 1616b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim break; 1626b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 1636b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (max_slots >= s) 1646b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim room = true; 1656b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_put_page(dentry_page, 0); 1666b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 1676b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 1686b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (!de && room && F2FS_I(dir)->chash != namehash) { 1696b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim F2FS_I(dir)->chash = namehash; 1706b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim F2FS_I(dir)->clevel = level; 1716b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 1726b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 1736b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return de; 1746b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 1756b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 1766b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim/* 1776b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim * Find an entry in the specified directory with the wanted name. 1786b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim * It returns the page where the entry was found (as a parameter - res_page), 1796b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim * and the entry itself. Page is returned mapped and unlocked. 1806b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim * Entry is guaranteed to be valid. 1816b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim */ 1826b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimstruct f2fs_dir_entry *f2fs_find_entry(struct inode *dir, 1836b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct qstr *child, struct page **res_page) 1846b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 1856b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim const char *name = child->name; 1869836b8b9499cb25ea32cad9fff640eef874c5431Leon Romanovsky size_t namelen = child->len; 1876b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned long npages = dir_blocks(dir); 1886b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_dir_entry *de = NULL; 1896b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_hash_t name_hash; 1906b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned int max_depth; 1916b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned int level; 1926b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 1936b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (npages == 0) 1946b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return NULL; 1956b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 1966b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim *res_page = NULL; 1976b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 1986b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim name_hash = f2fs_dentry_hash(name, namelen); 1996b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim max_depth = F2FS_I(dir)->i_current_depth; 2006b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 2016b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim for (level = 0; level < max_depth; level++) { 2026b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim de = find_in_level(dir, level, name, 2036b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim namelen, name_hash, res_page); 2046b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (de) 2056b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim break; 2066b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 2076b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (!de && F2FS_I(dir)->chash != name_hash) { 2086b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim F2FS_I(dir)->chash = name_hash; 2096b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim F2FS_I(dir)->clevel = level - 1; 2106b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 2116b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return de; 2126b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 2136b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 2146b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimstruct f2fs_dir_entry *f2fs_parent_dir(struct inode *dir, struct page **p) 2156b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 2164777f86b7c0a587dde275a5c1ff3022b2e601313Namjae Jeon struct page *page; 2174777f86b7c0a587dde275a5c1ff3022b2e601313Namjae Jeon struct f2fs_dir_entry *de; 2184777f86b7c0a587dde275a5c1ff3022b2e601313Namjae Jeon struct f2fs_dentry_block *dentry_blk; 2196b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 2206b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim page = get_lock_data_page(dir, 0); 2216b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (IS_ERR(page)) 2226b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return NULL; 2236b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 2246b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dentry_blk = kmap(page); 2256b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim de = &dentry_blk->dentry[1]; 2266b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim *p = page; 2276b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unlock_page(page); 2286b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return de; 2296b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 2306b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 2316b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimino_t f2fs_inode_by_name(struct inode *dir, struct qstr *qstr) 2326b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 2336b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim ino_t res = 0; 2346b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_dir_entry *de; 2356b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct page *page; 2366b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 2376b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim de = f2fs_find_entry(dir, qstr, &page); 2386b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (de) { 2396b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim res = le32_to_cpu(de->ino); 2406b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim kunmap(page); 2416b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_put_page(page, 0); 2426b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 2436b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 2446b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return res; 2456b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 2466b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 2476b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimvoid f2fs_set_link(struct inode *dir, struct f2fs_dir_entry *de, 2486b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct page *page, struct inode *inode) 2496b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 2506b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim lock_page(page); 2516b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim wait_on_page_writeback(page); 2526b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim de->ino = cpu_to_le32(inode->i_ino); 2536b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim set_de_type(de, inode); 2546b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim kunmap(page); 2556b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim set_page_dirty(page); 2566b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dir->i_mtime = dir->i_ctime = CURRENT_TIME; 2576b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim mark_inode_dirty(dir); 2586666e6aa9f36b2bfd6b30072c07b34f2a24becf1Jaegeuk Kim 2596b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_put_page(page, 1); 2606b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 2616b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 26244a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kimstatic void init_dent_inode(const struct qstr *name, struct page *ipage) 2636b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 26458bfaf44df58082c72882b235cae611c975537d4Jaegeuk Kim struct f2fs_inode *ri; 2656b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 26653dc9a67769d0a9733adb5156adfc07edcbc1ea3Al Viro /* copy name info. to this inode page */ 26758bfaf44df58082c72882b235cae611c975537d4Jaegeuk Kim ri = F2FS_INODE(ipage); 26858bfaf44df58082c72882b235cae611c975537d4Jaegeuk Kim ri->i_namelen = cpu_to_le32(name->len); 26958bfaf44df58082c72882b235cae611c975537d4Jaegeuk Kim memcpy(ri->i_name, name->name, name->len); 2706b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim set_page_dirty(ipage); 2716b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 2726b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 2731cd14cafc694bcedc5017a4f0dcb3c3faddec622Jaegeuk Kimint update_dent_inode(struct inode *inode, const struct qstr *name) 2741cd14cafc694bcedc5017a4f0dcb3c3faddec622Jaegeuk Kim{ 2751cd14cafc694bcedc5017a4f0dcb3c3faddec622Jaegeuk Kim struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); 2761cd14cafc694bcedc5017a4f0dcb3c3faddec622Jaegeuk Kim struct page *page; 2771cd14cafc694bcedc5017a4f0dcb3c3faddec622Jaegeuk Kim 2781cd14cafc694bcedc5017a4f0dcb3c3faddec622Jaegeuk Kim page = get_node_page(sbi, inode->i_ino); 2791cd14cafc694bcedc5017a4f0dcb3c3faddec622Jaegeuk Kim if (IS_ERR(page)) 2801cd14cafc694bcedc5017a4f0dcb3c3faddec622Jaegeuk Kim return PTR_ERR(page); 2811cd14cafc694bcedc5017a4f0dcb3c3faddec622Jaegeuk Kim 2821cd14cafc694bcedc5017a4f0dcb3c3faddec622Jaegeuk Kim init_dent_inode(name, page); 2831cd14cafc694bcedc5017a4f0dcb3c3faddec622Jaegeuk Kim f2fs_put_page(page, 1); 2841cd14cafc694bcedc5017a4f0dcb3c3faddec622Jaegeuk Kim 2851cd14cafc694bcedc5017a4f0dcb3c3faddec622Jaegeuk Kim return 0; 2861cd14cafc694bcedc5017a4f0dcb3c3faddec622Jaegeuk Kim} 2871cd14cafc694bcedc5017a4f0dcb3c3faddec622Jaegeuk Kim 28844a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kimstatic int make_empty_dir(struct inode *inode, 28944a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kim struct inode *parent, struct page *page) 290399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim{ 291399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim struct page *dentry_page; 292399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim struct f2fs_dentry_block *dentry_blk; 293399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim struct f2fs_dir_entry *de; 294399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim void *kaddr; 295399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim 29644a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kim dentry_page = get_new_data_page(inode, page, 0, true); 297399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim if (IS_ERR(dentry_page)) 298399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim return PTR_ERR(dentry_page); 299399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim 300399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim kaddr = kmap_atomic(dentry_page); 301399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim dentry_blk = (struct f2fs_dentry_block *)kaddr; 302399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim 303399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim de = &dentry_blk->dentry[0]; 304399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim de->name_len = cpu_to_le16(1); 305399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim de->hash_code = 0; 306399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim de->ino = cpu_to_le32(inode->i_ino); 307399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim memcpy(dentry_blk->filename[0], ".", 1); 308399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim set_de_type(de, inode); 309399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim 310399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim de = &dentry_blk->dentry[1]; 311399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim de->hash_code = 0; 312399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim de->name_len = cpu_to_le16(2); 313399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim de->ino = cpu_to_le32(parent->i_ino); 314399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim memcpy(dentry_blk->filename[1], "..", 2); 315399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim set_de_type(de, inode); 316399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim 317399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim test_and_set_bit_le(0, &dentry_blk->dentry_bitmap); 318399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim test_and_set_bit_le(1, &dentry_blk->dentry_bitmap); 319399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim kunmap_atomic(kaddr); 320399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim 321399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim set_page_dirty(dentry_page); 322399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim f2fs_put_page(dentry_page, 1); 323399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim return 0; 324399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim} 325399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim 32644a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kimstatic struct page *init_inode_metadata(struct inode *inode, 32769f24eac55725859a89c440ee2d19f36fa09e8fcAl Viro struct inode *dir, const struct qstr *name) 3286b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 32944a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kim struct page *page; 33044a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kim int err; 33144a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kim 3326b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (is_inode_flag_set(F2FS_I(inode), FI_NEW_INODE)) { 33344a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kim page = new_inode_page(inode, name); 33444a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kim if (IS_ERR(page)) 33544a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kim return page; 3366b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 3376b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (S_ISDIR(inode->i_mode)) { 33844a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kim err = make_empty_dir(inode, dir, page); 33944a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kim if (err) 34044a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kim goto error; 3416b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 3426b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 3432ed2d5b33cb564025b1eb90650d70a0a3592c0e3Jaegeuk Kim err = f2fs_init_acl(inode, dir, page); 34444a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kim if (err) 345a8865372a8414298982e07f4ac8d6dc0ab1e0a3dJaegeuk Kim goto put_error; 34644a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kim 3478ae8f1627f39bae505b90cade50cd8a911b8bda6Jaegeuk Kim err = f2fs_init_security(inode, dir, name, page); 3488ae8f1627f39bae505b90cade50cd8a911b8bda6Jaegeuk Kim if (err) 349a8865372a8414298982e07f4ac8d6dc0ab1e0a3dJaegeuk Kim goto put_error; 3508ae8f1627f39bae505b90cade50cd8a911b8bda6Jaegeuk Kim 35144a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kim wait_on_page_writeback(page); 3526b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } else { 35344a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kim page = get_node_page(F2FS_SB(dir->i_sb), inode->i_ino); 35444a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kim if (IS_ERR(page)) 35544a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kim return page; 35644a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kim 35744a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kim wait_on_page_writeback(page); 35844a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kim set_cold_node(inode, page); 3596b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 36044a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kim 36144a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kim init_dent_inode(name, page); 36244a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kim 36383d5d6f66b375f21bee4c2e17178f7c073a66301Jaegeuk Kim /* 36483d5d6f66b375f21bee4c2e17178f7c073a66301Jaegeuk Kim * This file should be checkpointed during fsync. 36583d5d6f66b375f21bee4c2e17178f7c073a66301Jaegeuk Kim * We lost i_pino from now on. 36683d5d6f66b375f21bee4c2e17178f7c073a66301Jaegeuk Kim */ 3676b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (is_inode_flag_set(F2FS_I(inode), FI_INC_LINK)) { 368354a3399dc6f7e556d04e1c731cd50e08eeb44bdJaegeuk Kim file_lost_pino(inode); 3696b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim inc_nlink(inode); 3706b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 37144a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kim return page; 37244a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kim 373a8865372a8414298982e07f4ac8d6dc0ab1e0a3dJaegeuk Kimput_error: 37444a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kim f2fs_put_page(page, 1); 375a8865372a8414298982e07f4ac8d6dc0ab1e0a3dJaegeuk Kimerror: 37644a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kim remove_inode_page(inode); 37744a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kim return ERR_PTR(err); 3786b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 3796b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 3806b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimstatic void update_parent_metadata(struct inode *dir, struct inode *inode, 3816b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned int current_depth) 3826b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 3836b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (is_inode_flag_set(F2FS_I(inode), FI_NEW_INODE)) { 3846b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (S_ISDIR(inode->i_mode)) { 3856b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim inc_nlink(dir); 386699489bbbea4fc3b9b735d69941cf4fca91ce1d5Jaegeuk Kim set_inode_flag(F2FS_I(dir), FI_UPDATE_DIR); 3876b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 3886b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim clear_inode_flag(F2FS_I(inode), FI_NEW_INODE); 3896b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 3906b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dir->i_mtime = dir->i_ctime = CURRENT_TIME; 391a18ff063406dd6aec41fda598eabe2691007a30dJaegeuk Kim mark_inode_dirty(dir); 392a18ff063406dd6aec41fda598eabe2691007a30dJaegeuk Kim 3936b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (F2FS_I(dir)->i_current_depth != current_depth) { 3946b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim F2FS_I(dir)->i_current_depth = current_depth; 395699489bbbea4fc3b9b735d69941cf4fca91ce1d5Jaegeuk Kim set_inode_flag(F2FS_I(dir), FI_UPDATE_DIR); 3966b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 3976b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 3986b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (is_inode_flag_set(F2FS_I(inode), FI_INC_LINK)) 3996b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim clear_inode_flag(F2FS_I(inode), FI_INC_LINK); 4006b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 4016b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 4026b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimstatic int room_for_filename(struct f2fs_dentry_block *dentry_blk, int slots) 4036b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 4046b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim int bit_start = 0; 4056b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim int zero_start, zero_end; 4066b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimnext: 4076b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim zero_start = find_next_zero_bit_le(&dentry_blk->dentry_bitmap, 4086b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim NR_DENTRY_IN_BLOCK, 4096b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_start); 4106b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (zero_start >= NR_DENTRY_IN_BLOCK) 4116b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return NR_DENTRY_IN_BLOCK; 4126b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 4136b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim zero_end = find_next_bit_le(&dentry_blk->dentry_bitmap, 4146b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim NR_DENTRY_IN_BLOCK, 4156b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim zero_start); 4166b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (zero_end - zero_start >= slots) 4176b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return zero_start; 4186b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 4196b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_start = zero_end + 1; 4206b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 4216b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (zero_end + 1 >= NR_DENTRY_IN_BLOCK) 4226b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return NR_DENTRY_IN_BLOCK; 4236b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim goto next; 4246b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 4256b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 426399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim/* 4274f4124d0b99682efa7307191a28ec050872d2079Chao Yu * Caller should grab and release a rwsem by calling f2fs_lock_op() and 4284f4124d0b99682efa7307191a28ec050872d2079Chao Yu * f2fs_unlock_op(). 429399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim */ 4306c311ec6c2d9e015d454b4e3fda8008b5bebf316Chris Friesint __f2fs_add_link(struct inode *dir, const struct qstr *name, 4316c311ec6c2d9e015d454b4e3fda8008b5bebf316Chris Fries struct inode *inode) 4326b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 4336b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned int bit_pos; 4346b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned int level; 4356b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned int current_depth; 4366b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned long bidx, block; 4376b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_hash_t dentry_hash; 4386b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_dir_entry *de; 4396b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned int nbucket, nblock; 440b7f7a5e0be94d13875a1c6c9aa65eeb11a46fc1bAl Viro size_t namelen = name->len; 4416b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct page *dentry_page = NULL; 4426b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_dentry_block *dentry_blk = NULL; 443457d08ee4fd91c8df17917ff2d32565e6adacbfcNamjae Jeon int slots = GET_DENTRY_SLOTS(namelen); 44444a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kim struct page *page; 4456b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim int err = 0; 4466b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim int i; 4476b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 448b7f7a5e0be94d13875a1c6c9aa65eeb11a46fc1bAl Viro dentry_hash = f2fs_dentry_hash(name->name, name->len); 4496b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim level = 0; 4506b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim current_depth = F2FS_I(dir)->i_current_depth; 4516b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (F2FS_I(dir)->chash == dentry_hash) { 4526b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim level = F2FS_I(dir)->clevel; 4536b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim F2FS_I(dir)->chash = 0; 4546b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 4556b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 4566b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimstart: 457cfb271d485d0ec31eb92b51f4fbe54bf6542e8e6Chao Yu if (unlikely(current_depth == MAX_DIR_HASH_DEPTH)) 4586b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return -ENOSPC; 4596b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 4606b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim /* Increase the depth, if required */ 4616b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (level == current_depth) 4626b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim ++current_depth; 4636b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 4646b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim nbucket = dir_buckets(level); 4656b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim nblock = bucket_blocks(level); 4666b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 46725ca923b2a766b9c93b63777ead351137533a623Jaegeuk Kim bidx = dir_block_index(level, (le32_to_cpu(dentry_hash) % nbucket)); 4686b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 4696b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim for (block = bidx; block <= (bidx + nblock - 1); block++) { 47064aa7ed98db489d1c41ef140876ada38498678abJaegeuk Kim dentry_page = get_new_data_page(dir, NULL, block, true); 471399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim if (IS_ERR(dentry_page)) 4726b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return PTR_ERR(dentry_page); 4736b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 4746b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dentry_blk = kmap(dentry_page); 4756b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_pos = room_for_filename(dentry_blk, slots); 4766b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (bit_pos < NR_DENTRY_IN_BLOCK) 4776b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim goto add_dentry; 4786b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 4796b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim kunmap(dentry_page); 4806b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_put_page(dentry_page, 1); 4816b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 4826b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 4836b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim /* Move to next level to find the empty slot for new dentry */ 4846b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim ++level; 4856b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim goto start; 4866b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimadd_dentry: 4876b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim wait_on_page_writeback(dentry_page); 4886b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 48944a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kim page = init_inode_metadata(inode, dir, name); 49044a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kim if (IS_ERR(page)) { 49144a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kim err = PTR_ERR(page); 49244a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kim goto fail; 49344a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kim } 4946b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim de = &dentry_blk->dentry[bit_pos]; 49525ca923b2a766b9c93b63777ead351137533a623Jaegeuk Kim de->hash_code = dentry_hash; 4966b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim de->name_len = cpu_to_le16(namelen); 497b7f7a5e0be94d13875a1c6c9aa65eeb11a46fc1bAl Viro memcpy(dentry_blk->filename[bit_pos], name->name, name->len); 4986b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim de->ino = cpu_to_le32(inode->i_ino); 4996b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim set_de_type(de, inode); 5006b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim for (i = 0; i < slots; i++) 5016b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim test_and_set_bit_le(bit_pos + i, &dentry_blk->dentry_bitmap); 5026b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim set_page_dirty(dentry_page); 5036666e6aa9f36b2bfd6b30072c07b34f2a24becf1Jaegeuk Kim 50444a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kim /* we don't need to mark_inode_dirty now */ 5056666e6aa9f36b2bfd6b30072c07b34f2a24becf1Jaegeuk Kim F2FS_I(inode)->i_pino = dir->i_ino; 50644a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kim update_inode(inode, page); 50744a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kim f2fs_put_page(page, 1); 50844a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kim 50944a83ff6a81d84ab83bcb43a49ff1ba6c7e17cd1Jaegeuk Kim update_parent_metadata(dir, inode, current_depth); 5106b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimfail: 511924a2ddbd0c2829ebca9ac899522cbb16a9b6d8cJaegeuk Kim if (is_inode_flag_set(F2FS_I(dir), FI_UPDATE_DIR)) { 512924a2ddbd0c2829ebca9ac899522cbb16a9b6d8cJaegeuk Kim update_inode_page(dir); 513924a2ddbd0c2829ebca9ac899522cbb16a9b6d8cJaegeuk Kim clear_inode_flag(F2FS_I(dir), FI_UPDATE_DIR); 514924a2ddbd0c2829ebca9ac899522cbb16a9b6d8cJaegeuk Kim } 5156b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim kunmap(dentry_page); 5166b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_put_page(dentry_page, 1); 5176b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return err; 5186b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 5196b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 5200a8165d7c2cf1395059db20ab07665baf3758fcdJaegeuk Kim/* 5216b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim * It only removes the dentry from the dentry page,corresponding name 5226b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim * entry in name page does not need to be touched during deletion. 5236b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim */ 5246b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimvoid f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page, 5256b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct inode *inode) 5266b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 5276b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_dentry_block *dentry_blk; 5286b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned int bit_pos; 5296b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct address_space *mapping = page->mapping; 5306b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct inode *dir = mapping->host; 5316b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb); 532457d08ee4fd91c8df17917ff2d32565e6adacbfcNamjae Jeon int slots = GET_DENTRY_SLOTS(le16_to_cpu(dentry->name_len)); 5336b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim void *kaddr = page_address(page); 5346b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim int i; 5356b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 5366b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim lock_page(page); 5376b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim wait_on_page_writeback(page); 5386b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 5396b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dentry_blk = (struct f2fs_dentry_block *)kaddr; 5406b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_pos = dentry - (struct f2fs_dir_entry *)dentry_blk->dentry; 5416b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim for (i = 0; i < slots; i++) 5426b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim test_and_clear_bit_le(bit_pos + i, &dentry_blk->dentry_bitmap); 5436b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 5446b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim /* Let's check and deallocate this dentry page */ 5456b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap, 5466b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim NR_DENTRY_IN_BLOCK, 5476b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 0); 5486b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim kunmap(page); /* kunmap - pair of f2fs_find_entry */ 5496b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim set_page_dirty(page); 5506b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 5516b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dir->i_ctime = dir->i_mtime = CURRENT_TIME; 5526b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 5536b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (inode) { 554e8dae6045882e32a067326f47b7ccd3aaf8814e2Jaegeuk Kim if (S_ISDIR(inode->i_mode)) { 555e8dae6045882e32a067326f47b7ccd3aaf8814e2Jaegeuk Kim drop_nlink(dir); 556e8dae6045882e32a067326f47b7ccd3aaf8814e2Jaegeuk Kim update_inode_page(dir); 557e8dae6045882e32a067326f47b7ccd3aaf8814e2Jaegeuk Kim } 558163799872b65b0cbf0091d82971233cc3d2425d3Namjae Jeon inode->i_ctime = CURRENT_TIME; 5596b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim drop_nlink(inode); 5606b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (S_ISDIR(inode->i_mode)) { 5616b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim drop_nlink(inode); 5626b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim i_size_write(inode, 0); 5636b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 564399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim update_inode_page(inode); 565399368372ed9f3c396eadb5c2bbc98be8c774a39Jaegeuk Kim 5666b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (inode->i_nlink == 0) 5676b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim add_orphan_inode(sbi, inode->i_ino); 568cbd56e7d20d7188d62a85aa6986a7b2c8e755ab5Jaegeuk Kim else 569cbd56e7d20d7188d62a85aa6986a7b2c8e755ab5Jaegeuk Kim release_orphan_inode(sbi); 5706b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 5716b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 5726b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (bit_pos == NR_DENTRY_IN_BLOCK) { 5736b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim truncate_hole(dir, page->index, page->index + 1); 5746b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim clear_page_dirty_for_io(page); 5756b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim ClearPageUptodate(page); 5766b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dec_page_count(sbi, F2FS_DIRTY_DENTS); 5776b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim inode_dec_dirty_dents(dir); 5786b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 579508198be3c2f7f8929101bb0daeb8f0039c1dc7fNamjae Jeon f2fs_put_page(page, 1); 5806b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 5816b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 5826b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimbool f2fs_empty_dir(struct inode *dir) 5836b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 5846b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned long bidx; 5856b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct page *dentry_page; 5866b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned int bit_pos; 5876b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_dentry_block *dentry_blk; 5886b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned long nblock = dir_blocks(dir); 5896b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 5906b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim for (bidx = 0; bidx < nblock; bidx++) { 5916b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim void *kaddr; 5926b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dentry_page = get_lock_data_page(dir, bidx); 5936b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (IS_ERR(dentry_page)) { 5946b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (PTR_ERR(dentry_page) == -ENOENT) 5956b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim continue; 5966b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim else 5976b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return false; 5986b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 5996b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 6006b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim kaddr = kmap_atomic(dentry_page); 6016b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dentry_blk = (struct f2fs_dentry_block *)kaddr; 6026b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (bidx == 0) 6036b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_pos = 2; 6046b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim else 6056b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_pos = 0; 6066b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap, 6076b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim NR_DENTRY_IN_BLOCK, 6086b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_pos); 6096b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim kunmap_atomic(kaddr); 6106b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 6116b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_put_page(dentry_page, 1); 6126b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 6136b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (bit_pos < NR_DENTRY_IN_BLOCK) 6146b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return false; 6156b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 6166b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return true; 6176b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 6186b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 6196f7f231e7b4f819b912f848a33d946b54261483dAl Virostatic int f2fs_readdir(struct file *file, struct dir_context *ctx) 6206b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim{ 621496ad9aa8ef448058e36ca7a787c61f2e63f0f54Al Viro struct inode *inode = file_inode(file); 6226b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned long npages = dir_blocks(inode); 62399b072bb38c9b398bc7c3fc8a0f30d0801f78750Jaegeuk Kim unsigned int bit_pos = 0; 6246b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_dentry_block *dentry_blk = NULL; 6256b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct f2fs_dir_entry *de = NULL; 6266b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim struct page *dentry_page = NULL; 6276f7f231e7b4f819b912f848a33d946b54261483dAl Viro unsigned int n = ((unsigned long)ctx->pos / NR_DENTRY_IN_BLOCK); 6286b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim unsigned char d_type = DT_UNKNOWN; 6296b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 6306f7f231e7b4f819b912f848a33d946b54261483dAl Viro bit_pos = ((unsigned long)ctx->pos % NR_DENTRY_IN_BLOCK); 6316b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 6326c311ec6c2d9e015d454b4e3fda8008b5bebf316Chris Fries for (; n < npages; n++) { 6336b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dentry_page = get_lock_data_page(inode, n); 6346b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (IS_ERR(dentry_page)) 6356b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim continue; 6366b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 6376b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dentry_blk = kmap(dentry_page); 6386b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim while (bit_pos < NR_DENTRY_IN_BLOCK) { 6396b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap, 6406b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim NR_DENTRY_IN_BLOCK, 6416b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_pos); 6426b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (bit_pos >= NR_DENTRY_IN_BLOCK) 6436b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim break; 6446b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 6456b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim de = &dentry_blk->dentry[bit_pos]; 6466f7f231e7b4f819b912f848a33d946b54261483dAl Viro if (de->file_type < F2FS_FT_MAX) 6476f7f231e7b4f819b912f848a33d946b54261483dAl Viro d_type = f2fs_filetype_table[de->file_type]; 6486f7f231e7b4f819b912f848a33d946b54261483dAl Viro else 6496f7f231e7b4f819b912f848a33d946b54261483dAl Viro d_type = DT_UNKNOWN; 6506f7f231e7b4f819b912f848a33d946b54261483dAl Viro if (!dir_emit(ctx, 65199b072bb38c9b398bc7c3fc8a0f30d0801f78750Jaegeuk Kim dentry_blk->filename[bit_pos], 65299b072bb38c9b398bc7c3fc8a0f30d0801f78750Jaegeuk Kim le16_to_cpu(de->name_len), 65399b072bb38c9b398bc7c3fc8a0f30d0801f78750Jaegeuk Kim le32_to_cpu(de->ino), d_type)) 65499b072bb38c9b398bc7c3fc8a0f30d0801f78750Jaegeuk Kim goto stop; 65599b072bb38c9b398bc7c3fc8a0f30d0801f78750Jaegeuk Kim 65699b072bb38c9b398bc7c3fc8a0f30d0801f78750Jaegeuk Kim bit_pos += GET_DENTRY_SLOTS(le16_to_cpu(de->name_len)); 65799b072bb38c9b398bc7c3fc8a0f30d0801f78750Jaegeuk Kim ctx->pos = n * NR_DENTRY_IN_BLOCK + bit_pos; 6586b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 6596b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim bit_pos = 0; 6606f7f231e7b4f819b912f848a33d946b54261483dAl Viro ctx->pos = (n + 1) * NR_DENTRY_IN_BLOCK; 6616b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim kunmap(dentry_page); 6626b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_put_page(dentry_page, 1); 6636b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim dentry_page = NULL; 6646b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 66599b072bb38c9b398bc7c3fc8a0f30d0801f78750Jaegeuk Kimstop: 6666b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim if (dentry_page && !IS_ERR(dentry_page)) { 6676b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim kunmap(dentry_page); 6686b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim f2fs_put_page(dentry_page, 1); 6696b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim } 6706b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 6716b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim return 0; 6726b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim} 6736b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim 6746b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kimconst struct file_operations f2fs_dir_operations = { 6756b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim .llseek = generic_file_llseek, 6766b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim .read = generic_read_dir, 6776f7f231e7b4f819b912f848a33d946b54261483dAl Viro .iterate = f2fs_readdir, 6786b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim .fsync = f2fs_sync_file, 6796b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim .unlocked_ioctl = f2fs_ioctl, 6806b4ea0160ae236a6561defa28e19f973aedda9ffJaegeuk Kim}; 681