15eb563f5SRyusuke Konishi /* 25eb563f5SRyusuke Konishi * mdt.c - meta data file for NILFS 35eb563f5SRyusuke Konishi * 45eb563f5SRyusuke Konishi * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation. 55eb563f5SRyusuke Konishi * 65eb563f5SRyusuke Konishi * This program is free software; you can redistribute it and/or modify 75eb563f5SRyusuke Konishi * it under the terms of the GNU General Public License as published by 85eb563f5SRyusuke Konishi * the Free Software Foundation; either version 2 of the License, or 95eb563f5SRyusuke Konishi * (at your option) any later version. 105eb563f5SRyusuke Konishi * 115eb563f5SRyusuke Konishi * This program is distributed in the hope that it will be useful, 125eb563f5SRyusuke Konishi * but WITHOUT ANY WARRANTY; without even the implied warranty of 135eb563f5SRyusuke Konishi * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 145eb563f5SRyusuke Konishi * GNU General Public License for more details. 155eb563f5SRyusuke Konishi * 165eb563f5SRyusuke Konishi * You should have received a copy of the GNU General Public License 175eb563f5SRyusuke Konishi * along with this program; if not, write to the Free Software 185eb563f5SRyusuke Konishi * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 195eb563f5SRyusuke Konishi * 205eb563f5SRyusuke Konishi * Written by Ryusuke Konishi <ryusuke@osrg.net> 215eb563f5SRyusuke Konishi */ 225eb563f5SRyusuke Konishi 235eb563f5SRyusuke Konishi #include <linux/buffer_head.h> 245eb563f5SRyusuke Konishi #include <linux/mpage.h> 255eb563f5SRyusuke Konishi #include <linux/mm.h> 265eb563f5SRyusuke Konishi #include <linux/writeback.h> 275eb563f5SRyusuke Konishi #include <linux/backing-dev.h> 285eb563f5SRyusuke Konishi #include <linux/swap.h> 295eb563f5SRyusuke Konishi #include "nilfs.h" 305eb563f5SRyusuke Konishi #include "segment.h" 315eb563f5SRyusuke Konishi #include "page.h" 325eb563f5SRyusuke Konishi #include "mdt.h" 335eb563f5SRyusuke Konishi 345eb563f5SRyusuke Konishi 355eb563f5SRyusuke Konishi #define NILFS_MDT_MAX_RA_BLOCKS (16 - 1) 365eb563f5SRyusuke Konishi 375eb563f5SRyusuke Konishi #define INIT_UNUSED_INODE_FIELDS 385eb563f5SRyusuke Konishi 395eb563f5SRyusuke Konishi static int 405eb563f5SRyusuke Konishi nilfs_mdt_insert_new_block(struct inode *inode, unsigned long block, 415eb563f5SRyusuke Konishi struct buffer_head *bh, 425eb563f5SRyusuke Konishi void (*init_block)(struct inode *, 435eb563f5SRyusuke Konishi struct buffer_head *, void *)) 445eb563f5SRyusuke Konishi { 455eb563f5SRyusuke Konishi struct nilfs_inode_info *ii = NILFS_I(inode); 465eb563f5SRyusuke Konishi void *kaddr; 475eb563f5SRyusuke Konishi int ret; 485eb563f5SRyusuke Konishi 495eb563f5SRyusuke Konishi /* Caller exclude read accesses using page lock */ 505eb563f5SRyusuke Konishi 515eb563f5SRyusuke Konishi /* set_buffer_new(bh); */ 525eb563f5SRyusuke Konishi bh->b_blocknr = 0; 535eb563f5SRyusuke Konishi 545eb563f5SRyusuke Konishi ret = nilfs_bmap_insert(ii->i_bmap, block, (unsigned long)bh); 555eb563f5SRyusuke Konishi if (unlikely(ret)) 565eb563f5SRyusuke Konishi return ret; 575eb563f5SRyusuke Konishi 585eb563f5SRyusuke Konishi set_buffer_mapped(bh); 595eb563f5SRyusuke Konishi 605eb563f5SRyusuke Konishi kaddr = kmap_atomic(bh->b_page, KM_USER0); 615eb563f5SRyusuke Konishi memset(kaddr + bh_offset(bh), 0, 1 << inode->i_blkbits); 625eb563f5SRyusuke Konishi if (init_block) 635eb563f5SRyusuke Konishi init_block(inode, bh, kaddr); 645eb563f5SRyusuke Konishi flush_dcache_page(bh->b_page); 655eb563f5SRyusuke Konishi kunmap_atomic(kaddr, KM_USER0); 665eb563f5SRyusuke Konishi 675eb563f5SRyusuke Konishi set_buffer_uptodate(bh); 685eb563f5SRyusuke Konishi nilfs_mark_buffer_dirty(bh); 695eb563f5SRyusuke Konishi nilfs_mdt_mark_dirty(inode); 705eb563f5SRyusuke Konishi return 0; 715eb563f5SRyusuke Konishi } 725eb563f5SRyusuke Konishi 735eb563f5SRyusuke Konishi static int nilfs_mdt_create_block(struct inode *inode, unsigned long block, 745eb563f5SRyusuke Konishi struct buffer_head **out_bh, 755eb563f5SRyusuke Konishi void (*init_block)(struct inode *, 765eb563f5SRyusuke Konishi struct buffer_head *, 775eb563f5SRyusuke Konishi void *)) 785eb563f5SRyusuke Konishi { 795eb563f5SRyusuke Konishi struct the_nilfs *nilfs = NILFS_MDT(inode)->mi_nilfs; 805eb563f5SRyusuke Konishi struct nilfs_sb_info *writer = NULL; 815eb563f5SRyusuke Konishi struct super_block *sb = inode->i_sb; 825eb563f5SRyusuke Konishi struct nilfs_transaction_info ti; 835eb563f5SRyusuke Konishi struct buffer_head *bh; 845eb563f5SRyusuke Konishi int err; 855eb563f5SRyusuke Konishi 865eb563f5SRyusuke Konishi if (!sb) { 875eb563f5SRyusuke Konishi writer = nilfs_get_writer(nilfs); 885eb563f5SRyusuke Konishi if (!writer) { 895eb563f5SRyusuke Konishi err = -EROFS; 905eb563f5SRyusuke Konishi goto out; 915eb563f5SRyusuke Konishi } 925eb563f5SRyusuke Konishi sb = writer->s_super; 935eb563f5SRyusuke Konishi } 945eb563f5SRyusuke Konishi 955eb563f5SRyusuke Konishi nilfs_transaction_begin(sb, &ti, 0); 965eb563f5SRyusuke Konishi 975eb563f5SRyusuke Konishi err = -ENOMEM; 985eb563f5SRyusuke Konishi bh = nilfs_grab_buffer(inode, inode->i_mapping, block, 0); 995eb563f5SRyusuke Konishi if (unlikely(!bh)) 1005eb563f5SRyusuke Konishi goto failed_unlock; 1015eb563f5SRyusuke Konishi 1025eb563f5SRyusuke Konishi err = -EEXIST; 1035eb563f5SRyusuke Konishi if (buffer_uptodate(bh) || buffer_mapped(bh)) 1045eb563f5SRyusuke Konishi goto failed_bh; 1055eb563f5SRyusuke Konishi #if 0 1065eb563f5SRyusuke Konishi /* The uptodate flag is not protected by the page lock, but 1075eb563f5SRyusuke Konishi the mapped flag is. Thus, we don't have to wait the buffer. */ 1085eb563f5SRyusuke Konishi wait_on_buffer(bh); 1095eb563f5SRyusuke Konishi if (buffer_uptodate(bh)) 1105eb563f5SRyusuke Konishi goto failed_bh; 1115eb563f5SRyusuke Konishi #endif 1125eb563f5SRyusuke Konishi 1135eb563f5SRyusuke Konishi bh->b_bdev = nilfs->ns_bdev; 1145eb563f5SRyusuke Konishi err = nilfs_mdt_insert_new_block(inode, block, bh, init_block); 1155eb563f5SRyusuke Konishi if (likely(!err)) { 1165eb563f5SRyusuke Konishi get_bh(bh); 1175eb563f5SRyusuke Konishi *out_bh = bh; 1185eb563f5SRyusuke Konishi } 1195eb563f5SRyusuke Konishi 1205eb563f5SRyusuke Konishi failed_bh: 1215eb563f5SRyusuke Konishi unlock_page(bh->b_page); 1225eb563f5SRyusuke Konishi page_cache_release(bh->b_page); 1235eb563f5SRyusuke Konishi brelse(bh); 1245eb563f5SRyusuke Konishi 1255eb563f5SRyusuke Konishi failed_unlock: 12647420c79SRyusuke Konishi if (likely(!err)) 12747420c79SRyusuke Konishi err = nilfs_transaction_commit(sb); 12847420c79SRyusuke Konishi else 12947420c79SRyusuke Konishi nilfs_transaction_abort(sb); 1305eb563f5SRyusuke Konishi if (writer) 1315eb563f5SRyusuke Konishi nilfs_put_writer(nilfs); 1325eb563f5SRyusuke Konishi out: 1335eb563f5SRyusuke Konishi return err; 1345eb563f5SRyusuke Konishi } 1355eb563f5SRyusuke Konishi 1365eb563f5SRyusuke Konishi static int 1375eb563f5SRyusuke Konishi nilfs_mdt_submit_block(struct inode *inode, unsigned long blkoff, 1385eb563f5SRyusuke Konishi int mode, struct buffer_head **out_bh) 1395eb563f5SRyusuke Konishi { 1405eb563f5SRyusuke Konishi struct buffer_head *bh; 1415eb563f5SRyusuke Konishi unsigned long blknum = 0; 1425eb563f5SRyusuke Konishi int ret = -ENOMEM; 1435eb563f5SRyusuke Konishi 1445eb563f5SRyusuke Konishi bh = nilfs_grab_buffer(inode, inode->i_mapping, blkoff, 0); 1455eb563f5SRyusuke Konishi if (unlikely(!bh)) 1465eb563f5SRyusuke Konishi goto failed; 1475eb563f5SRyusuke Konishi 1485eb563f5SRyusuke Konishi ret = -EEXIST; /* internal code */ 1495eb563f5SRyusuke Konishi if (buffer_uptodate(bh)) 1505eb563f5SRyusuke Konishi goto out; 1515eb563f5SRyusuke Konishi 1525eb563f5SRyusuke Konishi if (mode == READA) { 1535eb563f5SRyusuke Konishi if (!trylock_buffer(bh)) { 1545eb563f5SRyusuke Konishi ret = -EBUSY; 1555eb563f5SRyusuke Konishi goto failed_bh; 1565eb563f5SRyusuke Konishi } 1571f5abe7eSRyusuke Konishi } else /* mode == READ */ 1585eb563f5SRyusuke Konishi lock_buffer(bh); 1595eb563f5SRyusuke Konishi 1605eb563f5SRyusuke Konishi if (buffer_uptodate(bh)) { 1615eb563f5SRyusuke Konishi unlock_buffer(bh); 1625eb563f5SRyusuke Konishi goto out; 1635eb563f5SRyusuke Konishi } 1645eb563f5SRyusuke Konishi if (!buffer_mapped(bh)) { /* unused buffer */ 1655eb563f5SRyusuke Konishi ret = nilfs_bmap_lookup(NILFS_I(inode)->i_bmap, blkoff, 1665eb563f5SRyusuke Konishi &blknum); 1675eb563f5SRyusuke Konishi if (unlikely(ret)) { 1685eb563f5SRyusuke Konishi unlock_buffer(bh); 1695eb563f5SRyusuke Konishi goto failed_bh; 1705eb563f5SRyusuke Konishi } 1715eb563f5SRyusuke Konishi bh->b_bdev = NILFS_MDT(inode)->mi_nilfs->ns_bdev; 1725eb563f5SRyusuke Konishi bh->b_blocknr = blknum; 1735eb563f5SRyusuke Konishi set_buffer_mapped(bh); 1745eb563f5SRyusuke Konishi } 1755eb563f5SRyusuke Konishi 1765eb563f5SRyusuke Konishi bh->b_end_io = end_buffer_read_sync; 1775eb563f5SRyusuke Konishi get_bh(bh); 1785eb563f5SRyusuke Konishi submit_bh(mode, bh); 1795eb563f5SRyusuke Konishi ret = 0; 1805eb563f5SRyusuke Konishi out: 1815eb563f5SRyusuke Konishi get_bh(bh); 1825eb563f5SRyusuke Konishi *out_bh = bh; 1835eb563f5SRyusuke Konishi 1845eb563f5SRyusuke Konishi failed_bh: 1855eb563f5SRyusuke Konishi unlock_page(bh->b_page); 1865eb563f5SRyusuke Konishi page_cache_release(bh->b_page); 1875eb563f5SRyusuke Konishi brelse(bh); 1885eb563f5SRyusuke Konishi failed: 1895eb563f5SRyusuke Konishi return ret; 1905eb563f5SRyusuke Konishi } 1915eb563f5SRyusuke Konishi 1925eb563f5SRyusuke Konishi static int nilfs_mdt_read_block(struct inode *inode, unsigned long block, 1935eb563f5SRyusuke Konishi struct buffer_head **out_bh) 1945eb563f5SRyusuke Konishi { 1955eb563f5SRyusuke Konishi struct buffer_head *first_bh, *bh; 1965eb563f5SRyusuke Konishi unsigned long blkoff; 1975eb563f5SRyusuke Konishi int i, nr_ra_blocks = NILFS_MDT_MAX_RA_BLOCKS; 1985eb563f5SRyusuke Konishi int err; 1995eb563f5SRyusuke Konishi 2005eb563f5SRyusuke Konishi err = nilfs_mdt_submit_block(inode, block, READ, &first_bh); 2015eb563f5SRyusuke Konishi if (err == -EEXIST) /* internal code */ 2025eb563f5SRyusuke Konishi goto out; 2035eb563f5SRyusuke Konishi 2045eb563f5SRyusuke Konishi if (unlikely(err)) 2055eb563f5SRyusuke Konishi goto failed; 2065eb563f5SRyusuke Konishi 2075eb563f5SRyusuke Konishi blkoff = block + 1; 2085eb563f5SRyusuke Konishi for (i = 0; i < nr_ra_blocks; i++, blkoff++) { 2095eb563f5SRyusuke Konishi err = nilfs_mdt_submit_block(inode, blkoff, READA, &bh); 2105eb563f5SRyusuke Konishi if (likely(!err || err == -EEXIST)) 2115eb563f5SRyusuke Konishi brelse(bh); 2125eb563f5SRyusuke Konishi else if (err != -EBUSY) 2135eb563f5SRyusuke Konishi break; /* abort readahead if bmap lookup failed */ 2145eb563f5SRyusuke Konishi 2155eb563f5SRyusuke Konishi if (!buffer_locked(first_bh)) 2165eb563f5SRyusuke Konishi goto out_no_wait; 2175eb563f5SRyusuke Konishi } 2185eb563f5SRyusuke Konishi 2195eb563f5SRyusuke Konishi wait_on_buffer(first_bh); 2205eb563f5SRyusuke Konishi 2215eb563f5SRyusuke Konishi out_no_wait: 2225eb563f5SRyusuke Konishi err = -EIO; 2235eb563f5SRyusuke Konishi if (!buffer_uptodate(first_bh)) 2245eb563f5SRyusuke Konishi goto failed_bh; 2255eb563f5SRyusuke Konishi out: 2265eb563f5SRyusuke Konishi *out_bh = first_bh; 2275eb563f5SRyusuke Konishi return 0; 2285eb563f5SRyusuke Konishi 2295eb563f5SRyusuke Konishi failed_bh: 2305eb563f5SRyusuke Konishi brelse(first_bh); 2315eb563f5SRyusuke Konishi failed: 2325eb563f5SRyusuke Konishi return err; 2335eb563f5SRyusuke Konishi } 2345eb563f5SRyusuke Konishi 2355eb563f5SRyusuke Konishi /** 2365eb563f5SRyusuke Konishi * nilfs_mdt_get_block - read or create a buffer on meta data file. 2375eb563f5SRyusuke Konishi * @inode: inode of the meta data file 2385eb563f5SRyusuke Konishi * @blkoff: block offset 2395eb563f5SRyusuke Konishi * @create: create flag 2405eb563f5SRyusuke Konishi * @init_block: initializer used for newly allocated block 2415eb563f5SRyusuke Konishi * @out_bh: output of a pointer to the buffer_head 2425eb563f5SRyusuke Konishi * 2435eb563f5SRyusuke Konishi * nilfs_mdt_get_block() looks up the specified buffer and tries to create 2445eb563f5SRyusuke Konishi * a new buffer if @create is not zero. On success, the returned buffer is 2455eb563f5SRyusuke Konishi * assured to be either existing or formatted using a buffer lock on success. 2465eb563f5SRyusuke Konishi * @out_bh is substituted only when zero is returned. 2475eb563f5SRyusuke Konishi * 2485eb563f5SRyusuke Konishi * Return Value: On success, it returns 0. On error, the following negative 2495eb563f5SRyusuke Konishi * error code is returned. 2505eb563f5SRyusuke Konishi * 2515eb563f5SRyusuke Konishi * %-ENOMEM - Insufficient memory available. 2525eb563f5SRyusuke Konishi * 2535eb563f5SRyusuke Konishi * %-EIO - I/O error 2545eb563f5SRyusuke Konishi * 2555eb563f5SRyusuke Konishi * %-ENOENT - the specified block does not exist (hole block) 2565eb563f5SRyusuke Konishi * 2575eb563f5SRyusuke Konishi * %-EINVAL - bmap is broken. (the caller should call nilfs_error()) 2585eb563f5SRyusuke Konishi * 2595eb563f5SRyusuke Konishi * %-EROFS - Read only filesystem (for create mode) 2605eb563f5SRyusuke Konishi */ 2615eb563f5SRyusuke Konishi int nilfs_mdt_get_block(struct inode *inode, unsigned long blkoff, int create, 2625eb563f5SRyusuke Konishi void (*init_block)(struct inode *, 2635eb563f5SRyusuke Konishi struct buffer_head *, void *), 2645eb563f5SRyusuke Konishi struct buffer_head **out_bh) 2655eb563f5SRyusuke Konishi { 2665eb563f5SRyusuke Konishi int ret; 2675eb563f5SRyusuke Konishi 2685eb563f5SRyusuke Konishi /* Should be rewritten with merging nilfs_mdt_read_block() */ 2695eb563f5SRyusuke Konishi retry: 2705eb563f5SRyusuke Konishi ret = nilfs_mdt_read_block(inode, blkoff, out_bh); 2715eb563f5SRyusuke Konishi if (!create || ret != -ENOENT) 2725eb563f5SRyusuke Konishi return ret; 2735eb563f5SRyusuke Konishi 2745eb563f5SRyusuke Konishi ret = nilfs_mdt_create_block(inode, blkoff, out_bh, init_block); 2755eb563f5SRyusuke Konishi if (unlikely(ret == -EEXIST)) { 2765eb563f5SRyusuke Konishi /* create = 0; */ /* limit read-create loop retries */ 2775eb563f5SRyusuke Konishi goto retry; 2785eb563f5SRyusuke Konishi } 2795eb563f5SRyusuke Konishi return ret; 2805eb563f5SRyusuke Konishi } 2815eb563f5SRyusuke Konishi 2825eb563f5SRyusuke Konishi /** 2835eb563f5SRyusuke Konishi * nilfs_mdt_delete_block - make a hole on the meta data file. 2845eb563f5SRyusuke Konishi * @inode: inode of the meta data file 2855eb563f5SRyusuke Konishi * @block: block offset 2865eb563f5SRyusuke Konishi * 2875eb563f5SRyusuke Konishi * Return Value: On success, zero is returned. 2885eb563f5SRyusuke Konishi * On error, one of the following negative error code is returned. 2895eb563f5SRyusuke Konishi * 2905eb563f5SRyusuke Konishi * %-ENOMEM - Insufficient memory available. 2915eb563f5SRyusuke Konishi * 2925eb563f5SRyusuke Konishi * %-EIO - I/O error 2935eb563f5SRyusuke Konishi * 2945eb563f5SRyusuke Konishi * %-EINVAL - bmap is broken. (the caller should call nilfs_error()) 2955eb563f5SRyusuke Konishi */ 2965eb563f5SRyusuke Konishi int nilfs_mdt_delete_block(struct inode *inode, unsigned long block) 2975eb563f5SRyusuke Konishi { 2985eb563f5SRyusuke Konishi struct nilfs_inode_info *ii = NILFS_I(inode); 2995eb563f5SRyusuke Konishi int err; 3005eb563f5SRyusuke Konishi 3015eb563f5SRyusuke Konishi err = nilfs_bmap_delete(ii->i_bmap, block); 3025eb563f5SRyusuke Konishi if (likely(!err)) { 3035eb563f5SRyusuke Konishi nilfs_mdt_mark_dirty(inode); 3045eb563f5SRyusuke Konishi nilfs_mdt_forget_block(inode, block); 3055eb563f5SRyusuke Konishi } 3065eb563f5SRyusuke Konishi return err; 3075eb563f5SRyusuke Konishi } 3085eb563f5SRyusuke Konishi 3095eb563f5SRyusuke Konishi /** 3105eb563f5SRyusuke Konishi * nilfs_mdt_forget_block - discard dirty state and try to remove the page 3115eb563f5SRyusuke Konishi * @inode: inode of the meta data file 3125eb563f5SRyusuke Konishi * @block: block offset 3135eb563f5SRyusuke Konishi * 3145eb563f5SRyusuke Konishi * nilfs_mdt_forget_block() clears a dirty flag of the specified buffer, and 3155eb563f5SRyusuke Konishi * tries to release the page including the buffer from a page cache. 3165eb563f5SRyusuke Konishi * 3175eb563f5SRyusuke Konishi * Return Value: On success, 0 is returned. On error, one of the following 3185eb563f5SRyusuke Konishi * negative error code is returned. 3195eb563f5SRyusuke Konishi * 3205eb563f5SRyusuke Konishi * %-EBUSY - page has an active buffer. 3215eb563f5SRyusuke Konishi * 3225eb563f5SRyusuke Konishi * %-ENOENT - page cache has no page addressed by the offset. 3235eb563f5SRyusuke Konishi */ 3245eb563f5SRyusuke Konishi int nilfs_mdt_forget_block(struct inode *inode, unsigned long block) 3255eb563f5SRyusuke Konishi { 3265eb563f5SRyusuke Konishi pgoff_t index = (pgoff_t)block >> 3275eb563f5SRyusuke Konishi (PAGE_CACHE_SHIFT - inode->i_blkbits); 3285eb563f5SRyusuke Konishi struct page *page; 3295eb563f5SRyusuke Konishi unsigned long first_block; 3305eb563f5SRyusuke Konishi int ret = 0; 3315eb563f5SRyusuke Konishi int still_dirty; 3325eb563f5SRyusuke Konishi 3335eb563f5SRyusuke Konishi page = find_lock_page(inode->i_mapping, index); 3345eb563f5SRyusuke Konishi if (!page) 3355eb563f5SRyusuke Konishi return -ENOENT; 3365eb563f5SRyusuke Konishi 3375eb563f5SRyusuke Konishi wait_on_page_writeback(page); 3385eb563f5SRyusuke Konishi 3395eb563f5SRyusuke Konishi first_block = (unsigned long)index << 3405eb563f5SRyusuke Konishi (PAGE_CACHE_SHIFT - inode->i_blkbits); 3415eb563f5SRyusuke Konishi if (page_has_buffers(page)) { 3425eb563f5SRyusuke Konishi struct buffer_head *bh; 3435eb563f5SRyusuke Konishi 3445eb563f5SRyusuke Konishi bh = nilfs_page_get_nth_block(page, block - first_block); 3455eb563f5SRyusuke Konishi nilfs_forget_buffer(bh); 3465eb563f5SRyusuke Konishi } 3475eb563f5SRyusuke Konishi still_dirty = PageDirty(page); 3485eb563f5SRyusuke Konishi unlock_page(page); 3495eb563f5SRyusuke Konishi page_cache_release(page); 3505eb563f5SRyusuke Konishi 3515eb563f5SRyusuke Konishi if (still_dirty || 3525eb563f5SRyusuke Konishi invalidate_inode_pages2_range(inode->i_mapping, index, index) != 0) 3535eb563f5SRyusuke Konishi ret = -EBUSY; 3545eb563f5SRyusuke Konishi return ret; 3555eb563f5SRyusuke Konishi } 3565eb563f5SRyusuke Konishi 3575eb563f5SRyusuke Konishi /** 3585eb563f5SRyusuke Konishi * nilfs_mdt_mark_block_dirty - mark a block on the meta data file dirty. 3595eb563f5SRyusuke Konishi * @inode: inode of the meta data file 3605eb563f5SRyusuke Konishi * @block: block offset 3615eb563f5SRyusuke Konishi * 3625eb563f5SRyusuke Konishi * Return Value: On success, it returns 0. On error, the following negative 3635eb563f5SRyusuke Konishi * error code is returned. 3645eb563f5SRyusuke Konishi * 3655eb563f5SRyusuke Konishi * %-ENOMEM - Insufficient memory available. 3665eb563f5SRyusuke Konishi * 3675eb563f5SRyusuke Konishi * %-EIO - I/O error 3685eb563f5SRyusuke Konishi * 3695eb563f5SRyusuke Konishi * %-ENOENT - the specified block does not exist (hole block) 3705eb563f5SRyusuke Konishi * 3715eb563f5SRyusuke Konishi * %-EINVAL - bmap is broken. (the caller should call nilfs_error()) 3725eb563f5SRyusuke Konishi */ 3735eb563f5SRyusuke Konishi int nilfs_mdt_mark_block_dirty(struct inode *inode, unsigned long block) 3745eb563f5SRyusuke Konishi { 3755eb563f5SRyusuke Konishi struct buffer_head *bh; 3765eb563f5SRyusuke Konishi int err; 3775eb563f5SRyusuke Konishi 3785eb563f5SRyusuke Konishi err = nilfs_mdt_read_block(inode, block, &bh); 3795eb563f5SRyusuke Konishi if (unlikely(err)) 3805eb563f5SRyusuke Konishi return err; 3815eb563f5SRyusuke Konishi nilfs_mark_buffer_dirty(bh); 3825eb563f5SRyusuke Konishi nilfs_mdt_mark_dirty(inode); 3835eb563f5SRyusuke Konishi brelse(bh); 3845eb563f5SRyusuke Konishi return 0; 3855eb563f5SRyusuke Konishi } 3865eb563f5SRyusuke Konishi 3875eb563f5SRyusuke Konishi int nilfs_mdt_fetch_dirty(struct inode *inode) 3885eb563f5SRyusuke Konishi { 3895eb563f5SRyusuke Konishi struct nilfs_inode_info *ii = NILFS_I(inode); 3905eb563f5SRyusuke Konishi 3915eb563f5SRyusuke Konishi if (nilfs_bmap_test_and_clear_dirty(ii->i_bmap)) { 3925eb563f5SRyusuke Konishi set_bit(NILFS_I_DIRTY, &ii->i_state); 3935eb563f5SRyusuke Konishi return 1; 3945eb563f5SRyusuke Konishi } 3955eb563f5SRyusuke Konishi return test_bit(NILFS_I_DIRTY, &ii->i_state); 3965eb563f5SRyusuke Konishi } 3975eb563f5SRyusuke Konishi 3985eb563f5SRyusuke Konishi static int 3995eb563f5SRyusuke Konishi nilfs_mdt_write_page(struct page *page, struct writeback_control *wbc) 4005eb563f5SRyusuke Konishi { 4015eb563f5SRyusuke Konishi struct inode *inode = container_of(page->mapping, 4025eb563f5SRyusuke Konishi struct inode, i_data); 4035eb563f5SRyusuke Konishi struct super_block *sb = inode->i_sb; 4045eb563f5SRyusuke Konishi struct nilfs_sb_info *writer = NULL; 4055eb563f5SRyusuke Konishi int err = 0; 4065eb563f5SRyusuke Konishi 4075eb563f5SRyusuke Konishi redirty_page_for_writepage(wbc, page); 4085eb563f5SRyusuke Konishi unlock_page(page); 4095eb563f5SRyusuke Konishi 4105eb563f5SRyusuke Konishi if (page->mapping->assoc_mapping) 4115eb563f5SRyusuke Konishi return 0; /* Do not request flush for shadow page cache */ 4125eb563f5SRyusuke Konishi if (!sb) { 4135eb563f5SRyusuke Konishi writer = nilfs_get_writer(NILFS_MDT(inode)->mi_nilfs); 4145eb563f5SRyusuke Konishi if (!writer) 4155eb563f5SRyusuke Konishi return -EROFS; 4165eb563f5SRyusuke Konishi sb = writer->s_super; 4175eb563f5SRyusuke Konishi } 4185eb563f5SRyusuke Konishi 4195eb563f5SRyusuke Konishi if (wbc->sync_mode == WB_SYNC_ALL) 4205eb563f5SRyusuke Konishi err = nilfs_construct_segment(sb); 4215eb563f5SRyusuke Konishi else if (wbc->for_reclaim) 4225eb563f5SRyusuke Konishi nilfs_flush_segment(sb, inode->i_ino); 4235eb563f5SRyusuke Konishi 4245eb563f5SRyusuke Konishi if (writer) 4255eb563f5SRyusuke Konishi nilfs_put_writer(NILFS_MDT(inode)->mi_nilfs); 4265eb563f5SRyusuke Konishi return err; 4275eb563f5SRyusuke Konishi } 4285eb563f5SRyusuke Konishi 4295eb563f5SRyusuke Konishi 4305eb563f5SRyusuke Konishi static struct address_space_operations def_mdt_aops = { 4315eb563f5SRyusuke Konishi .writepage = nilfs_mdt_write_page, 4325eb563f5SRyusuke Konishi }; 4335eb563f5SRyusuke Konishi 4345eb563f5SRyusuke Konishi static struct inode_operations def_mdt_iops; 4355eb563f5SRyusuke Konishi static struct file_operations def_mdt_fops; 4365eb563f5SRyusuke Konishi 4375eb563f5SRyusuke Konishi /* 4385eb563f5SRyusuke Konishi * NILFS2 uses pseudo inodes for meta data files such as DAT, cpfile, sufile, 4395eb563f5SRyusuke Konishi * ifile, or gcinodes. This allows the B-tree code and segment constructor 4405eb563f5SRyusuke Konishi * to treat them like regular files, and this helps to simplify the 4415eb563f5SRyusuke Konishi * implementation. 4425eb563f5SRyusuke Konishi * On the other hand, some of the pseudo inodes have an irregular point: 4435eb563f5SRyusuke Konishi * They don't have valid inode->i_sb pointer because their lifetimes are 4445eb563f5SRyusuke Konishi * longer than those of the super block structs; they may continue for 4455eb563f5SRyusuke Konishi * several consecutive mounts/umounts. This would need discussions. 4465eb563f5SRyusuke Konishi */ 4475eb563f5SRyusuke Konishi struct inode * 4485eb563f5SRyusuke Konishi nilfs_mdt_new_common(struct the_nilfs *nilfs, struct super_block *sb, 4495eb563f5SRyusuke Konishi ino_t ino, gfp_t gfp_mask) 4505eb563f5SRyusuke Konishi { 4515eb563f5SRyusuke Konishi struct inode *inode = nilfs_alloc_inode(sb); 4525eb563f5SRyusuke Konishi 4535eb563f5SRyusuke Konishi if (!inode) 4545eb563f5SRyusuke Konishi return NULL; 4555eb563f5SRyusuke Konishi else { 4565eb563f5SRyusuke Konishi struct address_space * const mapping = &inode->i_data; 4575eb563f5SRyusuke Konishi struct nilfs_mdt_info *mi = kzalloc(sizeof(*mi), GFP_NOFS); 4585eb563f5SRyusuke Konishi 4595eb563f5SRyusuke Konishi if (!mi) { 4605eb563f5SRyusuke Konishi nilfs_destroy_inode(inode); 4615eb563f5SRyusuke Konishi return NULL; 4625eb563f5SRyusuke Konishi } 4635eb563f5SRyusuke Konishi mi->mi_nilfs = nilfs; 4645eb563f5SRyusuke Konishi init_rwsem(&mi->mi_sem); 4655eb563f5SRyusuke Konishi 4665eb563f5SRyusuke Konishi inode->i_sb = sb; /* sb may be NULL for some meta data files */ 4675eb563f5SRyusuke Konishi inode->i_blkbits = nilfs->ns_blocksize_bits; 4685eb563f5SRyusuke Konishi inode->i_flags = 0; 4695eb563f5SRyusuke Konishi atomic_set(&inode->i_count, 1); 4705eb563f5SRyusuke Konishi inode->i_nlink = 1; 4715eb563f5SRyusuke Konishi inode->i_ino = ino; 4725eb563f5SRyusuke Konishi inode->i_mode = S_IFREG; 4735eb563f5SRyusuke Konishi inode->i_private = mi; 4745eb563f5SRyusuke Konishi 4755eb563f5SRyusuke Konishi #ifdef INIT_UNUSED_INODE_FIELDS 4765eb563f5SRyusuke Konishi atomic_set(&inode->i_writecount, 0); 4775eb563f5SRyusuke Konishi inode->i_size = 0; 4785eb563f5SRyusuke Konishi inode->i_blocks = 0; 4795eb563f5SRyusuke Konishi inode->i_bytes = 0; 4805eb563f5SRyusuke Konishi inode->i_generation = 0; 4815eb563f5SRyusuke Konishi #ifdef CONFIG_QUOTA 4825eb563f5SRyusuke Konishi memset(&inode->i_dquot, 0, sizeof(inode->i_dquot)); 4835eb563f5SRyusuke Konishi #endif 4845eb563f5SRyusuke Konishi inode->i_pipe = NULL; 4855eb563f5SRyusuke Konishi inode->i_bdev = NULL; 4865eb563f5SRyusuke Konishi inode->i_cdev = NULL; 4875eb563f5SRyusuke Konishi inode->i_rdev = 0; 4885eb563f5SRyusuke Konishi #ifdef CONFIG_SECURITY 4895eb563f5SRyusuke Konishi inode->i_security = NULL; 4905eb563f5SRyusuke Konishi #endif 4915eb563f5SRyusuke Konishi inode->dirtied_when = 0; 4925eb563f5SRyusuke Konishi 4935eb563f5SRyusuke Konishi INIT_LIST_HEAD(&inode->i_list); 4945eb563f5SRyusuke Konishi INIT_LIST_HEAD(&inode->i_sb_list); 4955eb563f5SRyusuke Konishi inode->i_state = 0; 4965eb563f5SRyusuke Konishi #endif 4975eb563f5SRyusuke Konishi 4985eb563f5SRyusuke Konishi spin_lock_init(&inode->i_lock); 4995eb563f5SRyusuke Konishi mutex_init(&inode->i_mutex); 5005eb563f5SRyusuke Konishi init_rwsem(&inode->i_alloc_sem); 5015eb563f5SRyusuke Konishi 5025eb563f5SRyusuke Konishi mapping->host = NULL; /* instead of inode */ 5035eb563f5SRyusuke Konishi mapping->flags = 0; 5045eb563f5SRyusuke Konishi mapping_set_gfp_mask(mapping, gfp_mask); 5055eb563f5SRyusuke Konishi mapping->assoc_mapping = NULL; 5065eb563f5SRyusuke Konishi mapping->backing_dev_info = nilfs->ns_bdi; 5075eb563f5SRyusuke Konishi 5085eb563f5SRyusuke Konishi inode->i_mapping = mapping; 5095eb563f5SRyusuke Konishi } 5105eb563f5SRyusuke Konishi 5115eb563f5SRyusuke Konishi return inode; 5125eb563f5SRyusuke Konishi } 5135eb563f5SRyusuke Konishi 5145eb563f5SRyusuke Konishi struct inode *nilfs_mdt_new(struct the_nilfs *nilfs, struct super_block *sb, 5155eb563f5SRyusuke Konishi ino_t ino, gfp_t gfp_mask) 5165eb563f5SRyusuke Konishi { 5175eb563f5SRyusuke Konishi struct inode *inode = nilfs_mdt_new_common(nilfs, sb, ino, gfp_mask); 5185eb563f5SRyusuke Konishi 5195eb563f5SRyusuke Konishi if (!inode) 5205eb563f5SRyusuke Konishi return NULL; 5215eb563f5SRyusuke Konishi 5225eb563f5SRyusuke Konishi inode->i_op = &def_mdt_iops; 5235eb563f5SRyusuke Konishi inode->i_fop = &def_mdt_fops; 5245eb563f5SRyusuke Konishi inode->i_mapping->a_ops = &def_mdt_aops; 5255eb563f5SRyusuke Konishi return inode; 5265eb563f5SRyusuke Konishi } 5275eb563f5SRyusuke Konishi 5285eb563f5SRyusuke Konishi void nilfs_mdt_set_entry_size(struct inode *inode, unsigned entry_size, 5295eb563f5SRyusuke Konishi unsigned header_size) 5305eb563f5SRyusuke Konishi { 5315eb563f5SRyusuke Konishi struct nilfs_mdt_info *mi = NILFS_MDT(inode); 5325eb563f5SRyusuke Konishi 5335eb563f5SRyusuke Konishi mi->mi_entry_size = entry_size; 5345eb563f5SRyusuke Konishi mi->mi_entries_per_block = (1 << inode->i_blkbits) / entry_size; 5355eb563f5SRyusuke Konishi mi->mi_first_entry_offset = DIV_ROUND_UP(header_size, entry_size); 5365eb563f5SRyusuke Konishi } 5375eb563f5SRyusuke Konishi 5385eb563f5SRyusuke Konishi void nilfs_mdt_set_shadow(struct inode *orig, struct inode *shadow) 5395eb563f5SRyusuke Konishi { 5405eb563f5SRyusuke Konishi shadow->i_mapping->assoc_mapping = orig->i_mapping; 5415eb563f5SRyusuke Konishi NILFS_I(shadow)->i_btnode_cache.assoc_mapping = 5425eb563f5SRyusuke Konishi &NILFS_I(orig)->i_btnode_cache; 5435eb563f5SRyusuke Konishi } 5445eb563f5SRyusuke Konishi 5455eb563f5SRyusuke Konishi void nilfs_mdt_clear(struct inode *inode) 5465eb563f5SRyusuke Konishi { 5475eb563f5SRyusuke Konishi struct nilfs_inode_info *ii = NILFS_I(inode); 5485eb563f5SRyusuke Konishi 5495eb563f5SRyusuke Konishi invalidate_mapping_pages(inode->i_mapping, 0, -1); 5505eb563f5SRyusuke Konishi truncate_inode_pages(inode->i_mapping, 0); 5515eb563f5SRyusuke Konishi 5525eb563f5SRyusuke Konishi nilfs_bmap_clear(ii->i_bmap); 5535eb563f5SRyusuke Konishi nilfs_btnode_cache_clear(&ii->i_btnode_cache); 5545eb563f5SRyusuke Konishi } 5555eb563f5SRyusuke Konishi 5565eb563f5SRyusuke Konishi void nilfs_mdt_destroy(struct inode *inode) 5575eb563f5SRyusuke Konishi { 5585eb563f5SRyusuke Konishi struct nilfs_mdt_info *mdi = NILFS_MDT(inode); 5595eb563f5SRyusuke Konishi 5605eb563f5SRyusuke Konishi kfree(mdi->mi_bgl); /* kfree(NULL) is safe */ 5615eb563f5SRyusuke Konishi kfree(mdi); 5625eb563f5SRyusuke Konishi nilfs_destroy_inode(inode); 5635eb563f5SRyusuke Konishi } 564