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 super_block *sb = inode->i_sb; 815eb563f5SRyusuke Konishi struct nilfs_transaction_info ti; 825eb563f5SRyusuke Konishi struct buffer_head *bh; 835eb563f5SRyusuke Konishi int err; 845eb563f5SRyusuke Konishi 855eb563f5SRyusuke Konishi if (!sb) { 86201913edSRyusuke Konishi /* 87201913edSRyusuke Konishi * Make sure this function is not called from any 88201913edSRyusuke Konishi * read-only context. 89201913edSRyusuke Konishi */ 90201913edSRyusuke Konishi if (!nilfs->ns_writer) { 91201913edSRyusuke Konishi WARN_ON(1); 925eb563f5SRyusuke Konishi err = -EROFS; 935eb563f5SRyusuke Konishi goto out; 945eb563f5SRyusuke Konishi } 95201913edSRyusuke Konishi sb = nilfs->ns_writer->s_super; 965eb563f5SRyusuke Konishi } 975eb563f5SRyusuke Konishi 985eb563f5SRyusuke Konishi nilfs_transaction_begin(sb, &ti, 0); 995eb563f5SRyusuke Konishi 1005eb563f5SRyusuke Konishi err = -ENOMEM; 1015eb563f5SRyusuke Konishi bh = nilfs_grab_buffer(inode, inode->i_mapping, block, 0); 1025eb563f5SRyusuke Konishi if (unlikely(!bh)) 1035eb563f5SRyusuke Konishi goto failed_unlock; 1045eb563f5SRyusuke Konishi 1055eb563f5SRyusuke Konishi err = -EEXIST; 10614351104SRyusuke Konishi if (buffer_uptodate(bh)) 1075eb563f5SRyusuke Konishi goto failed_bh; 10814351104SRyusuke Konishi 1095eb563f5SRyusuke Konishi wait_on_buffer(bh); 1105eb563f5SRyusuke Konishi if (buffer_uptodate(bh)) 1115eb563f5SRyusuke Konishi goto failed_bh; 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 out: 1315eb563f5SRyusuke Konishi return err; 1325eb563f5SRyusuke Konishi } 1335eb563f5SRyusuke Konishi 1345eb563f5SRyusuke Konishi static int 1355eb563f5SRyusuke Konishi nilfs_mdt_submit_block(struct inode *inode, unsigned long blkoff, 1365eb563f5SRyusuke Konishi int mode, struct buffer_head **out_bh) 1375eb563f5SRyusuke Konishi { 1385eb563f5SRyusuke Konishi struct buffer_head *bh; 1390f3fe33bSRyusuke Konishi __u64 blknum = 0; 1405eb563f5SRyusuke Konishi int ret = -ENOMEM; 1415eb563f5SRyusuke Konishi 1425eb563f5SRyusuke Konishi bh = nilfs_grab_buffer(inode, inode->i_mapping, blkoff, 0); 1435eb563f5SRyusuke Konishi if (unlikely(!bh)) 1445eb563f5SRyusuke Konishi goto failed; 1455eb563f5SRyusuke Konishi 1465eb563f5SRyusuke Konishi ret = -EEXIST; /* internal code */ 1475eb563f5SRyusuke Konishi if (buffer_uptodate(bh)) 1485eb563f5SRyusuke Konishi goto out; 1495eb563f5SRyusuke Konishi 1505eb563f5SRyusuke Konishi if (mode == READA) { 1515eb563f5SRyusuke Konishi if (!trylock_buffer(bh)) { 1525eb563f5SRyusuke Konishi ret = -EBUSY; 1535eb563f5SRyusuke Konishi goto failed_bh; 1545eb563f5SRyusuke Konishi } 1551f5abe7eSRyusuke Konishi } else /* mode == READ */ 1565eb563f5SRyusuke Konishi lock_buffer(bh); 1575eb563f5SRyusuke Konishi 1585eb563f5SRyusuke Konishi if (buffer_uptodate(bh)) { 1595eb563f5SRyusuke Konishi unlock_buffer(bh); 1605eb563f5SRyusuke Konishi goto out; 1615eb563f5SRyusuke Konishi } 16214351104SRyusuke Konishi 16314351104SRyusuke Konishi ret = nilfs_bmap_lookup(NILFS_I(inode)->i_bmap, blkoff, &blknum); 1645eb563f5SRyusuke Konishi if (unlikely(ret)) { 1655eb563f5SRyusuke Konishi unlock_buffer(bh); 1665eb563f5SRyusuke Konishi goto failed_bh; 1675eb563f5SRyusuke Konishi } 1685eb563f5SRyusuke Konishi bh->b_bdev = NILFS_MDT(inode)->mi_nilfs->ns_bdev; 1690f3fe33bSRyusuke Konishi bh->b_blocknr = (sector_t)blknum; 1705eb563f5SRyusuke Konishi set_buffer_mapped(bh); 1715eb563f5SRyusuke Konishi 1725eb563f5SRyusuke Konishi bh->b_end_io = end_buffer_read_sync; 1735eb563f5SRyusuke Konishi get_bh(bh); 1745eb563f5SRyusuke Konishi submit_bh(mode, bh); 1755eb563f5SRyusuke Konishi ret = 0; 1765eb563f5SRyusuke Konishi out: 1775eb563f5SRyusuke Konishi get_bh(bh); 1785eb563f5SRyusuke Konishi *out_bh = bh; 1795eb563f5SRyusuke Konishi 1805eb563f5SRyusuke Konishi failed_bh: 1815eb563f5SRyusuke Konishi unlock_page(bh->b_page); 1825eb563f5SRyusuke Konishi page_cache_release(bh->b_page); 1835eb563f5SRyusuke Konishi brelse(bh); 1845eb563f5SRyusuke Konishi failed: 1855eb563f5SRyusuke Konishi return ret; 1865eb563f5SRyusuke Konishi } 1875eb563f5SRyusuke Konishi 1885eb563f5SRyusuke Konishi static int nilfs_mdt_read_block(struct inode *inode, unsigned long block, 1895eb563f5SRyusuke Konishi struct buffer_head **out_bh) 1905eb563f5SRyusuke Konishi { 1915eb563f5SRyusuke Konishi struct buffer_head *first_bh, *bh; 1925eb563f5SRyusuke Konishi unsigned long blkoff; 1935eb563f5SRyusuke Konishi int i, nr_ra_blocks = NILFS_MDT_MAX_RA_BLOCKS; 1945eb563f5SRyusuke Konishi int err; 1955eb563f5SRyusuke Konishi 1965eb563f5SRyusuke Konishi err = nilfs_mdt_submit_block(inode, block, READ, &first_bh); 1975eb563f5SRyusuke Konishi if (err == -EEXIST) /* internal code */ 1985eb563f5SRyusuke Konishi goto out; 1995eb563f5SRyusuke Konishi 2005eb563f5SRyusuke Konishi if (unlikely(err)) 2015eb563f5SRyusuke Konishi goto failed; 2025eb563f5SRyusuke Konishi 2035eb563f5SRyusuke Konishi blkoff = block + 1; 2045eb563f5SRyusuke Konishi for (i = 0; i < nr_ra_blocks; i++, blkoff++) { 2055eb563f5SRyusuke Konishi err = nilfs_mdt_submit_block(inode, blkoff, READA, &bh); 2065eb563f5SRyusuke Konishi if (likely(!err || err == -EEXIST)) 2075eb563f5SRyusuke Konishi brelse(bh); 2085eb563f5SRyusuke Konishi else if (err != -EBUSY) 2095eb563f5SRyusuke Konishi break; /* abort readahead if bmap lookup failed */ 2105eb563f5SRyusuke Konishi 2115eb563f5SRyusuke Konishi if (!buffer_locked(first_bh)) 2125eb563f5SRyusuke Konishi goto out_no_wait; 2135eb563f5SRyusuke Konishi } 2145eb563f5SRyusuke Konishi 2155eb563f5SRyusuke Konishi wait_on_buffer(first_bh); 2165eb563f5SRyusuke Konishi 2175eb563f5SRyusuke Konishi out_no_wait: 2185eb563f5SRyusuke Konishi err = -EIO; 2195eb563f5SRyusuke Konishi if (!buffer_uptodate(first_bh)) 2205eb563f5SRyusuke Konishi goto failed_bh; 2215eb563f5SRyusuke Konishi out: 2225eb563f5SRyusuke Konishi *out_bh = first_bh; 2235eb563f5SRyusuke Konishi return 0; 2245eb563f5SRyusuke Konishi 2255eb563f5SRyusuke Konishi failed_bh: 2265eb563f5SRyusuke Konishi brelse(first_bh); 2275eb563f5SRyusuke Konishi failed: 2285eb563f5SRyusuke Konishi return err; 2295eb563f5SRyusuke Konishi } 2305eb563f5SRyusuke Konishi 2315eb563f5SRyusuke Konishi /** 2325eb563f5SRyusuke Konishi * nilfs_mdt_get_block - read or create a buffer on meta data file. 2335eb563f5SRyusuke Konishi * @inode: inode of the meta data file 2345eb563f5SRyusuke Konishi * @blkoff: block offset 2355eb563f5SRyusuke Konishi * @create: create flag 2365eb563f5SRyusuke Konishi * @init_block: initializer used for newly allocated block 2375eb563f5SRyusuke Konishi * @out_bh: output of a pointer to the buffer_head 2385eb563f5SRyusuke Konishi * 2395eb563f5SRyusuke Konishi * nilfs_mdt_get_block() looks up the specified buffer and tries to create 2405eb563f5SRyusuke Konishi * a new buffer if @create is not zero. On success, the returned buffer is 2415eb563f5SRyusuke Konishi * assured to be either existing or formatted using a buffer lock on success. 2425eb563f5SRyusuke Konishi * @out_bh is substituted only when zero is returned. 2435eb563f5SRyusuke Konishi * 2445eb563f5SRyusuke Konishi * Return Value: On success, it returns 0. On error, the following negative 2455eb563f5SRyusuke Konishi * error code is returned. 2465eb563f5SRyusuke Konishi * 2475eb563f5SRyusuke Konishi * %-ENOMEM - Insufficient memory available. 2485eb563f5SRyusuke Konishi * 2495eb563f5SRyusuke Konishi * %-EIO - I/O error 2505eb563f5SRyusuke Konishi * 2515eb563f5SRyusuke Konishi * %-ENOENT - the specified block does not exist (hole block) 2525eb563f5SRyusuke Konishi * 2535eb563f5SRyusuke Konishi * %-EINVAL - bmap is broken. (the caller should call nilfs_error()) 2545eb563f5SRyusuke Konishi * 2555eb563f5SRyusuke Konishi * %-EROFS - Read only filesystem (for create mode) 2565eb563f5SRyusuke Konishi */ 2575eb563f5SRyusuke Konishi int nilfs_mdt_get_block(struct inode *inode, unsigned long blkoff, int create, 2585eb563f5SRyusuke Konishi void (*init_block)(struct inode *, 2595eb563f5SRyusuke Konishi struct buffer_head *, void *), 2605eb563f5SRyusuke Konishi struct buffer_head **out_bh) 2615eb563f5SRyusuke Konishi { 2625eb563f5SRyusuke Konishi int ret; 2635eb563f5SRyusuke Konishi 2645eb563f5SRyusuke Konishi /* Should be rewritten with merging nilfs_mdt_read_block() */ 2655eb563f5SRyusuke Konishi retry: 2665eb563f5SRyusuke Konishi ret = nilfs_mdt_read_block(inode, blkoff, out_bh); 2675eb563f5SRyusuke Konishi if (!create || ret != -ENOENT) 2685eb563f5SRyusuke Konishi return ret; 2695eb563f5SRyusuke Konishi 2705eb563f5SRyusuke Konishi ret = nilfs_mdt_create_block(inode, blkoff, out_bh, init_block); 2715eb563f5SRyusuke Konishi if (unlikely(ret == -EEXIST)) { 2725eb563f5SRyusuke Konishi /* create = 0; */ /* limit read-create loop retries */ 2735eb563f5SRyusuke Konishi goto retry; 2745eb563f5SRyusuke Konishi } 2755eb563f5SRyusuke Konishi return ret; 2765eb563f5SRyusuke Konishi } 2775eb563f5SRyusuke Konishi 2785eb563f5SRyusuke Konishi /** 2795eb563f5SRyusuke Konishi * nilfs_mdt_delete_block - make a hole on the meta data file. 2805eb563f5SRyusuke Konishi * @inode: inode of the meta data file 2815eb563f5SRyusuke Konishi * @block: block offset 2825eb563f5SRyusuke Konishi * 2835eb563f5SRyusuke Konishi * Return Value: On success, zero is returned. 2845eb563f5SRyusuke Konishi * On error, one of the following negative error code is returned. 2855eb563f5SRyusuke Konishi * 2865eb563f5SRyusuke Konishi * %-ENOMEM - Insufficient memory available. 2875eb563f5SRyusuke Konishi * 2885eb563f5SRyusuke Konishi * %-EIO - I/O error 2895eb563f5SRyusuke Konishi * 2905eb563f5SRyusuke Konishi * %-EINVAL - bmap is broken. (the caller should call nilfs_error()) 2915eb563f5SRyusuke Konishi */ 2925eb563f5SRyusuke Konishi int nilfs_mdt_delete_block(struct inode *inode, unsigned long block) 2935eb563f5SRyusuke Konishi { 2945eb563f5SRyusuke Konishi struct nilfs_inode_info *ii = NILFS_I(inode); 2955eb563f5SRyusuke Konishi int err; 2965eb563f5SRyusuke Konishi 2975eb563f5SRyusuke Konishi err = nilfs_bmap_delete(ii->i_bmap, block); 29884338237SRyusuke Konishi if (!err || err == -ENOENT) { 2995eb563f5SRyusuke Konishi nilfs_mdt_mark_dirty(inode); 3005eb563f5SRyusuke Konishi nilfs_mdt_forget_block(inode, block); 3015eb563f5SRyusuke Konishi } 3025eb563f5SRyusuke Konishi return err; 3035eb563f5SRyusuke Konishi } 3045eb563f5SRyusuke Konishi 3055eb563f5SRyusuke Konishi /** 3065eb563f5SRyusuke Konishi * nilfs_mdt_forget_block - discard dirty state and try to remove the page 3075eb563f5SRyusuke Konishi * @inode: inode of the meta data file 3085eb563f5SRyusuke Konishi * @block: block offset 3095eb563f5SRyusuke Konishi * 3105eb563f5SRyusuke Konishi * nilfs_mdt_forget_block() clears a dirty flag of the specified buffer, and 3115eb563f5SRyusuke Konishi * tries to release the page including the buffer from a page cache. 3125eb563f5SRyusuke Konishi * 3135eb563f5SRyusuke Konishi * Return Value: On success, 0 is returned. On error, one of the following 3145eb563f5SRyusuke Konishi * negative error code is returned. 3155eb563f5SRyusuke Konishi * 3165eb563f5SRyusuke Konishi * %-EBUSY - page has an active buffer. 3175eb563f5SRyusuke Konishi * 3185eb563f5SRyusuke Konishi * %-ENOENT - page cache has no page addressed by the offset. 3195eb563f5SRyusuke Konishi */ 3205eb563f5SRyusuke Konishi int nilfs_mdt_forget_block(struct inode *inode, unsigned long block) 3215eb563f5SRyusuke Konishi { 3225eb563f5SRyusuke Konishi pgoff_t index = (pgoff_t)block >> 3235eb563f5SRyusuke Konishi (PAGE_CACHE_SHIFT - inode->i_blkbits); 3245eb563f5SRyusuke Konishi struct page *page; 3255eb563f5SRyusuke Konishi unsigned long first_block; 3265eb563f5SRyusuke Konishi int ret = 0; 3275eb563f5SRyusuke Konishi int still_dirty; 3285eb563f5SRyusuke Konishi 3295eb563f5SRyusuke Konishi page = find_lock_page(inode->i_mapping, index); 3305eb563f5SRyusuke Konishi if (!page) 3315eb563f5SRyusuke Konishi return -ENOENT; 3325eb563f5SRyusuke Konishi 3335eb563f5SRyusuke Konishi wait_on_page_writeback(page); 3345eb563f5SRyusuke Konishi 3355eb563f5SRyusuke Konishi first_block = (unsigned long)index << 3365eb563f5SRyusuke Konishi (PAGE_CACHE_SHIFT - inode->i_blkbits); 3375eb563f5SRyusuke Konishi if (page_has_buffers(page)) { 3385eb563f5SRyusuke Konishi struct buffer_head *bh; 3395eb563f5SRyusuke Konishi 3405eb563f5SRyusuke Konishi bh = nilfs_page_get_nth_block(page, block - first_block); 3415eb563f5SRyusuke Konishi nilfs_forget_buffer(bh); 3425eb563f5SRyusuke Konishi } 3435eb563f5SRyusuke Konishi still_dirty = PageDirty(page); 3445eb563f5SRyusuke Konishi unlock_page(page); 3455eb563f5SRyusuke Konishi page_cache_release(page); 3465eb563f5SRyusuke Konishi 3475eb563f5SRyusuke Konishi if (still_dirty || 3485eb563f5SRyusuke Konishi invalidate_inode_pages2_range(inode->i_mapping, index, index) != 0) 3495eb563f5SRyusuke Konishi ret = -EBUSY; 3505eb563f5SRyusuke Konishi return ret; 3515eb563f5SRyusuke Konishi } 3525eb563f5SRyusuke Konishi 3535eb563f5SRyusuke Konishi /** 3545eb563f5SRyusuke Konishi * nilfs_mdt_mark_block_dirty - mark a block on the meta data file dirty. 3555eb563f5SRyusuke Konishi * @inode: inode of the meta data file 3565eb563f5SRyusuke Konishi * @block: block offset 3575eb563f5SRyusuke Konishi * 3585eb563f5SRyusuke Konishi * Return Value: On success, it returns 0. On error, the following negative 3595eb563f5SRyusuke Konishi * error code is returned. 3605eb563f5SRyusuke Konishi * 3615eb563f5SRyusuke Konishi * %-ENOMEM - Insufficient memory available. 3625eb563f5SRyusuke Konishi * 3635eb563f5SRyusuke Konishi * %-EIO - I/O error 3645eb563f5SRyusuke Konishi * 3655eb563f5SRyusuke Konishi * %-ENOENT - the specified block does not exist (hole block) 3665eb563f5SRyusuke Konishi * 3675eb563f5SRyusuke Konishi * %-EINVAL - bmap is broken. (the caller should call nilfs_error()) 3685eb563f5SRyusuke Konishi */ 3695eb563f5SRyusuke Konishi int nilfs_mdt_mark_block_dirty(struct inode *inode, unsigned long block) 3705eb563f5SRyusuke Konishi { 3715eb563f5SRyusuke Konishi struct buffer_head *bh; 3725eb563f5SRyusuke Konishi int err; 3735eb563f5SRyusuke Konishi 3745eb563f5SRyusuke Konishi err = nilfs_mdt_read_block(inode, block, &bh); 3755eb563f5SRyusuke Konishi if (unlikely(err)) 3765eb563f5SRyusuke Konishi return err; 3775eb563f5SRyusuke Konishi nilfs_mark_buffer_dirty(bh); 3785eb563f5SRyusuke Konishi nilfs_mdt_mark_dirty(inode); 3795eb563f5SRyusuke Konishi brelse(bh); 3805eb563f5SRyusuke Konishi return 0; 3815eb563f5SRyusuke Konishi } 3825eb563f5SRyusuke Konishi 3835eb563f5SRyusuke Konishi int nilfs_mdt_fetch_dirty(struct inode *inode) 3845eb563f5SRyusuke Konishi { 3855eb563f5SRyusuke Konishi struct nilfs_inode_info *ii = NILFS_I(inode); 3865eb563f5SRyusuke Konishi 3875eb563f5SRyusuke Konishi if (nilfs_bmap_test_and_clear_dirty(ii->i_bmap)) { 3885eb563f5SRyusuke Konishi set_bit(NILFS_I_DIRTY, &ii->i_state); 3895eb563f5SRyusuke Konishi return 1; 3905eb563f5SRyusuke Konishi } 3915eb563f5SRyusuke Konishi return test_bit(NILFS_I_DIRTY, &ii->i_state); 3925eb563f5SRyusuke Konishi } 3935eb563f5SRyusuke Konishi 3945eb563f5SRyusuke Konishi static int 3955eb563f5SRyusuke Konishi nilfs_mdt_write_page(struct page *page, struct writeback_control *wbc) 3965eb563f5SRyusuke Konishi { 3975eb563f5SRyusuke Konishi struct inode *inode = container_of(page->mapping, 3985eb563f5SRyusuke Konishi struct inode, i_data); 3995eb563f5SRyusuke Konishi struct super_block *sb = inode->i_sb; 400027d6404SRyusuke Konishi struct the_nilfs *nilfs = NILFS_MDT(inode)->mi_nilfs; 4015eb563f5SRyusuke Konishi struct nilfs_sb_info *writer = NULL; 4025eb563f5SRyusuke Konishi int err = 0; 4035eb563f5SRyusuke Konishi 4045eb563f5SRyusuke Konishi redirty_page_for_writepage(wbc, page); 4055eb563f5SRyusuke Konishi unlock_page(page); 4065eb563f5SRyusuke Konishi 4075eb563f5SRyusuke Konishi if (page->mapping->assoc_mapping) 4085eb563f5SRyusuke Konishi return 0; /* Do not request flush for shadow page cache */ 4095eb563f5SRyusuke Konishi if (!sb) { 410027d6404SRyusuke Konishi down_read(&nilfs->ns_writer_sem); 411027d6404SRyusuke Konishi writer = nilfs->ns_writer; 41201a261e0SRyusuke Konishi if (!writer) { 413027d6404SRyusuke Konishi up_read(&nilfs->ns_writer_sem); 4145eb563f5SRyusuke Konishi return -EROFS; 41501a261e0SRyusuke Konishi } 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) 425027d6404SRyusuke Konishi up_read(&nilfs->ns_writer_sem); 4265eb563f5SRyusuke Konishi return err; 4275eb563f5SRyusuke Konishi } 4285eb563f5SRyusuke Konishi 4295eb563f5SRyusuke Konishi 4307f09410bSAlexey Dobriyan static const struct address_space_operations def_mdt_aops = { 4315eb563f5SRyusuke Konishi .writepage = nilfs_mdt_write_page, 432fa032744SRyusuke Konishi .sync_page = block_sync_page, 4335eb563f5SRyusuke Konishi }; 4345eb563f5SRyusuke Konishi 4356e1d5dccSAlexey Dobriyan static const struct inode_operations def_mdt_iops; 4365eb563f5SRyusuke Konishi static struct file_operations def_mdt_fops; 4375eb563f5SRyusuke Konishi 4385eb563f5SRyusuke Konishi /* 4395eb563f5SRyusuke Konishi * NILFS2 uses pseudo inodes for meta data files such as DAT, cpfile, sufile, 4405eb563f5SRyusuke Konishi * ifile, or gcinodes. This allows the B-tree code and segment constructor 4415eb563f5SRyusuke Konishi * to treat them like regular files, and this helps to simplify the 4425eb563f5SRyusuke Konishi * implementation. 4435eb563f5SRyusuke Konishi * On the other hand, some of the pseudo inodes have an irregular point: 4445eb563f5SRyusuke Konishi * They don't have valid inode->i_sb pointer because their lifetimes are 4455eb563f5SRyusuke Konishi * longer than those of the super block structs; they may continue for 4465eb563f5SRyusuke Konishi * several consecutive mounts/umounts. This would need discussions. 4475eb563f5SRyusuke Konishi */ 4485eb563f5SRyusuke Konishi struct inode * 4495eb563f5SRyusuke Konishi nilfs_mdt_new_common(struct the_nilfs *nilfs, struct super_block *sb, 4505eb563f5SRyusuke Konishi ino_t ino, gfp_t gfp_mask) 4515eb563f5SRyusuke Konishi { 452a53b4751SRyusuke Konishi struct inode *inode = nilfs_alloc_inode_common(nilfs); 4535eb563f5SRyusuke Konishi 4545eb563f5SRyusuke Konishi if (!inode) 4555eb563f5SRyusuke Konishi return NULL; 4565eb563f5SRyusuke Konishi else { 4575eb563f5SRyusuke Konishi struct address_space * const mapping = &inode->i_data; 4585eb563f5SRyusuke Konishi struct nilfs_mdt_info *mi = kzalloc(sizeof(*mi), GFP_NOFS); 4595eb563f5SRyusuke Konishi 4605eb563f5SRyusuke Konishi if (!mi) { 4615eb563f5SRyusuke Konishi nilfs_destroy_inode(inode); 4625eb563f5SRyusuke Konishi return NULL; 4635eb563f5SRyusuke Konishi } 4645eb563f5SRyusuke Konishi mi->mi_nilfs = nilfs; 4655eb563f5SRyusuke Konishi init_rwsem(&mi->mi_sem); 4665eb563f5SRyusuke Konishi 4675eb563f5SRyusuke Konishi inode->i_sb = sb; /* sb may be NULL for some meta data files */ 4685eb563f5SRyusuke Konishi inode->i_blkbits = nilfs->ns_blocksize_bits; 4695eb563f5SRyusuke Konishi inode->i_flags = 0; 4705eb563f5SRyusuke Konishi atomic_set(&inode->i_count, 1); 4715eb563f5SRyusuke Konishi inode->i_nlink = 1; 4725eb563f5SRyusuke Konishi inode->i_ino = ino; 4735eb563f5SRyusuke Konishi inode->i_mode = S_IFREG; 4745eb563f5SRyusuke Konishi inode->i_private = mi; 4755eb563f5SRyusuke Konishi 4765eb563f5SRyusuke Konishi #ifdef INIT_UNUSED_INODE_FIELDS 4775eb563f5SRyusuke Konishi atomic_set(&inode->i_writecount, 0); 4785eb563f5SRyusuke Konishi inode->i_size = 0; 4795eb563f5SRyusuke Konishi inode->i_blocks = 0; 4805eb563f5SRyusuke Konishi inode->i_bytes = 0; 4815eb563f5SRyusuke Konishi inode->i_generation = 0; 4825eb563f5SRyusuke Konishi #ifdef CONFIG_QUOTA 4835eb563f5SRyusuke Konishi memset(&inode->i_dquot, 0, sizeof(inode->i_dquot)); 4845eb563f5SRyusuke Konishi #endif 4855eb563f5SRyusuke Konishi inode->i_pipe = NULL; 4865eb563f5SRyusuke Konishi inode->i_bdev = NULL; 4875eb563f5SRyusuke Konishi inode->i_cdev = NULL; 4885eb563f5SRyusuke Konishi inode->i_rdev = 0; 4895eb563f5SRyusuke Konishi #ifdef CONFIG_SECURITY 4905eb563f5SRyusuke Konishi inode->i_security = NULL; 4915eb563f5SRyusuke Konishi #endif 4925eb563f5SRyusuke Konishi inode->dirtied_when = 0; 4935eb563f5SRyusuke Konishi 4945eb563f5SRyusuke Konishi INIT_LIST_HEAD(&inode->i_list); 4955eb563f5SRyusuke Konishi INIT_LIST_HEAD(&inode->i_sb_list); 4965eb563f5SRyusuke Konishi inode->i_state = 0; 4975eb563f5SRyusuke Konishi #endif 4985eb563f5SRyusuke Konishi 4995eb563f5SRyusuke Konishi spin_lock_init(&inode->i_lock); 5005eb563f5SRyusuke Konishi mutex_init(&inode->i_mutex); 5015eb563f5SRyusuke Konishi init_rwsem(&inode->i_alloc_sem); 5025eb563f5SRyusuke Konishi 5035eb563f5SRyusuke Konishi mapping->host = NULL; /* instead of inode */ 5045eb563f5SRyusuke Konishi mapping->flags = 0; 5055eb563f5SRyusuke Konishi mapping_set_gfp_mask(mapping, gfp_mask); 5065eb563f5SRyusuke Konishi mapping->assoc_mapping = NULL; 5075eb563f5SRyusuke Konishi mapping->backing_dev_info = nilfs->ns_bdi; 5085eb563f5SRyusuke Konishi 5095eb563f5SRyusuke Konishi inode->i_mapping = mapping; 5105eb563f5SRyusuke Konishi } 5115eb563f5SRyusuke Konishi 5125eb563f5SRyusuke Konishi return inode; 5135eb563f5SRyusuke Konishi } 5145eb563f5SRyusuke Konishi 5155eb563f5SRyusuke Konishi struct inode *nilfs_mdt_new(struct the_nilfs *nilfs, struct super_block *sb, 5167a102b09SRyusuke Konishi ino_t ino) 5175eb563f5SRyusuke Konishi { 5187a102b09SRyusuke Konishi struct inode *inode = nilfs_mdt_new_common(nilfs, sb, ino, 5197a102b09SRyusuke Konishi NILFS_MDT_GFP); 5205eb563f5SRyusuke Konishi 5215eb563f5SRyusuke Konishi if (!inode) 5225eb563f5SRyusuke Konishi return NULL; 5235eb563f5SRyusuke Konishi 5245eb563f5SRyusuke Konishi inode->i_op = &def_mdt_iops; 5255eb563f5SRyusuke Konishi inode->i_fop = &def_mdt_fops; 5265eb563f5SRyusuke Konishi inode->i_mapping->a_ops = &def_mdt_aops; 5275eb563f5SRyusuke Konishi return inode; 5285eb563f5SRyusuke Konishi } 5295eb563f5SRyusuke Konishi 5305eb563f5SRyusuke Konishi void nilfs_mdt_set_entry_size(struct inode *inode, unsigned entry_size, 5315eb563f5SRyusuke Konishi unsigned header_size) 5325eb563f5SRyusuke Konishi { 5335eb563f5SRyusuke Konishi struct nilfs_mdt_info *mi = NILFS_MDT(inode); 5345eb563f5SRyusuke Konishi 5355eb563f5SRyusuke Konishi mi->mi_entry_size = entry_size; 5365eb563f5SRyusuke Konishi mi->mi_entries_per_block = (1 << inode->i_blkbits) / entry_size; 5375eb563f5SRyusuke Konishi mi->mi_first_entry_offset = DIV_ROUND_UP(header_size, entry_size); 5385eb563f5SRyusuke Konishi } 5395eb563f5SRyusuke Konishi 5405eb563f5SRyusuke Konishi void nilfs_mdt_set_shadow(struct inode *orig, struct inode *shadow) 5415eb563f5SRyusuke Konishi { 5425eb563f5SRyusuke Konishi shadow->i_mapping->assoc_mapping = orig->i_mapping; 5435eb563f5SRyusuke Konishi NILFS_I(shadow)->i_btnode_cache.assoc_mapping = 5445eb563f5SRyusuke Konishi &NILFS_I(orig)->i_btnode_cache; 5455eb563f5SRyusuke Konishi } 5465eb563f5SRyusuke Konishi 5475eb563f5SRyusuke Konishi void nilfs_mdt_clear(struct inode *inode) 5485eb563f5SRyusuke Konishi { 5495eb563f5SRyusuke Konishi struct nilfs_inode_info *ii = NILFS_I(inode); 5505eb563f5SRyusuke Konishi 5515eb563f5SRyusuke Konishi invalidate_mapping_pages(inode->i_mapping, 0, -1); 5525eb563f5SRyusuke Konishi truncate_inode_pages(inode->i_mapping, 0); 5535eb563f5SRyusuke Konishi 5545eb563f5SRyusuke Konishi nilfs_bmap_clear(ii->i_bmap); 5555eb563f5SRyusuke Konishi nilfs_btnode_cache_clear(&ii->i_btnode_cache); 5565eb563f5SRyusuke Konishi } 5575eb563f5SRyusuke Konishi 5585eb563f5SRyusuke Konishi void nilfs_mdt_destroy(struct inode *inode) 5595eb563f5SRyusuke Konishi { 5605eb563f5SRyusuke Konishi struct nilfs_mdt_info *mdi = NILFS_MDT(inode); 5615eb563f5SRyusuke Konishi 5625eb563f5SRyusuke Konishi kfree(mdi->mi_bgl); /* kfree(NULL) is safe */ 5635eb563f5SRyusuke Konishi kfree(mdi); 5645eb563f5SRyusuke Konishi nilfs_destroy_inode(inode); 5655eb563f5SRyusuke Konishi } 566