xref: /openbmc/linux/fs/nilfs2/mdt.c (revision 6e1d5dcc)
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