Blame view

fs/nilfs2/segment.c 71 KB
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
  /*
   * segment.c - NILFS segment constructor.
   *
   * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
   *
   * Written by Ryusuke Konishi <ryusuke@osrg.net>
   *
   */
  
  #include <linux/pagemap.h>
  #include <linux/buffer_head.h>
  #include <linux/writeback.h>
  #include <linux/bio.h>
  #include <linux/completion.h>
  #include <linux/blkdev.h>
  #include <linux/backing-dev.h>
  #include <linux/freezer.h>
  #include <linux/kthread.h>
  #include <linux/crc32.h>
  #include <linux/pagevec.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
35
  #include <linux/slab.h>
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
36
37
38
39
40
41
42
  #include "nilfs.h"
  #include "btnode.h"
  #include "page.h"
  #include "segment.h"
  #include "sufile.h"
  #include "cpfile.h"
  #include "ifile.h"
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
  #include "segbuf.h"
  
  
  /*
   * Segment constructor
   */
  #define SC_N_INODEVEC	16   /* Size of locally allocated inode vector */
  
  #define SC_MAX_SEGDELTA 64   /* Upper limit of the number of segments
  				appended in collection retry loop */
  
  /* Construction mode */
  enum {
  	SC_LSEG_SR = 1,	/* Make a logical segment having a super root */
  	SC_LSEG_DSYNC,	/* Flush data blocks of a given file and make
  			   a logical segment without a super root */
  	SC_FLUSH_FILE,	/* Flush data files, leads to segment writes without
  			   creating a checkpoint */
  	SC_FLUSH_DAT,	/* Flush DAT file. This also creates segments without
  			   a checkpoint */
  };
  
  /* Stage numbers of dirty block collection */
  enum {
  	NILFS_ST_INIT = 0,
  	NILFS_ST_GC,		/* Collecting dirty blocks for GC */
  	NILFS_ST_FILE,
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
70
71
72
73
74
75
76
77
78
79
80
81
  	NILFS_ST_IFILE,
  	NILFS_ST_CPFILE,
  	NILFS_ST_SUFILE,
  	NILFS_ST_DAT,
  	NILFS_ST_SR,		/* Super root */
  	NILFS_ST_DSYNC,		/* Data sync blocks */
  	NILFS_ST_DONE,
  };
  
  /* State flags of collection */
  #define NILFS_CF_NODE		0x0001	/* Collecting node blocks */
  #define NILFS_CF_IFILE_STARTED	0x0002	/* IFILE stage has started */
071cb4b81   Ryusuke Konishi   nilfs2: eliminate...
82
83
  #define NILFS_CF_SUFREED	0x0004	/* segment usages has been freed */
  #define NILFS_CF_HISTORY_MASK	(NILFS_CF_IFILE_STARTED | NILFS_CF_SUFREED)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
  
  /* Operations depending on the construction mode and file type */
  struct nilfs_sc_operations {
  	int (*collect_data)(struct nilfs_sc_info *, struct buffer_head *,
  			    struct inode *);
  	int (*collect_node)(struct nilfs_sc_info *, struct buffer_head *,
  			    struct inode *);
  	int (*collect_bmap)(struct nilfs_sc_info *, struct buffer_head *,
  			    struct inode *);
  	void (*write_data_binfo)(struct nilfs_sc_info *,
  				 struct nilfs_segsum_pointer *,
  				 union nilfs_binfo *);
  	void (*write_node_binfo)(struct nilfs_sc_info *,
  				 struct nilfs_segsum_pointer *,
  				 union nilfs_binfo *);
  };
  
  /*
   * Other definitions
   */
  static void nilfs_segctor_start_timer(struct nilfs_sc_info *);
  static void nilfs_segctor_do_flush(struct nilfs_sc_info *, int);
  static void nilfs_segctor_do_immediate_flush(struct nilfs_sc_info *);
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
107
  static void nilfs_dispose_list(struct the_nilfs *, struct list_head *, int);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
108
109
110
111
112
113
114
115
116
  
  #define nilfs_cnt32_gt(a, b)   \
  	(typecheck(__u32, a) && typecheck(__u32, b) && \
  	 ((__s32)(b) - (__s32)(a) < 0))
  #define nilfs_cnt32_ge(a, b)   \
  	(typecheck(__u32, a) && typecheck(__u32, b) && \
  	 ((__s32)(a) - (__s32)(b) >= 0))
  #define nilfs_cnt32_lt(a, b)  nilfs_cnt32_gt(b, a)
  #define nilfs_cnt32_le(a, b)  nilfs_cnt32_ge(b, a)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
117
118
119
120
121
122
123
124
125
126
127
  static int nilfs_prepare_segment_lock(struct nilfs_transaction_info *ti)
  {
  	struct nilfs_transaction_info *cur_ti = current->journal_info;
  	void *save = NULL;
  
  	if (cur_ti) {
  		if (cur_ti->ti_magic == NILFS_TI_MAGIC)
  			return ++cur_ti->ti_count;
  		else {
  			/*
  			 * If journal_info field is occupied by other FS,
47420c799   Ryusuke Konishi   nilfs2: avoid dou...
128
129
  			 * it is saved and will be restored on
  			 * nilfs_transaction_commit().
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
  			 */
  			printk(KERN_WARNING
  			       "NILFS warning: journal info from a different "
  			       "FS
  ");
  			save = current->journal_info;
  		}
  	}
  	if (!ti) {
  		ti = kmem_cache_alloc(nilfs_transaction_cachep, GFP_NOFS);
  		if (!ti)
  			return -ENOMEM;
  		ti->ti_flags = NILFS_TI_DYNAMIC_ALLOC;
  	} else {
  		ti->ti_flags = 0;
  	}
  	ti->ti_count = 0;
  	ti->ti_save = save;
  	ti->ti_magic = NILFS_TI_MAGIC;
  	current->journal_info = ti;
  	return 0;
  }
  
  /**
   * nilfs_transaction_begin - start indivisible file operations.
   * @sb: super block
   * @ti: nilfs_transaction_info
   * @vacancy_check: flags for vacancy rate checks
   *
   * nilfs_transaction_begin() acquires a reader/writer semaphore, called
   * the segment semaphore, to make a segment construction and write tasks
47420c799   Ryusuke Konishi   nilfs2: avoid dou...
161
   * exclusive.  The function is used with nilfs_transaction_commit() in pairs.
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
162
163
164
165
166
167
   * The region enclosed by these two functions can be nested.  To avoid a
   * deadlock, the semaphore is only acquired or released in the outermost call.
   *
   * This function allocates a nilfs_transaction_info struct to keep context
   * information on it.  It is initialized and hooked onto the current task in
   * the outermost call.  If a pre-allocated struct is given to @ti, it is used
7a65004bb   Ryusuke Konishi   nilfs2: fix vario...
168
   * instead; otherwise a new struct is assigned from a slab.
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
169
170
171
172
173
174
175
176
177
   *
   * When @vacancy_check flag is set, this function will check the amount of
   * free space, and will wait for the GC to reclaim disk space if low capacity.
   *
   * Return Value: On success, 0 is returned. On error, one of the following
   * negative error code is returned.
   *
   * %-ENOMEM - Insufficient memory available.
   *
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
178
179
180
181
182
183
   * %-ENOSPC - No space left on device
   */
  int nilfs_transaction_begin(struct super_block *sb,
  			    struct nilfs_transaction_info *ti,
  			    int vacancy_check)
  {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
184
185
186
187
188
189
190
  	struct the_nilfs *nilfs;
  	int ret = nilfs_prepare_segment_lock(ti);
  
  	if (unlikely(ret < 0))
  		return ret;
  	if (ret > 0)
  		return 0;
5beb6e0b2   Ryusuke Konishi   nilfs2: add bdev ...
191
  	vfs_check_frozen(sb, SB_FREEZE_WRITE);
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
192
  	nilfs = sb->s_fs_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
  	down_read(&nilfs->ns_segctor_sem);
  	if (vacancy_check && nilfs_near_disk_full(nilfs)) {
  		up_read(&nilfs->ns_segctor_sem);
  		ret = -ENOSPC;
  		goto failed;
  	}
  	return 0;
  
   failed:
  	ti = current->journal_info;
  	current->journal_info = ti->ti_save;
  	if (ti->ti_flags & NILFS_TI_DYNAMIC_ALLOC)
  		kmem_cache_free(nilfs_transaction_cachep, ti);
  	return ret;
  }
  
  /**
47420c799   Ryusuke Konishi   nilfs2: avoid dou...
210
   * nilfs_transaction_commit - commit indivisible file operations.
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
211
   * @sb: super block
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
212
   *
47420c799   Ryusuke Konishi   nilfs2: avoid dou...
213
214
215
216
217
218
   * nilfs_transaction_commit() releases the read semaphore which is
   * acquired by nilfs_transaction_begin(). This is only performed
   * in outermost call of this function.  If a commit flag is set,
   * nilfs_transaction_commit() sets a timer to start the segment
   * constructor.  If a sync flag is set, it starts construction
   * directly.
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
219
   */
47420c799   Ryusuke Konishi   nilfs2: avoid dou...
220
  int nilfs_transaction_commit(struct super_block *sb)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
221
222
  {
  	struct nilfs_transaction_info *ti = current->journal_info;
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
223
  	struct the_nilfs *nilfs = sb->s_fs_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
224
225
226
  	int err = 0;
  
  	BUG_ON(ti == NULL || ti->ti_magic != NILFS_TI_MAGIC);
47420c799   Ryusuke Konishi   nilfs2: avoid dou...
227
  	ti->ti_flags |= NILFS_TI_COMMIT;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
228
229
230
231
  	if (ti->ti_count > 0) {
  		ti->ti_count--;
  		return 0;
  	}
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
232
233
  	if (nilfs->ns_writer) {
  		struct nilfs_sc_info *sci = nilfs->ns_writer;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
234
235
  		if (ti->ti_flags & NILFS_TI_COMMIT)
  			nilfs_segctor_start_timer(sci);
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
236
  		if (atomic_read(&nilfs->ns_ndirtyblks) > sci->sc_watermark)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
237
238
  			nilfs_segctor_do_flush(sci, 0);
  	}
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
239
  	up_read(&nilfs->ns_segctor_sem);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
240
241
242
243
244
245
246
247
  	current->journal_info = ti->ti_save;
  
  	if (ti->ti_flags & NILFS_TI_SYNC)
  		err = nilfs_construct_segment(sb);
  	if (ti->ti_flags & NILFS_TI_DYNAMIC_ALLOC)
  		kmem_cache_free(nilfs_transaction_cachep, ti);
  	return err;
  }
47420c799   Ryusuke Konishi   nilfs2: avoid dou...
248
249
250
  void nilfs_transaction_abort(struct super_block *sb)
  {
  	struct nilfs_transaction_info *ti = current->journal_info;
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
251
  	struct the_nilfs *nilfs = sb->s_fs_info;
47420c799   Ryusuke Konishi   nilfs2: avoid dou...
252
253
254
255
256
257
  
  	BUG_ON(ti == NULL || ti->ti_magic != NILFS_TI_MAGIC);
  	if (ti->ti_count > 0) {
  		ti->ti_count--;
  		return;
  	}
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
258
  	up_read(&nilfs->ns_segctor_sem);
47420c799   Ryusuke Konishi   nilfs2: avoid dou...
259
260
261
262
263
  
  	current->journal_info = ti->ti_save;
  	if (ti->ti_flags & NILFS_TI_DYNAMIC_ALLOC)
  		kmem_cache_free(nilfs_transaction_cachep, ti);
  }
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
264
265
  void nilfs_relax_pressure_in_lock(struct super_block *sb)
  {
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
266
  	struct the_nilfs *nilfs = sb->s_fs_info;
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
267
  	struct nilfs_sc_info *sci = nilfs->ns_writer;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
  
  	if (!sci || !sci->sc_flush_request)
  		return;
  
  	set_bit(NILFS_SC_PRIOR_FLUSH, &sci->sc_flags);
  	up_read(&nilfs->ns_segctor_sem);
  
  	down_write(&nilfs->ns_segctor_sem);
  	if (sci->sc_flush_request &&
  	    test_bit(NILFS_SC_PRIOR_FLUSH, &sci->sc_flags)) {
  		struct nilfs_transaction_info *ti = current->journal_info;
  
  		ti->ti_flags |= NILFS_TI_WRITER;
  		nilfs_segctor_do_immediate_flush(sci);
  		ti->ti_flags &= ~NILFS_TI_WRITER;
  	}
  	downgrade_write(&nilfs->ns_segctor_sem);
  }
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
286
  static void nilfs_transaction_lock(struct super_block *sb,
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
287
288
289
290
  				   struct nilfs_transaction_info *ti,
  				   int gcflag)
  {
  	struct nilfs_transaction_info *cur_ti = current->journal_info;
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
291
  	struct the_nilfs *nilfs = sb->s_fs_info;
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
292
  	struct nilfs_sc_info *sci = nilfs->ns_writer;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
293

1f5abe7e7   Ryusuke Konishi   nilfs2: replace B...
294
  	WARN_ON(cur_ti);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
295
296
297
298
299
300
301
302
  	ti->ti_flags = NILFS_TI_WRITER;
  	ti->ti_count = 0;
  	ti->ti_save = cur_ti;
  	ti->ti_magic = NILFS_TI_MAGIC;
  	INIT_LIST_HEAD(&ti->ti_garbage);
  	current->journal_info = ti;
  
  	for (;;) {
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
303
304
  		down_write(&nilfs->ns_segctor_sem);
  		if (!test_bit(NILFS_SC_PRIOR_FLUSH, &sci->sc_flags))
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
305
  			break;
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
306
  		nilfs_segctor_do_immediate_flush(sci);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
307

f7545144c   Ryusuke Konishi   nilfs2: use sb in...
308
  		up_write(&nilfs->ns_segctor_sem);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
309
310
311
312
313
  		yield();
  	}
  	if (gcflag)
  		ti->ti_flags |= NILFS_TI_GC;
  }
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
314
  static void nilfs_transaction_unlock(struct super_block *sb)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
315
316
  {
  	struct nilfs_transaction_info *ti = current->journal_info;
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
317
  	struct the_nilfs *nilfs = sb->s_fs_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
318
319
320
  
  	BUG_ON(ti == NULL || ti->ti_magic != NILFS_TI_MAGIC);
  	BUG_ON(ti->ti_count > 0);
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
321
  	up_write(&nilfs->ns_segctor_sem);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
322
323
  	current->journal_info = ti->ti_save;
  	if (!list_empty(&ti->ti_garbage))
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
324
  		nilfs_dispose_list(nilfs, &ti->ti_garbage, 0);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
  }
  
  static void *nilfs_segctor_map_segsum_entry(struct nilfs_sc_info *sci,
  					    struct nilfs_segsum_pointer *ssp,
  					    unsigned bytes)
  {
  	struct nilfs_segment_buffer *segbuf = sci->sc_curseg;
  	unsigned blocksize = sci->sc_super->s_blocksize;
  	void *p;
  
  	if (unlikely(ssp->offset + bytes > blocksize)) {
  		ssp->offset = 0;
  		BUG_ON(NILFS_SEGBUF_BH_IS_LAST(ssp->bh,
  					       &segbuf->sb_segsum_buffers));
  		ssp->bh = NILFS_SEGBUF_NEXT_BH(ssp->bh);
  	}
  	p = ssp->bh->b_data + ssp->offset;
  	ssp->offset += bytes;
  	return p;
  }
  
  /**
   * nilfs_segctor_reset_segment_buffer - reset the current segment buffer
   * @sci: nilfs_sc_info
   */
  static int nilfs_segctor_reset_segment_buffer(struct nilfs_sc_info *sci)
  {
  	struct nilfs_segment_buffer *segbuf = sci->sc_curseg;
  	struct buffer_head *sumbh;
  	unsigned sumbytes;
  	unsigned flags = 0;
  	int err;
  
  	if (nilfs_doing_gc())
  		flags = NILFS_SS_GC;
6c43f4100   Ryusuke Konishi   nilfs2: keep zero...
360
  	err = nilfs_segbuf_reset(segbuf, flags, sci->sc_seg_ctime, sci->sc_cno);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
  	if (unlikely(err))
  		return err;
  
  	sumbh = NILFS_SEGBUF_FIRST_BH(&segbuf->sb_segsum_buffers);
  	sumbytes = segbuf->sb_sum.sumbytes;
  	sci->sc_finfo_ptr.bh = sumbh;  sci->sc_finfo_ptr.offset = sumbytes;
  	sci->sc_binfo_ptr.bh = sumbh;  sci->sc_binfo_ptr.offset = sumbytes;
  	sci->sc_blk_cnt = sci->sc_datablk_cnt = 0;
  	return 0;
  }
  
  static int nilfs_segctor_feed_segment(struct nilfs_sc_info *sci)
  {
  	sci->sc_nblk_this_inc += sci->sc_curseg->sb_sum.nblocks;
  	if (NILFS_SEGBUF_IS_LAST(sci->sc_curseg, &sci->sc_segbufs))
  		return -E2BIG; /* The current segment is filled up
  				  (internal code) */
  	sci->sc_curseg = NILFS_NEXT_SEGBUF(sci->sc_curseg);
  	return nilfs_segctor_reset_segment_buffer(sci);
  }
  
  static int nilfs_segctor_add_super_root(struct nilfs_sc_info *sci)
  {
  	struct nilfs_segment_buffer *segbuf = sci->sc_curseg;
  	int err;
  
  	if (segbuf->sb_sum.nblocks >= segbuf->sb_rest_blocks) {
  		err = nilfs_segctor_feed_segment(sci);
  		if (err)
  			return err;
  		segbuf = sci->sc_curseg;
  	}
1e2b68bf2   Ryusuke Konishi   nilfs2: move poin...
393
  	err = nilfs_segbuf_extend_payload(segbuf, &segbuf->sb_super_root);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
  	if (likely(!err))
  		segbuf->sb_sum.flags |= NILFS_SS_SR;
  	return err;
  }
  
  /*
   * Functions for making segment summary and payloads
   */
  static int nilfs_segctor_segsum_block_required(
  	struct nilfs_sc_info *sci, const struct nilfs_segsum_pointer *ssp,
  	unsigned binfo_size)
  {
  	unsigned blocksize = sci->sc_super->s_blocksize;
  	/* Size of finfo and binfo is enough small against blocksize */
  
  	return ssp->offset + binfo_size +
  		(!sci->sc_blk_cnt ? sizeof(struct nilfs_finfo) : 0) >
  		blocksize;
  }
  
  static void nilfs_segctor_begin_finfo(struct nilfs_sc_info *sci,
  				      struct inode *inode)
  {
  	sci->sc_curseg->sb_sum.nfinfo++;
  	sci->sc_binfo_ptr = sci->sc_finfo_ptr;
  	nilfs_segctor_map_segsum_entry(
  		sci, &sci->sc_binfo_ptr, sizeof(struct nilfs_finfo));
c96fa464a   Ryusuke Konishi   nilfs2: mark mino...
421

72746ac64   Ryusuke Konishi   nilfs2: fix regre...
422
423
  	if (NILFS_I(inode)->i_root &&
  	    !test_bit(NILFS_SC_HAVE_DELTA, &sci->sc_flags))
c96fa464a   Ryusuke Konishi   nilfs2: mark mino...
424
  		set_bit(NILFS_SC_HAVE_DELTA, &sci->sc_flags);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
425
426
427
428
429
430
431
432
433
  	/* skip finfo */
  }
  
  static void nilfs_segctor_end_finfo(struct nilfs_sc_info *sci,
  				    struct inode *inode)
  {
  	struct nilfs_finfo *finfo;
  	struct nilfs_inode_info *ii;
  	struct nilfs_segment_buffer *segbuf;
6c43f4100   Ryusuke Konishi   nilfs2: keep zero...
434
  	__u64 cno;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
435
436
437
438
439
  
  	if (sci->sc_blk_cnt == 0)
  		return;
  
  	ii = NILFS_I(inode);
6c43f4100   Ryusuke Konishi   nilfs2: keep zero...
440
441
442
443
444
445
446
  
  	if (test_bit(NILFS_I_GCINODE, &ii->i_state))
  		cno = ii->i_cno;
  	else if (NILFS_ROOT_METADATA_FILE(inode->i_ino))
  		cno = 0;
  	else
  		cno = sci->sc_cno;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
447
448
449
450
451
  	finfo = nilfs_segctor_map_segsum_entry(sci, &sci->sc_finfo_ptr,
  						 sizeof(*finfo));
  	finfo->fi_ino = cpu_to_le64(inode->i_ino);
  	finfo->fi_nblocks = cpu_to_le32(sci->sc_blk_cnt);
  	finfo->fi_ndatablk = cpu_to_le32(sci->sc_datablk_cnt);
6c43f4100   Ryusuke Konishi   nilfs2: keep zero...
452
  	finfo->fi_cno = cpu_to_le64(cno);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
  
  	segbuf = sci->sc_curseg;
  	segbuf->sb_sum.sumbytes = sci->sc_binfo_ptr.offset +
  		sci->sc_super->s_blocksize * (segbuf->sb_sum.nsumblk - 1);
  	sci->sc_finfo_ptr = sci->sc_binfo_ptr;
  	sci->sc_blk_cnt = sci->sc_datablk_cnt = 0;
  }
  
  static int nilfs_segctor_add_file_block(struct nilfs_sc_info *sci,
  					struct buffer_head *bh,
  					struct inode *inode,
  					unsigned binfo_size)
  {
  	struct nilfs_segment_buffer *segbuf;
  	int required, err = 0;
  
   retry:
  	segbuf = sci->sc_curseg;
  	required = nilfs_segctor_segsum_block_required(
  		sci, &sci->sc_binfo_ptr, binfo_size);
  	if (segbuf->sb_sum.nblocks + required + 1 > segbuf->sb_rest_blocks) {
  		nilfs_segctor_end_finfo(sci, inode);
  		err = nilfs_segctor_feed_segment(sci);
  		if (err)
  			return err;
  		goto retry;
  	}
  	if (unlikely(required)) {
  		err = nilfs_segbuf_extend_segsum(segbuf);
  		if (unlikely(err))
  			goto failed;
  	}
  	if (sci->sc_blk_cnt == 0)
  		nilfs_segctor_begin_finfo(sci, inode);
  
  	nilfs_segctor_map_segsum_entry(sci, &sci->sc_binfo_ptr, binfo_size);
  	/* Substitution to vblocknr is delayed until update_blocknr() */
  	nilfs_segbuf_add_file_buffer(segbuf, bh);
  	sci->sc_blk_cnt++;
   failed:
  	return err;
  }
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
495
496
497
498
499
500
501
  /*
   * Callback functions that enumerate, mark, and collect dirty blocks
   */
  static int nilfs_collect_file_data(struct nilfs_sc_info *sci,
  				   struct buffer_head *bh, struct inode *inode)
  {
  	int err;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
502
  	err = nilfs_bmap_propagate(NILFS_I(inode)->i_bmap, bh);
e828949e5   Ryusuke Konishi   nilfs2: call nilf...
503
504
  	if (err < 0)
  		return err;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
505
506
507
508
509
510
511
512
513
514
515
516
  
  	err = nilfs_segctor_add_file_block(sci, bh, inode,
  					   sizeof(struct nilfs_binfo_v));
  	if (!err)
  		sci->sc_datablk_cnt++;
  	return err;
  }
  
  static int nilfs_collect_file_node(struct nilfs_sc_info *sci,
  				   struct buffer_head *bh,
  				   struct inode *inode)
  {
e828949e5   Ryusuke Konishi   nilfs2: call nilf...
517
  	return nilfs_bmap_propagate(NILFS_I(inode)->i_bmap, bh);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
518
519
520
521
522
523
  }
  
  static int nilfs_collect_file_bmap(struct nilfs_sc_info *sci,
  				   struct buffer_head *bh,
  				   struct inode *inode)
  {
1f5abe7e7   Ryusuke Konishi   nilfs2: replace B...
524
  	WARN_ON(!buffer_dirty(bh));
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
  	return nilfs_segctor_add_file_block(sci, bh, inode, sizeof(__le64));
  }
  
  static void nilfs_write_file_data_binfo(struct nilfs_sc_info *sci,
  					struct nilfs_segsum_pointer *ssp,
  					union nilfs_binfo *binfo)
  {
  	struct nilfs_binfo_v *binfo_v = nilfs_segctor_map_segsum_entry(
  		sci, ssp, sizeof(*binfo_v));
  	*binfo_v = binfo->bi_v;
  }
  
  static void nilfs_write_file_node_binfo(struct nilfs_sc_info *sci,
  					struct nilfs_segsum_pointer *ssp,
  					union nilfs_binfo *binfo)
  {
  	__le64 *vblocknr = nilfs_segctor_map_segsum_entry(
  		sci, ssp, sizeof(*vblocknr));
  	*vblocknr = binfo->bi_v.bi_vblocknr;
  }
4e819509c   Ryusuke Konishi   nilfs2: make nilf...
545
  static struct nilfs_sc_operations nilfs_sc_file_ops = {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
546
547
548
549
550
551
552
553
554
555
556
557
558
  	.collect_data = nilfs_collect_file_data,
  	.collect_node = nilfs_collect_file_node,
  	.collect_bmap = nilfs_collect_file_bmap,
  	.write_data_binfo = nilfs_write_file_data_binfo,
  	.write_node_binfo = nilfs_write_file_node_binfo,
  };
  
  static int nilfs_collect_dat_data(struct nilfs_sc_info *sci,
  				  struct buffer_head *bh, struct inode *inode)
  {
  	int err;
  
  	err = nilfs_bmap_propagate(NILFS_I(inode)->i_bmap, bh);
e828949e5   Ryusuke Konishi   nilfs2: call nilf...
559
560
  	if (err < 0)
  		return err;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
561
562
563
564
565
566
567
568
569
570
  
  	err = nilfs_segctor_add_file_block(sci, bh, inode, sizeof(__le64));
  	if (!err)
  		sci->sc_datablk_cnt++;
  	return err;
  }
  
  static int nilfs_collect_dat_bmap(struct nilfs_sc_info *sci,
  				  struct buffer_head *bh, struct inode *inode)
  {
1f5abe7e7   Ryusuke Konishi   nilfs2: replace B...
571
  	WARN_ON(!buffer_dirty(bh));
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
  	return nilfs_segctor_add_file_block(sci, bh, inode,
  					    sizeof(struct nilfs_binfo_dat));
  }
  
  static void nilfs_write_dat_data_binfo(struct nilfs_sc_info *sci,
  				       struct nilfs_segsum_pointer *ssp,
  				       union nilfs_binfo *binfo)
  {
  	__le64 *blkoff = nilfs_segctor_map_segsum_entry(sci, ssp,
  							  sizeof(*blkoff));
  	*blkoff = binfo->bi_dat.bi_blkoff;
  }
  
  static void nilfs_write_dat_node_binfo(struct nilfs_sc_info *sci,
  				       struct nilfs_segsum_pointer *ssp,
  				       union nilfs_binfo *binfo)
  {
  	struct nilfs_binfo_dat *binfo_dat =
  		nilfs_segctor_map_segsum_entry(sci, ssp, sizeof(*binfo_dat));
  	*binfo_dat = binfo->bi_dat;
  }
4e819509c   Ryusuke Konishi   nilfs2: make nilf...
593
  static struct nilfs_sc_operations nilfs_sc_dat_ops = {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
594
595
596
597
598
599
  	.collect_data = nilfs_collect_dat_data,
  	.collect_node = nilfs_collect_file_node,
  	.collect_bmap = nilfs_collect_dat_bmap,
  	.write_data_binfo = nilfs_write_dat_data_binfo,
  	.write_node_binfo = nilfs_write_dat_node_binfo,
  };
4e819509c   Ryusuke Konishi   nilfs2: make nilf...
600
  static struct nilfs_sc_operations nilfs_sc_dsync_ops = {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
601
602
603
604
605
606
  	.collect_data = nilfs_collect_file_data,
  	.collect_node = NULL,
  	.collect_bmap = NULL,
  	.write_data_binfo = nilfs_write_file_data_binfo,
  	.write_node_binfo = NULL,
  };
f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
607
608
609
610
  static size_t nilfs_lookup_dirty_data_buffers(struct inode *inode,
  					      struct list_head *listp,
  					      size_t nlimit,
  					      loff_t start, loff_t end)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
611
  {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
612
613
  	struct address_space *mapping = inode->i_mapping;
  	struct pagevec pvec;
f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
614
615
616
  	pgoff_t index = 0, last = ULONG_MAX;
  	size_t ndirties = 0;
  	int i;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
617

f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
618
619
620
621
622
623
624
625
626
  	if (unlikely(start != 0 || end != LLONG_MAX)) {
  		/*
  		 * A valid range is given for sync-ing data pages. The
  		 * range is rounded to per-page; extra dirty buffers
  		 * may be included if blocksize < pagesize.
  		 */
  		index = start >> PAGE_SHIFT;
  		last = end >> PAGE_SHIFT;
  	}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
627
628
  	pagevec_init(&pvec, 0);
   repeat:
f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
629
630
631
632
633
  	if (unlikely(index > last) ||
  	    !pagevec_lookup_tag(&pvec, mapping, &index, PAGECACHE_TAG_DIRTY,
  				min_t(pgoff_t, last - index,
  				      PAGEVEC_SIZE - 1) + 1))
  		return ndirties;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
634
635
636
637
  
  	for (i = 0; i < pagevec_count(&pvec); i++) {
  		struct buffer_head *bh, *head;
  		struct page *page = pvec.pages[i];
f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
638
639
  		if (unlikely(page->index > last))
  			break;
aa405b1f4   Ryusuke Konishi   nilfs2: always se...
640
641
642
643
  		lock_page(page);
  		if (!page_has_buffers(page))
  			create_empty_buffers(page, 1 << inode->i_blkbits, 0);
  		unlock_page(page);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
644
645
646
  
  		bh = head = page_buffers(page);
  		do {
f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
647
648
649
650
651
652
653
654
655
  			if (!buffer_dirty(bh))
  				continue;
  			get_bh(bh);
  			list_add_tail(&bh->b_assoc_buffers, listp);
  			ndirties++;
  			if (unlikely(ndirties >= nlimit)) {
  				pagevec_release(&pvec);
  				cond_resched();
  				return ndirties;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
656
  			}
f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
657
  		} while (bh = bh->b_this_page, bh != head);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
658
659
660
  	}
  	pagevec_release(&pvec);
  	cond_resched();
f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
661
  	goto repeat;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
  }
  
  static void nilfs_lookup_dirty_node_buffers(struct inode *inode,
  					    struct list_head *listp)
  {
  	struct nilfs_inode_info *ii = NILFS_I(inode);
  	struct address_space *mapping = &ii->i_btnode_cache;
  	struct pagevec pvec;
  	struct buffer_head *bh, *head;
  	unsigned int i;
  	pgoff_t index = 0;
  
  	pagevec_init(&pvec, 0);
  
  	while (pagevec_lookup_tag(&pvec, mapping, &index, PAGECACHE_TAG_DIRTY,
  				  PAGEVEC_SIZE)) {
  		for (i = 0; i < pagevec_count(&pvec); i++) {
  			bh = head = page_buffers(pvec.pages[i]);
  			do {
  				if (buffer_dirty(bh)) {
  					get_bh(bh);
  					list_add_tail(&bh->b_assoc_buffers,
  						      listp);
  				}
  				bh = bh->b_this_page;
  			} while (bh != head);
  		}
  		pagevec_release(&pvec);
  		cond_resched();
  	}
  }
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
693
  static void nilfs_dispose_list(struct the_nilfs *nilfs,
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
694
695
696
697
698
699
700
  			       struct list_head *head, int force)
  {
  	struct nilfs_inode_info *ii, *n;
  	struct nilfs_inode_info *ivec[SC_N_INODEVEC], **pii;
  	unsigned nv = 0;
  
  	while (!list_empty(head)) {
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
701
  		spin_lock(&nilfs->ns_inode_lock);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
702
703
704
705
706
707
708
709
710
711
  		list_for_each_entry_safe(ii, n, head, i_dirty) {
  			list_del_init(&ii->i_dirty);
  			if (force) {
  				if (unlikely(ii->i_bh)) {
  					brelse(ii->i_bh);
  					ii->i_bh = NULL;
  				}
  			} else if (test_bit(NILFS_I_DIRTY, &ii->i_state)) {
  				set_bit(NILFS_I_QUEUED, &ii->i_state);
  				list_add_tail(&ii->i_dirty,
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
712
  					      &nilfs->ns_dirty_files);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
713
714
715
716
717
718
  				continue;
  			}
  			ivec[nv++] = ii;
  			if (nv == SC_N_INODEVEC)
  				break;
  		}
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
719
  		spin_unlock(&nilfs->ns_inode_lock);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
720
721
722
723
724
  
  		for (pii = ivec; nv > 0; pii++, nv--)
  			iput(&(*pii)->vfs_inode);
  	}
  }
e912a5b66   Ryusuke Konishi   nilfs2: use root ...
725
726
  static int nilfs_test_metadata_dirty(struct the_nilfs *nilfs,
  				     struct nilfs_root *root)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
727
  {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
728
  	int ret = 0;
e912a5b66   Ryusuke Konishi   nilfs2: use root ...
729
  	if (nilfs_mdt_fetch_dirty(root->ifile))
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
730
731
732
733
734
  		ret++;
  	if (nilfs_mdt_fetch_dirty(nilfs->ns_cpfile))
  		ret++;
  	if (nilfs_mdt_fetch_dirty(nilfs->ns_sufile))
  		ret++;
365e215ce   Ryusuke Konishi   nilfs2: unfold ni...
735
736
  	if ((ret || nilfs_doing_gc()) && nilfs_mdt_fetch_dirty(nilfs->ns_dat))
  		ret++;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
737
738
739
740
741
742
743
  	return ret;
  }
  
  static int nilfs_segctor_clean(struct nilfs_sc_info *sci)
  {
  	return list_empty(&sci->sc_dirty_files) &&
  		!test_bit(NILFS_SC_DIRTY, &sci->sc_flags) &&
071cb4b81   Ryusuke Konishi   nilfs2: eliminate...
744
  		sci->sc_nfreesegs == 0 &&
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
745
746
747
748
749
  		(!nilfs_doing_gc() || list_empty(&sci->sc_gc_inodes));
  }
  
  static int nilfs_segctor_confirm(struct nilfs_sc_info *sci)
  {
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
750
  	struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
751
  	int ret = 0;
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
752
  	if (nilfs_test_metadata_dirty(nilfs, sci->sc_root))
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
753
  		set_bit(NILFS_SC_DIRTY, &sci->sc_flags);
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
754
755
  	spin_lock(&nilfs->ns_inode_lock);
  	if (list_empty(&nilfs->ns_dirty_files) && nilfs_segctor_clean(sci))
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
756
  		ret++;
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
757
  	spin_unlock(&nilfs->ns_inode_lock);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
758
759
760
761
762
  	return ret;
  }
  
  static void nilfs_segctor_clear_metadata_dirty(struct nilfs_sc_info *sci)
  {
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
763
  	struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
764

e912a5b66   Ryusuke Konishi   nilfs2: use root ...
765
  	nilfs_mdt_clear_dirty(sci->sc_root->ifile);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
766
767
  	nilfs_mdt_clear_dirty(nilfs->ns_cpfile);
  	nilfs_mdt_clear_dirty(nilfs->ns_sufile);
365e215ce   Ryusuke Konishi   nilfs2: unfold ni...
768
  	nilfs_mdt_clear_dirty(nilfs->ns_dat);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
769
770
771
772
  }
  
  static int nilfs_segctor_create_checkpoint(struct nilfs_sc_info *sci)
  {
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
773
  	struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
774
775
776
777
778
779
780
781
782
783
784
  	struct buffer_head *bh_cp;
  	struct nilfs_checkpoint *raw_cp;
  	int err;
  
  	/* XXX: this interface will be changed */
  	err = nilfs_cpfile_get_checkpoint(nilfs->ns_cpfile, nilfs->ns_cno, 1,
  					  &raw_cp, &bh_cp);
  	if (likely(!err)) {
  		/* The following code is duplicated with cpfile.  But, it is
  		   needed to collect the checkpoint even if it was not newly
  		   created */
5fc7b1417   Ryusuke Konishi   nilfs2: use mark_...
785
  		mark_buffer_dirty(bh_cp);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
786
787
788
  		nilfs_mdt_mark_dirty(nilfs->ns_cpfile);
  		nilfs_cpfile_put_checkpoint(
  			nilfs->ns_cpfile, nilfs->ns_cno, bh_cp);
1f5abe7e7   Ryusuke Konishi   nilfs2: replace B...
789
790
  	} else
  		WARN_ON(err == -EINVAL || err == -ENOENT);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
791
792
793
794
795
  	return err;
  }
  
  static int nilfs_segctor_fill_in_checkpoint(struct nilfs_sc_info *sci)
  {
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
796
  	struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
797
798
799
800
801
802
803
  	struct buffer_head *bh_cp;
  	struct nilfs_checkpoint *raw_cp;
  	int err;
  
  	err = nilfs_cpfile_get_checkpoint(nilfs->ns_cpfile, nilfs->ns_cno, 0,
  					  &raw_cp, &bh_cp);
  	if (unlikely(err)) {
1f5abe7e7   Ryusuke Konishi   nilfs2: replace B...
804
  		WARN_ON(err == -EINVAL || err == -ENOENT);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
805
806
807
808
809
  		goto failed_ibh;
  	}
  	raw_cp->cp_snapshot_list.ssl_next = 0;
  	raw_cp->cp_snapshot_list.ssl_prev = 0;
  	raw_cp->cp_inodes_count =
b7c063420   Ryusuke Konishi   nilfs2: move inod...
810
  		cpu_to_le64(atomic_read(&sci->sc_root->inodes_count));
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
811
  	raw_cp->cp_blocks_count =
b7c063420   Ryusuke Konishi   nilfs2: move inod...
812
  		cpu_to_le64(atomic_read(&sci->sc_root->blocks_count));
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
813
814
815
816
  	raw_cp->cp_nblk_inc =
  		cpu_to_le64(sci->sc_nblk_inc + sci->sc_nblk_this_inc);
  	raw_cp->cp_create = cpu_to_le64(sci->sc_seg_ctime);
  	raw_cp->cp_cno = cpu_to_le64(nilfs->ns_cno);
458c5b082   Ryusuke Konishi   nilfs2: clean up ...
817

c96fa464a   Ryusuke Konishi   nilfs2: mark mino...
818
819
820
821
  	if (test_bit(NILFS_SC_HAVE_DELTA, &sci->sc_flags))
  		nilfs_checkpoint_clear_minor(raw_cp);
  	else
  		nilfs_checkpoint_set_minor(raw_cp);
e912a5b66   Ryusuke Konishi   nilfs2: use root ...
822
823
  	nilfs_write_inode_common(sci->sc_root->ifile,
  				 &raw_cp->cp_ifile_inode, 1);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
  	nilfs_cpfile_put_checkpoint(nilfs->ns_cpfile, nilfs->ns_cno, bh_cp);
  	return 0;
  
   failed_ibh:
  	return err;
  }
  
  static void nilfs_fill_in_file_bmap(struct inode *ifile,
  				    struct nilfs_inode_info *ii)
  
  {
  	struct buffer_head *ibh;
  	struct nilfs_inode *raw_inode;
  
  	if (test_bit(NILFS_I_BMAP, &ii->i_state)) {
  		ibh = ii->i_bh;
  		BUG_ON(!ibh);
  		raw_inode = nilfs_ifile_map_inode(ifile, ii->vfs_inode.i_ino,
  						  ibh);
  		nilfs_bmap_write(ii->i_bmap, raw_inode);
  		nilfs_ifile_unmap_inode(ifile, ii->vfs_inode.i_ino, ibh);
  	}
  }
e912a5b66   Ryusuke Konishi   nilfs2: use root ...
847
  static void nilfs_segctor_fill_in_file_bmap(struct nilfs_sc_info *sci)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
848
849
850
851
  {
  	struct nilfs_inode_info *ii;
  
  	list_for_each_entry(ii, &sci->sc_dirty_files, i_dirty) {
e912a5b66   Ryusuke Konishi   nilfs2: use root ...
852
  		nilfs_fill_in_file_bmap(sci->sc_root->ifile, ii);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
853
854
  		set_bit(NILFS_I_COLLECTED, &ii->i_state);
  	}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
855
  }
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
856
857
858
  static void nilfs_segctor_fill_in_super_root(struct nilfs_sc_info *sci,
  					     struct the_nilfs *nilfs)
  {
1e2b68bf2   Ryusuke Konishi   nilfs2: move poin...
859
860
  	struct buffer_head *bh_sr;
  	struct nilfs_super_root *raw_sr;
56eb55388   Ryusuke Konishi   nilfs2: zero fill...
861
  	unsigned isz, srsz;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
862

1e2b68bf2   Ryusuke Konishi   nilfs2: move poin...
863
864
  	bh_sr = NILFS_LAST_SEGBUF(&sci->sc_segbufs)->sb_super_root;
  	raw_sr = (struct nilfs_super_root *)bh_sr->b_data;
56eb55388   Ryusuke Konishi   nilfs2: zero fill...
865
866
  	isz = nilfs->ns_inode_size;
  	srsz = NILFS_SR_BYTES(isz);
1e2b68bf2   Ryusuke Konishi   nilfs2: move poin...
867

56eb55388   Ryusuke Konishi   nilfs2: zero fill...
868
  	raw_sr->sr_bytes = cpu_to_le16(srsz);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
869
870
871
872
  	raw_sr->sr_nongc_ctime
  		= cpu_to_le64(nilfs_doing_gc() ?
  			      nilfs->ns_nongc_ctime : sci->sc_seg_ctime);
  	raw_sr->sr_flags = 0;
365e215ce   Ryusuke Konishi   nilfs2: unfold ni...
873
  	nilfs_write_inode_common(nilfs->ns_dat, (void *)raw_sr +
3961f0e27   Ryusuke Konishi   nilfs2: eliminate...
874
875
876
877
878
  				 NILFS_SR_DAT_OFFSET(isz), 1);
  	nilfs_write_inode_common(nilfs->ns_cpfile, (void *)raw_sr +
  				 NILFS_SR_CPFILE_OFFSET(isz), 1);
  	nilfs_write_inode_common(nilfs->ns_sufile, (void *)raw_sr +
  				 NILFS_SR_SUFILE_OFFSET(isz), 1);
56eb55388   Ryusuke Konishi   nilfs2: zero fill...
879
  	memset((void *)raw_sr + srsz, 0, nilfs->ns_blocksize - srsz);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
  }
  
  static void nilfs_redirty_inodes(struct list_head *head)
  {
  	struct nilfs_inode_info *ii;
  
  	list_for_each_entry(ii, head, i_dirty) {
  		if (test_bit(NILFS_I_COLLECTED, &ii->i_state))
  			clear_bit(NILFS_I_COLLECTED, &ii->i_state);
  	}
  }
  
  static void nilfs_drop_collected_inodes(struct list_head *head)
  {
  	struct nilfs_inode_info *ii;
  
  	list_for_each_entry(ii, head, i_dirty) {
  		if (!test_and_clear_bit(NILFS_I_COLLECTED, &ii->i_state))
  			continue;
  
  		clear_bit(NILFS_I_INODE_DIRTY, &ii->i_state);
  		set_bit(NILFS_I_UPDATED, &ii->i_state);
  	}
  }
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
  static int nilfs_segctor_apply_buffers(struct nilfs_sc_info *sci,
  				       struct inode *inode,
  				       struct list_head *listp,
  				       int (*collect)(struct nilfs_sc_info *,
  						      struct buffer_head *,
  						      struct inode *))
  {
  	struct buffer_head *bh, *n;
  	int err = 0;
  
  	if (collect) {
  		list_for_each_entry_safe(bh, n, listp, b_assoc_buffers) {
  			list_del_init(&bh->b_assoc_buffers);
  			err = collect(sci, bh, inode);
  			brelse(bh);
  			if (unlikely(err))
  				goto dispose_buffers;
  		}
  		return 0;
  	}
  
   dispose_buffers:
  	while (!list_empty(listp)) {
0cc128388   Ryusuke Konishi   nilfs2: use list_...
927
928
  		bh = list_first_entry(listp, struct buffer_head,
  				      b_assoc_buffers);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
929
930
931
932
933
  		list_del_init(&bh->b_assoc_buffers);
  		brelse(bh);
  	}
  	return err;
  }
f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
934
935
936
937
938
939
  static size_t nilfs_segctor_buffer_rest(struct nilfs_sc_info *sci)
  {
  	/* Remaining number of blocks within segment buffer */
  	return sci->sc_segbuf_nblocks -
  		(sci->sc_nblk_this_inc + sci->sc_curseg->sb_sum.nblocks);
  }
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
940
941
942
943
944
945
  static int nilfs_segctor_scan_file(struct nilfs_sc_info *sci,
  				   struct inode *inode,
  				   struct nilfs_sc_operations *sc_ops)
  {
  	LIST_HEAD(data_buffers);
  	LIST_HEAD(node_buffers);
f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
946
  	int err;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
947
948
  
  	if (!(sci->sc_stage.flags & NILFS_CF_NODE)) {
f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
949
950
951
952
953
954
  		size_t n, rest = nilfs_segctor_buffer_rest(sci);
  
  		n = nilfs_lookup_dirty_data_buffers(
  			inode, &data_buffers, rest + 1, 0, LLONG_MAX);
  		if (n > rest) {
  			err = nilfs_segctor_apply_buffers(
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
955
  				sci, inode, &data_buffers,
f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
956
957
  				sc_ops->collect_data);
  			BUG_ON(!err); /* always receive -E2BIG or true error */
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
  			goto break_or_fail;
  		}
  	}
  	nilfs_lookup_dirty_node_buffers(inode, &node_buffers);
  
  	if (!(sci->sc_stage.flags & NILFS_CF_NODE)) {
  		err = nilfs_segctor_apply_buffers(
  			sci, inode, &data_buffers, sc_ops->collect_data);
  		if (unlikely(err)) {
  			/* dispose node list */
  			nilfs_segctor_apply_buffers(
  				sci, inode, &node_buffers, NULL);
  			goto break_or_fail;
  		}
  		sci->sc_stage.flags |= NILFS_CF_NODE;
  	}
  	/* Collect node */
  	err = nilfs_segctor_apply_buffers(
  		sci, inode, &node_buffers, sc_ops->collect_node);
  	if (unlikely(err))
  		goto break_or_fail;
  
  	nilfs_bmap_lookup_dirty_buffers(NILFS_I(inode)->i_bmap, &node_buffers);
  	err = nilfs_segctor_apply_buffers(
  		sci, inode, &node_buffers, sc_ops->collect_bmap);
  	if (unlikely(err))
  		goto break_or_fail;
  
  	nilfs_segctor_end_finfo(sci, inode);
  	sci->sc_stage.flags &= ~NILFS_CF_NODE;
  
   break_or_fail:
  	return err;
  }
  
  static int nilfs_segctor_scan_file_dsync(struct nilfs_sc_info *sci,
  					 struct inode *inode)
  {
  	LIST_HEAD(data_buffers);
f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
997
998
  	size_t n, rest = nilfs_segctor_buffer_rest(sci);
  	int err;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
999

f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
1000
1001
1002
1003
1004
1005
1006
  	n = nilfs_lookup_dirty_data_buffers(inode, &data_buffers, rest + 1,
  					    sci->sc_dsync_start,
  					    sci->sc_dsync_end);
  
  	err = nilfs_segctor_apply_buffers(sci, inode, &data_buffers,
  					  nilfs_collect_file_data);
  	if (!err) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1007
  		nilfs_segctor_end_finfo(sci, inode);
f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
1008
1009
1010
  		BUG_ON(n > rest);
  		/* always receive -E2BIG or true error if n > rest */
  	}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1011
1012
1013
1014
1015
  	return err;
  }
  
  static int nilfs_segctor_collect_blocks(struct nilfs_sc_info *sci, int mode)
  {
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
1016
  	struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1017
1018
  	struct list_head *head;
  	struct nilfs_inode_info *ii;
071cb4b81   Ryusuke Konishi   nilfs2: eliminate...
1019
  	size_t ndone;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
  	int err = 0;
  
  	switch (sci->sc_stage.scnt) {
  	case NILFS_ST_INIT:
  		/* Pre-processes */
  		sci->sc_stage.flags = 0;
  
  		if (!test_bit(NILFS_SC_UNCLOSED, &sci->sc_flags)) {
  			sci->sc_nblk_inc = 0;
  			sci->sc_curseg->sb_sum.flags = NILFS_SS_LOGBGN;
  			if (mode == SC_LSEG_DSYNC) {
  				sci->sc_stage.scnt = NILFS_ST_DSYNC;
  				goto dsync_mode;
  			}
  		}
  
  		sci->sc_stage.dirty_file_ptr = NULL;
  		sci->sc_stage.gc_inode_ptr = NULL;
  		if (mode == SC_FLUSH_DAT) {
  			sci->sc_stage.scnt = NILFS_ST_DAT;
  			goto dat_stage;
  		}
  		sci->sc_stage.scnt++;  /* Fall through */
  	case NILFS_ST_GC:
  		if (nilfs_doing_gc()) {
  			head = &sci->sc_gc_inodes;
  			ii = list_prepare_entry(sci->sc_stage.gc_inode_ptr,
  						head, i_dirty);
  			list_for_each_entry_continue(ii, head, i_dirty) {
  				err = nilfs_segctor_scan_file(
  					sci, &ii->vfs_inode,
  					&nilfs_sc_file_ops);
  				if (unlikely(err)) {
  					sci->sc_stage.gc_inode_ptr = list_entry(
  						ii->i_dirty.prev,
  						struct nilfs_inode_info,
  						i_dirty);
  					goto break_or_fail;
  				}
  				set_bit(NILFS_I_COLLECTED, &ii->i_state);
  			}
  			sci->sc_stage.gc_inode_ptr = NULL;
  		}
  		sci->sc_stage.scnt++;  /* Fall through */
  	case NILFS_ST_FILE:
  		head = &sci->sc_dirty_files;
  		ii = list_prepare_entry(sci->sc_stage.dirty_file_ptr, head,
  					i_dirty);
  		list_for_each_entry_continue(ii, head, i_dirty) {
  			clear_bit(NILFS_I_DIRTY, &ii->i_state);
  
  			err = nilfs_segctor_scan_file(sci, &ii->vfs_inode,
  						      &nilfs_sc_file_ops);
  			if (unlikely(err)) {
  				sci->sc_stage.dirty_file_ptr =
  					list_entry(ii->i_dirty.prev,
  						   struct nilfs_inode_info,
  						   i_dirty);
  				goto break_or_fail;
  			}
  			/* sci->sc_stage.dirty_file_ptr = NILFS_I(inode); */
  			/* XXX: required ? */
  		}
  		sci->sc_stage.dirty_file_ptr = NULL;
  		if (mode == SC_FLUSH_FILE) {
  			sci->sc_stage.scnt = NILFS_ST_DONE;
  			return 0;
  		}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1088
1089
1090
1091
  		sci->sc_stage.scnt++;
  		sci->sc_stage.flags |= NILFS_CF_IFILE_STARTED;
  		/* Fall through */
  	case NILFS_ST_IFILE:
e912a5b66   Ryusuke Konishi   nilfs2: use root ...
1092
  		err = nilfs_segctor_scan_file(sci, sci->sc_root->ifile,
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
  					      &nilfs_sc_file_ops);
  		if (unlikely(err))
  			break;
  		sci->sc_stage.scnt++;
  		/* Creating a checkpoint */
  		err = nilfs_segctor_create_checkpoint(sci);
  		if (unlikely(err))
  			break;
  		/* Fall through */
  	case NILFS_ST_CPFILE:
  		err = nilfs_segctor_scan_file(sci, nilfs->ns_cpfile,
  					      &nilfs_sc_file_ops);
  		if (unlikely(err))
  			break;
  		sci->sc_stage.scnt++;  /* Fall through */
  	case NILFS_ST_SUFILE:
071cb4b81   Ryusuke Konishi   nilfs2: eliminate...
1109
1110
1111
1112
1113
1114
  		err = nilfs_sufile_freev(nilfs->ns_sufile, sci->sc_freesegs,
  					 sci->sc_nfreesegs, &ndone);
  		if (unlikely(err)) {
  			nilfs_sufile_cancel_freev(nilfs->ns_sufile,
  						  sci->sc_freesegs, ndone,
  						  NULL);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1115
  			break;
071cb4b81   Ryusuke Konishi   nilfs2: eliminate...
1116
1117
  		}
  		sci->sc_stage.flags |= NILFS_CF_SUFREED;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1118
1119
1120
1121
1122
1123
1124
  		err = nilfs_segctor_scan_file(sci, nilfs->ns_sufile,
  					      &nilfs_sc_file_ops);
  		if (unlikely(err))
  			break;
  		sci->sc_stage.scnt++;  /* Fall through */
  	case NILFS_ST_DAT:
   dat_stage:
365e215ce   Ryusuke Konishi   nilfs2: unfold ni...
1125
  		err = nilfs_segctor_scan_file(sci, nilfs->ns_dat,
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
  					      &nilfs_sc_dat_ops);
  		if (unlikely(err))
  			break;
  		if (mode == SC_FLUSH_DAT) {
  			sci->sc_stage.scnt = NILFS_ST_DONE;
  			return 0;
  		}
  		sci->sc_stage.scnt++;  /* Fall through */
  	case NILFS_ST_SR:
  		if (mode == SC_LSEG_SR) {
  			/* Appending a super root */
  			err = nilfs_segctor_add_super_root(sci);
  			if (unlikely(err))
  				break;
  		}
  		/* End of a logical segment */
  		sci->sc_curseg->sb_sum.flags |= NILFS_SS_LOGEND;
  		sci->sc_stage.scnt = NILFS_ST_DONE;
  		return 0;
  	case NILFS_ST_DSYNC:
   dsync_mode:
  		sci->sc_curseg->sb_sum.flags |= NILFS_SS_SYNDT;
f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
1148
  		ii = sci->sc_dsync_inode;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1149
1150
1151
1152
1153
1154
  		if (!test_bit(NILFS_I_BUSY, &ii->i_state))
  			break;
  
  		err = nilfs_segctor_scan_file_dsync(sci, &ii->vfs_inode);
  		if (unlikely(err))
  			break;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
  		sci->sc_curseg->sb_sum.flags |= NILFS_SS_LOGEND;
  		sci->sc_stage.scnt = NILFS_ST_DONE;
  		return 0;
  	case NILFS_ST_DONE:
  		return 0;
  	default:
  		BUG();
  	}
  
   break_or_fail:
  	return err;
  }
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1167
1168
1169
1170
1171
  /**
   * nilfs_segctor_begin_construction - setup segment buffer to make a new log
   * @sci: nilfs_sc_info
   * @nilfs: nilfs object
   */
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1172
1173
1174
  static int nilfs_segctor_begin_construction(struct nilfs_sc_info *sci,
  					    struct the_nilfs *nilfs)
  {
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1175
  	struct nilfs_segment_buffer *segbuf, *prev;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1176
  	__u64 nextnum;
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1177
  	int err, alloc = 0;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1178

a694291a6   Ryusuke Konishi   nilfs2: separate ...
1179
1180
1181
  	segbuf = nilfs_segbuf_new(sci->sc_super);
  	if (unlikely(!segbuf))
  		return -ENOMEM;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1182

a694291a6   Ryusuke Konishi   nilfs2: separate ...
1183
1184
1185
1186
1187
1188
1189
  	if (list_empty(&sci->sc_write_logs)) {
  		nilfs_segbuf_map(segbuf, nilfs->ns_segnum,
  				 nilfs->ns_pseg_offset, nilfs);
  		if (segbuf->sb_rest_blocks < NILFS_PSEG_MIN_BLOCKS) {
  			nilfs_shift_to_next_segment(nilfs);
  			nilfs_segbuf_map(segbuf, nilfs->ns_segnum, 0, nilfs);
  		}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1190

a694291a6   Ryusuke Konishi   nilfs2: separate ...
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
  		segbuf->sb_sum.seg_seq = nilfs->ns_seg_seq;
  		nextnum = nilfs->ns_nextnum;
  
  		if (nilfs->ns_segnum == nilfs->ns_nextnum)
  			/* Start from the head of a new full segment */
  			alloc++;
  	} else {
  		/* Continue logs */
  		prev = NILFS_LAST_SEGBUF(&sci->sc_write_logs);
  		nilfs_segbuf_map_cont(segbuf, prev);
  		segbuf->sb_sum.seg_seq = prev->sb_sum.seg_seq;
  		nextnum = prev->sb_nextnum;
  
  		if (segbuf->sb_rest_blocks < NILFS_PSEG_MIN_BLOCKS) {
  			nilfs_segbuf_map(segbuf, prev->sb_nextnum, 0, nilfs);
  			segbuf->sb_sum.seg_seq++;
  			alloc++;
  		}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1209
  	}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1210

61a189e9c   Ryusuke Konishi   nilfs2: move rout...
1211
  	err = nilfs_sufile_mark_dirty(nilfs->ns_sufile, segbuf->sb_segnum);
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1212
1213
  	if (err)
  		goto failed;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1214

a694291a6   Ryusuke Konishi   nilfs2: separate ...
1215
  	if (alloc) {
cece55207   Ryusuke Konishi   nilfs2: simplify ...
1216
  		err = nilfs_sufile_alloc(nilfs->ns_sufile, &nextnum);
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1217
1218
1219
  		if (err)
  			goto failed;
  	}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1220
  	nilfs_segbuf_set_next_segnum(segbuf, nextnum, nilfs);
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1221
1222
1223
  	BUG_ON(!list_empty(&sci->sc_segbufs));
  	list_add_tail(&segbuf->sb_list, &sci->sc_segbufs);
  	sci->sc_segbuf_nblocks = segbuf->sb_rest_blocks;
cece55207   Ryusuke Konishi   nilfs2: simplify ...
1224
  	return 0;
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1225
1226
1227
1228
  
   failed:
  	nilfs_segbuf_free(segbuf);
  	return err;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1229
1230
1231
1232
1233
  }
  
  static int nilfs_segctor_extend_segments(struct nilfs_sc_info *sci,
  					 struct the_nilfs *nilfs, int nadd)
  {
e29df395b   Ryusuke Konishi   nilfs2: add itera...
1234
  	struct nilfs_segment_buffer *segbuf, *prev;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
  	struct inode *sufile = nilfs->ns_sufile;
  	__u64 nextnextnum;
  	LIST_HEAD(list);
  	int err, ret, i;
  
  	prev = NILFS_LAST_SEGBUF(&sci->sc_segbufs);
  	/*
  	 * Since the segment specified with nextnum might be allocated during
  	 * the previous construction, the buffer including its segusage may
  	 * not be dirty.  The following call ensures that the buffer is dirty
  	 * and will pin the buffer on memory until the sufile is written.
  	 */
61a189e9c   Ryusuke Konishi   nilfs2: move rout...
1247
  	err = nilfs_sufile_mark_dirty(sufile, prev->sb_nextnum);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
  	if (unlikely(err))
  		return err;
  
  	for (i = 0; i < nadd; i++) {
  		/* extend segment info */
  		err = -ENOMEM;
  		segbuf = nilfs_segbuf_new(sci->sc_super);
  		if (unlikely(!segbuf))
  			goto failed;
  
  		/* map this buffer to region of segment on-disk */
cece55207   Ryusuke Konishi   nilfs2: simplify ...
1259
  		nilfs_segbuf_map(segbuf, prev->sb_nextnum, 0, nilfs);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
  		sci->sc_segbuf_nblocks += segbuf->sb_rest_blocks;
  
  		/* allocate the next next full segment */
  		err = nilfs_sufile_alloc(sufile, &nextnextnum);
  		if (unlikely(err))
  			goto failed_segbuf;
  
  		segbuf->sb_sum.seg_seq = prev->sb_sum.seg_seq + 1;
  		nilfs_segbuf_set_next_segnum(segbuf, nextnextnum, nilfs);
  
  		list_add_tail(&segbuf->sb_list, &list);
  		prev = segbuf;
  	}
0935db747   Ryusuke Konishi   nilfs2: use list_...
1273
  	list_splice_tail(&list, &sci->sc_segbufs);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1274
1275
1276
1277
1278
  	return 0;
  
   failed_segbuf:
  	nilfs_segbuf_free(segbuf);
   failed:
e29df395b   Ryusuke Konishi   nilfs2: add itera...
1279
  	list_for_each_entry(segbuf, &list, sb_list) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1280
  		ret = nilfs_sufile_free(sufile, segbuf->sb_nextnum);
1f5abe7e7   Ryusuke Konishi   nilfs2: replace B...
1281
  		WARN_ON(ret); /* never fails */
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1282
  	}
e29df395b   Ryusuke Konishi   nilfs2: add itera...
1283
  	nilfs_destroy_logs(&list);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1284
1285
  	return err;
  }
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1286
1287
  static void nilfs_free_incomplete_logs(struct list_head *logs,
  				       struct the_nilfs *nilfs)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1288
  {
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1289
1290
  	struct nilfs_segment_buffer *segbuf, *prev;
  	struct inode *sufile = nilfs->ns_sufile;
9284ad2a9   Ryusuke Konishi   nilfs2: relocate ...
1291
  	int ret;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1292

a694291a6   Ryusuke Konishi   nilfs2: separate ...
1293
  	segbuf = NILFS_FIRST_SEGBUF(logs);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1294
  	if (nilfs->ns_nextnum != segbuf->sb_nextnum) {
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1295
  		ret = nilfs_sufile_free(sufile, segbuf->sb_nextnum);
1f5abe7e7   Ryusuke Konishi   nilfs2: replace B...
1296
  		WARN_ON(ret); /* never fails */
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1297
  	}
9284ad2a9   Ryusuke Konishi   nilfs2: relocate ...
1298
  	if (atomic_read(&segbuf->sb_err)) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1299
1300
1301
1302
1303
1304
1305
1306
  		/* Case 1: The first segment failed */
  		if (segbuf->sb_pseg_start != segbuf->sb_fseg_start)
  			/* Case 1a:  Partial segment appended into an existing
  			   segment */
  			nilfs_terminate_segment(nilfs, segbuf->sb_fseg_start,
  						segbuf->sb_fseg_end);
  		else /* Case 1b:  New full segment */
  			set_nilfs_discontinued(nilfs);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1307
  	}
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1308
1309
1310
1311
1312
1313
  	prev = segbuf;
  	list_for_each_entry_continue(segbuf, logs, sb_list) {
  		if (prev->sb_nextnum != segbuf->sb_nextnum) {
  			ret = nilfs_sufile_free(sufile, segbuf->sb_nextnum);
  			WARN_ON(ret); /* never fails */
  		}
9284ad2a9   Ryusuke Konishi   nilfs2: relocate ...
1314
1315
1316
  		if (atomic_read(&segbuf->sb_err) &&
  		    segbuf->sb_segnum != nilfs->ns_nextnum)
  			/* Case 2: extended segment (!= next) failed */
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1317
1318
  			nilfs_sufile_set_error(sufile, segbuf->sb_segnum);
  		prev = segbuf;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1319
  	}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1320
1321
1322
1323
1324
1325
  }
  
  static void nilfs_segctor_update_segusage(struct nilfs_sc_info *sci,
  					  struct inode *sufile)
  {
  	struct nilfs_segment_buffer *segbuf;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1326
1327
1328
1329
  	unsigned long live_blocks;
  	int ret;
  
  	list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1330
1331
  		live_blocks = segbuf->sb_sum.nblocks +
  			(segbuf->sb_pseg_start - segbuf->sb_fseg_start);
071ec54dd   Ryusuke Konishi   nilfs2: move rout...
1332
1333
1334
1335
  		ret = nilfs_sufile_set_segment_usage(sufile, segbuf->sb_segnum,
  						     live_blocks,
  						     sci->sc_seg_ctime);
  		WARN_ON(ret); /* always succeed because the segusage is dirty */
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1336
1337
  	}
  }
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1338
  static void nilfs_cancel_segusage(struct list_head *logs, struct inode *sufile)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1339
1340
  {
  	struct nilfs_segment_buffer *segbuf;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1341
  	int ret;
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1342
  	segbuf = NILFS_FIRST_SEGBUF(logs);
071ec54dd   Ryusuke Konishi   nilfs2: move rout...
1343
1344
1345
1346
  	ret = nilfs_sufile_set_segment_usage(sufile, segbuf->sb_segnum,
  					     segbuf->sb_pseg_start -
  					     segbuf->sb_fseg_start, 0);
  	WARN_ON(ret); /* always succeed because the segusage is dirty */
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1347

a694291a6   Ryusuke Konishi   nilfs2: separate ...
1348
  	list_for_each_entry_continue(segbuf, logs, sb_list) {
071ec54dd   Ryusuke Konishi   nilfs2: move rout...
1349
1350
  		ret = nilfs_sufile_set_segment_usage(sufile, segbuf->sb_segnum,
  						     0, 0);
1f5abe7e7   Ryusuke Konishi   nilfs2: replace B...
1351
  		WARN_ON(ret); /* always succeed */
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1352
1353
1354
1355
1356
1357
1358
  	}
  }
  
  static void nilfs_segctor_truncate_segments(struct nilfs_sc_info *sci,
  					    struct nilfs_segment_buffer *last,
  					    struct inode *sufile)
  {
e29df395b   Ryusuke Konishi   nilfs2: add itera...
1359
  	struct nilfs_segment_buffer *segbuf = last;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1360
  	int ret;
e29df395b   Ryusuke Konishi   nilfs2: add itera...
1361
  	list_for_each_entry_continue(segbuf, &sci->sc_segbufs, sb_list) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1362
1363
  		sci->sc_segbuf_nblocks -= segbuf->sb_rest_blocks;
  		ret = nilfs_sufile_free(sufile, segbuf->sb_nextnum);
1f5abe7e7   Ryusuke Konishi   nilfs2: replace B...
1364
  		WARN_ON(ret);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1365
  	}
e29df395b   Ryusuke Konishi   nilfs2: add itera...
1366
  	nilfs_truncate_logs(&sci->sc_segbufs, last);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
  }
  
  
  static int nilfs_segctor_collect(struct nilfs_sc_info *sci,
  				 struct the_nilfs *nilfs, int mode)
  {
  	struct nilfs_cstage prev_stage = sci->sc_stage;
  	int err, nadd = 1;
  
  	/* Collection retry loop */
  	for (;;) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
  		sci->sc_nblk_this_inc = 0;
  		sci->sc_curseg = NILFS_FIRST_SEGBUF(&sci->sc_segbufs);
  
  		err = nilfs_segctor_reset_segment_buffer(sci);
  		if (unlikely(err))
  			goto failed;
  
  		err = nilfs_segctor_collect_blocks(sci, mode);
  		sci->sc_nblk_this_inc += sci->sc_curseg->sb_sum.nblocks;
  		if (!err)
  			break;
  
  		if (unlikely(err != -E2BIG))
  			goto failed;
  
  		/* The current segment is filled up */
  		if (mode != SC_LSEG_SR || sci->sc_stage.scnt < NILFS_ST_CPFILE)
  			break;
2d8428aca   Ryusuke Konishi   nilfs2: fix dupli...
1396
1397
1398
1399
1400
  		nilfs_clear_logs(&sci->sc_segbufs);
  
  		err = nilfs_segctor_extend_segments(sci, nilfs, nadd);
  		if (unlikely(err))
  			return err;
071cb4b81   Ryusuke Konishi   nilfs2: eliminate...
1401
1402
1403
1404
1405
1406
1407
  		if (sci->sc_stage.flags & NILFS_CF_SUFREED) {
  			err = nilfs_sufile_cancel_freev(nilfs->ns_sufile,
  							sci->sc_freesegs,
  							sci->sc_nfreesegs,
  							NULL);
  			WARN_ON(err); /* do not happen */
  		}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
  		nadd = min_t(int, nadd << 1, SC_MAX_SEGDELTA);
  		sci->sc_stage = prev_stage;
  	}
  	nilfs_segctor_truncate_segments(sci, sci->sc_curseg, nilfs->ns_sufile);
  	return 0;
  
   failed:
  	return err;
  }
  
  static void nilfs_list_replace_buffer(struct buffer_head *old_bh,
  				      struct buffer_head *new_bh)
  {
  	BUG_ON(!list_empty(&new_bh->b_assoc_buffers));
  
  	list_replace_init(&old_bh->b_assoc_buffers, &new_bh->b_assoc_buffers);
  	/* The caller must release old_bh */
  }
  
  static int
  nilfs_segctor_update_payload_blocknr(struct nilfs_sc_info *sci,
  				     struct nilfs_segment_buffer *segbuf,
  				     int mode)
  {
  	struct inode *inode = NULL;
  	sector_t blocknr;
  	unsigned long nfinfo = segbuf->sb_sum.nfinfo;
  	unsigned long nblocks = 0, ndatablk = 0;
  	struct nilfs_sc_operations *sc_op = NULL;
  	struct nilfs_segsum_pointer ssp;
  	struct nilfs_finfo *finfo = NULL;
  	union nilfs_binfo binfo;
  	struct buffer_head *bh, *bh_org;
  	ino_t ino = 0;
  	int err = 0;
  
  	if (!nfinfo)
  		goto out;
  
  	blocknr = segbuf->sb_pseg_start + segbuf->sb_sum.nsumblk;
  	ssp.bh = NILFS_SEGBUF_FIRST_BH(&segbuf->sb_segsum_buffers);
  	ssp.offset = sizeof(struct nilfs_segment_summary);
  
  	list_for_each_entry(bh, &segbuf->sb_payload_buffers, b_assoc_buffers) {
1e2b68bf2   Ryusuke Konishi   nilfs2: move poin...
1452
  		if (bh == segbuf->sb_super_root)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1453
1454
1455
1456
1457
1458
1459
  			break;
  		if (!finfo) {
  			finfo =	nilfs_segctor_map_segsum_entry(
  				sci, &ssp, sizeof(*finfo));
  			ino = le64_to_cpu(finfo->fi_ino);
  			nblocks = le32_to_cpu(finfo->fi_nblocks);
  			ndatablk = le32_to_cpu(finfo->fi_ndatablk);
aa405b1f4   Ryusuke Konishi   nilfs2: always se...
1460
  			inode = bh->b_page->mapping->host;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
  
  			if (mode == SC_LSEG_DSYNC)
  				sc_op = &nilfs_sc_dsync_ops;
  			else if (ino == NILFS_DAT_INO)
  				sc_op = &nilfs_sc_dat_ops;
  			else /* file blocks */
  				sc_op = &nilfs_sc_file_ops;
  		}
  		bh_org = bh;
  		get_bh(bh_org);
  		err = nilfs_bmap_assign(NILFS_I(inode)->i_bmap, &bh, blocknr,
  					&binfo);
  		if (bh != bh_org)
  			nilfs_list_replace_buffer(bh_org, bh);
  		brelse(bh_org);
  		if (unlikely(err))
  			goto failed_bmap;
  
  		if (ndatablk > 0)
  			sc_op->write_data_binfo(sci, &ssp, &binfo);
  		else
  			sc_op->write_node_binfo(sci, &ssp, &binfo);
  
  		blocknr++;
  		if (--nblocks == 0) {
  			finfo = NULL;
  			if (--nfinfo == 0)
  				break;
  		} else if (ndatablk > 0)
  			ndatablk--;
  	}
   out:
  	return 0;
  
   failed_bmap:
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
  	return err;
  }
  
  static int nilfs_segctor_assign(struct nilfs_sc_info *sci, int mode)
  {
  	struct nilfs_segment_buffer *segbuf;
  	int err;
  
  	list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) {
  		err = nilfs_segctor_update_payload_blocknr(sci, segbuf, mode);
  		if (unlikely(err))
  			return err;
  		nilfs_segbuf_fill_in_segsum(segbuf);
  	}
  	return 0;
  }
1cb2d38cb   Ryusuke Konishi   nilfs2: get rid o...
1512
  static void nilfs_begin_page_io(struct page *page)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1513
1514
1515
1516
  {
  	if (!page || PageWriteback(page))
  		/* For split b-tree node pages, this function may be called
  		   twice.  We ignore the 2nd or later calls by this check. */
1cb2d38cb   Ryusuke Konishi   nilfs2: get rid o...
1517
  		return;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1518
1519
1520
1521
1522
  
  	lock_page(page);
  	clear_page_dirty_for_io(page);
  	set_page_writeback(page);
  	unlock_page(page);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1523
  }
1cb2d38cb   Ryusuke Konishi   nilfs2: get rid o...
1524
  static void nilfs_segctor_prepare_write(struct nilfs_sc_info *sci)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1525
1526
1527
  {
  	struct nilfs_segment_buffer *segbuf;
  	struct page *bd_page = NULL, *fs_page = NULL;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1528

9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
  	list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) {
  		struct buffer_head *bh;
  
  		list_for_each_entry(bh, &segbuf->sb_segsum_buffers,
  				    b_assoc_buffers) {
  			if (bh->b_page != bd_page) {
  				if (bd_page) {
  					lock_page(bd_page);
  					clear_page_dirty_for_io(bd_page);
  					set_page_writeback(bd_page);
  					unlock_page(bd_page);
  				}
  				bd_page = bh->b_page;
  			}
  		}
  
  		list_for_each_entry(bh, &segbuf->sb_payload_buffers,
  				    b_assoc_buffers) {
1e2b68bf2   Ryusuke Konishi   nilfs2: move poin...
1547
  			if (bh == segbuf->sb_super_root) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
  				if (bh->b_page != bd_page) {
  					lock_page(bd_page);
  					clear_page_dirty_for_io(bd_page);
  					set_page_writeback(bd_page);
  					unlock_page(bd_page);
  					bd_page = bh->b_page;
  				}
  				break;
  			}
  			if (bh->b_page != fs_page) {
1cb2d38cb   Ryusuke Konishi   nilfs2: get rid o...
1558
  				nilfs_begin_page_io(fs_page);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
  				fs_page = bh->b_page;
  			}
  		}
  	}
  	if (bd_page) {
  		lock_page(bd_page);
  		clear_page_dirty_for_io(bd_page);
  		set_page_writeback(bd_page);
  		unlock_page(bd_page);
  	}
1cb2d38cb   Ryusuke Konishi   nilfs2: get rid o...
1569
  	nilfs_begin_page_io(fs_page);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1570
1571
1572
  }
  
  static int nilfs_segctor_write(struct nilfs_sc_info *sci,
9c965bac1   Ryusuke Konishi   nilfs2: hide nilf...
1573
  			       struct the_nilfs *nilfs)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1574
  {
d1c6b72a7   Ryusuke Konishi   nilfs2: move iter...
1575
  	int ret;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1576

d1c6b72a7   Ryusuke Konishi   nilfs2: move iter...
1577
  	ret = nilfs_write_logs(&sci->sc_segbufs, nilfs);
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1578
1579
  	list_splice_tail_init(&sci->sc_segbufs, &sci->sc_write_logs);
  	return ret;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1580
  }
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1581
1582
1583
1584
  static void nilfs_end_page_io(struct page *page, int err)
  {
  	if (!page)
  		return;
a97778457   Ryusuke Konishi   nilfs2: fix oops ...
1585
  	if (buffer_nilfs_node(page_buffers(page)) && !PageWriteback(page)) {
8227b2972   Ryusuke Konishi   nilfs2: fix hang ...
1586
1587
1588
1589
  		/*
  		 * For b-tree node pages, this function may be called twice
  		 * or more because they might be split in a segment.
  		 */
a97778457   Ryusuke Konishi   nilfs2: fix oops ...
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
  		if (PageDirty(page)) {
  			/*
  			 * For pages holding split b-tree node buffers, dirty
  			 * flag on the buffers may be cleared discretely.
  			 * In that case, the page is once redirtied for
  			 * remaining buffers, and it must be cancelled if
  			 * all the buffers get cleaned later.
  			 */
  			lock_page(page);
  			if (nilfs_page_buffers_clean(page))
  				__nilfs_clear_page_dirty(page);
  			unlock_page(page);
  		}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1603
  		return;
a97778457   Ryusuke Konishi   nilfs2: fix oops ...
1604
  	}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1605

1cb2d38cb   Ryusuke Konishi   nilfs2: get rid o...
1606
1607
1608
1609
1610
1611
1612
  	if (!err) {
  		if (!nilfs_page_buffers_clean(page))
  			__set_page_dirty_nobuffers(page);
  		ClearPageError(page);
  	} else {
  		__set_page_dirty_nobuffers(page);
  		SetPageError(page);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1613
  	}
1cb2d38cb   Ryusuke Konishi   nilfs2: get rid o...
1614
1615
  
  	end_page_writeback(page);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1616
  }
1cb2d38cb   Ryusuke Konishi   nilfs2: get rid o...
1617
  static void nilfs_abort_logs(struct list_head *logs, int err)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1618
1619
1620
  {
  	struct nilfs_segment_buffer *segbuf;
  	struct page *bd_page = NULL, *fs_page = NULL;
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1621
  	struct buffer_head *bh;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1622

a694291a6   Ryusuke Konishi   nilfs2: separate ...
1623
1624
  	if (list_empty(logs))
  		return;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1625

a694291a6   Ryusuke Konishi   nilfs2: separate ...
1626
  	list_for_each_entry(segbuf, logs, sb_list) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
  		list_for_each_entry(bh, &segbuf->sb_segsum_buffers,
  				    b_assoc_buffers) {
  			if (bh->b_page != bd_page) {
  				if (bd_page)
  					end_page_writeback(bd_page);
  				bd_page = bh->b_page;
  			}
  		}
  
  		list_for_each_entry(bh, &segbuf->sb_payload_buffers,
  				    b_assoc_buffers) {
1e2b68bf2   Ryusuke Konishi   nilfs2: move poin...
1638
  			if (bh == segbuf->sb_super_root) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1639
1640
1641
1642
1643
1644
1645
1646
  				if (bh->b_page != bd_page) {
  					end_page_writeback(bd_page);
  					bd_page = bh->b_page;
  				}
  				break;
  			}
  			if (bh->b_page != fs_page) {
  				nilfs_end_page_io(fs_page, err);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1647
1648
1649
1650
1651
1652
1653
1654
  				fs_page = bh->b_page;
  			}
  		}
  	}
  	if (bd_page)
  		end_page_writeback(bd_page);
  
  	nilfs_end_page_io(fs_page, err);
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
  }
  
  static void nilfs_segctor_abort_construction(struct nilfs_sc_info *sci,
  					     struct the_nilfs *nilfs, int err)
  {
  	LIST_HEAD(logs);
  	int ret;
  
  	list_splice_tail_init(&sci->sc_write_logs, &logs);
  	ret = nilfs_wait_on_logs(&logs);
1cb2d38cb   Ryusuke Konishi   nilfs2: get rid o...
1665
  	nilfs_abort_logs(&logs, ret ? : err);
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1666
1667
1668
1669
  
  	list_splice_tail_init(&sci->sc_segbufs, &logs);
  	nilfs_cancel_segusage(&logs, nilfs->ns_sufile);
  	nilfs_free_incomplete_logs(&logs, nilfs);
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
  
  	if (sci->sc_stage.flags & NILFS_CF_SUFREED) {
  		ret = nilfs_sufile_cancel_freev(nilfs->ns_sufile,
  						sci->sc_freesegs,
  						sci->sc_nfreesegs,
  						NULL);
  		WARN_ON(ret); /* do not happen */
  	}
  
  	nilfs_destroy_logs(&logs);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
  }
  
  static void nilfs_set_next_segment(struct the_nilfs *nilfs,
  				   struct nilfs_segment_buffer *segbuf)
  {
  	nilfs->ns_segnum = segbuf->sb_segnum;
  	nilfs->ns_nextnum = segbuf->sb_nextnum;
  	nilfs->ns_pseg_offset = segbuf->sb_pseg_start - segbuf->sb_fseg_start
  		+ segbuf->sb_sum.nblocks;
  	nilfs->ns_seg_seq = segbuf->sb_sum.seg_seq;
  	nilfs->ns_ctime = segbuf->sb_sum.ctime;
  }
  
  static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci)
  {
  	struct nilfs_segment_buffer *segbuf;
  	struct page *bd_page = NULL, *fs_page = NULL;
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
1697
  	struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
1e2b68bf2   Ryusuke Konishi   nilfs2: move poin...
1698
  	int update_sr = false;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1699

a694291a6   Ryusuke Konishi   nilfs2: separate ...
1700
  	list_for_each_entry(segbuf, &sci->sc_write_logs, sb_list) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
  		struct buffer_head *bh;
  
  		list_for_each_entry(bh, &segbuf->sb_segsum_buffers,
  				    b_assoc_buffers) {
  			set_buffer_uptodate(bh);
  			clear_buffer_dirty(bh);
  			if (bh->b_page != bd_page) {
  				if (bd_page)
  					end_page_writeback(bd_page);
  				bd_page = bh->b_page;
  			}
  		}
  		/*
  		 * We assume that the buffers which belong to the same page
  		 * continue over the buffer list.
  		 * Under this assumption, the last BHs of pages is
  		 * identifiable by the discontinuity of bh->b_page
  		 * (page != fs_page).
  		 *
  		 * For B-tree node blocks, however, this assumption is not
  		 * guaranteed.  The cleanup code of B-tree node pages needs
  		 * special care.
  		 */
  		list_for_each_entry(bh, &segbuf->sb_payload_buffers,
  				    b_assoc_buffers) {
  			set_buffer_uptodate(bh);
  			clear_buffer_dirty(bh);
27e6c7a3c   Ryusuke Konishi   nilfs2: mark buff...
1728
  			clear_buffer_delay(bh);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1729
  			clear_buffer_nilfs_volatile(bh);
b1f6a4f29   Ryusuke Konishi   nilfs2: add routi...
1730
  			clear_buffer_nilfs_redirected(bh);
1e2b68bf2   Ryusuke Konishi   nilfs2: move poin...
1731
  			if (bh == segbuf->sb_super_root) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1732
1733
1734
1735
  				if (bh->b_page != bd_page) {
  					end_page_writeback(bd_page);
  					bd_page = bh->b_page;
  				}
1e2b68bf2   Ryusuke Konishi   nilfs2: move poin...
1736
  				update_sr = true;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1737
1738
1739
1740
1741
1742
1743
  				break;
  			}
  			if (bh->b_page != fs_page) {
  				nilfs_end_page_io(fs_page, 0);
  				fs_page = bh->b_page;
  			}
  		}
4762077c7   Ryusuke Konishi   nilfs2: get rid o...
1744
1745
  		if (!nilfs_segbuf_simplex(segbuf)) {
  			if (segbuf->sb_sum.flags & NILFS_SS_LOGBGN) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1746
1747
1748
  				set_bit(NILFS_SC_UNCLOSED, &sci->sc_flags);
  				sci->sc_lseg_stime = jiffies;
  			}
4762077c7   Ryusuke Konishi   nilfs2: get rid o...
1749
  			if (segbuf->sb_sum.flags & NILFS_SS_LOGEND)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
  				clear_bit(NILFS_SC_UNCLOSED, &sci->sc_flags);
  		}
  	}
  	/*
  	 * Since pages may continue over multiple segment buffers,
  	 * end of the last page must be checked outside of the loop.
  	 */
  	if (bd_page)
  		end_page_writeback(bd_page);
  
  	nilfs_end_page_io(fs_page, 0);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1761
  	nilfs_drop_collected_inodes(&sci->sc_dirty_files);
c1c1d7092   Ryusuke Konishi   nilfs2: get rid o...
1762
  	if (nilfs_doing_gc())
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1763
  		nilfs_drop_collected_inodes(&sci->sc_gc_inodes);
c1c1d7092   Ryusuke Konishi   nilfs2: get rid o...
1764
  	else
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1765
  		nilfs->ns_nongc_ctime = sci->sc_seg_ctime;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1766
1767
  
  	sci->sc_nblk_inc += sci->sc_nblk_this_inc;
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1768
  	segbuf = NILFS_LAST_SEGBUF(&sci->sc_write_logs);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1769
1770
1771
1772
  	nilfs_set_next_segment(nilfs, segbuf);
  
  	if (update_sr) {
  		nilfs_set_last_segment(nilfs, segbuf->sb_pseg_start,
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
1773
  				       segbuf->sb_sum.seg_seq, nilfs->ns_cno++);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1774

c96fa464a   Ryusuke Konishi   nilfs2: mark mino...
1775
  		clear_bit(NILFS_SC_HAVE_DELTA, &sci->sc_flags);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1776
1777
  		clear_bit(NILFS_SC_DIRTY, &sci->sc_flags);
  		set_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags);
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1778
  		nilfs_segctor_clear_metadata_dirty(sci);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1779
1780
1781
  	} else
  		clear_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags);
  }
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
  static int nilfs_segctor_wait(struct nilfs_sc_info *sci)
  {
  	int ret;
  
  	ret = nilfs_wait_on_logs(&sci->sc_write_logs);
  	if (!ret) {
  		nilfs_segctor_complete_write(sci);
  		nilfs_destroy_logs(&sci->sc_write_logs);
  	}
  	return ret;
  }
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
1793
1794
  static int nilfs_segctor_collect_dirty_files(struct nilfs_sc_info *sci,
  					     struct the_nilfs *nilfs)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1795
1796
  {
  	struct nilfs_inode_info *ii, *n;
e912a5b66   Ryusuke Konishi   nilfs2: use root ...
1797
  	struct inode *ifile = sci->sc_root->ifile;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1798

693dd3212   Ryusuke Konishi   nilfs2: move s_in...
1799
  	spin_lock(&nilfs->ns_inode_lock);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1800
   retry:
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
1801
  	list_for_each_entry_safe(ii, n, &nilfs->ns_dirty_files, i_dirty) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1802
1803
1804
  		if (!ii->i_bh) {
  			struct buffer_head *ibh;
  			int err;
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
1805
  			spin_unlock(&nilfs->ns_inode_lock);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1806
  			err = nilfs_ifile_get_inode_block(
e912a5b66   Ryusuke Konishi   nilfs2: use root ...
1807
  				ifile, ii->vfs_inode.i_ino, &ibh);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1808
  			if (unlikely(err)) {
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
1809
  				nilfs_warning(sci->sc_super, __func__,
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1810
1811
1812
1813
  					      "failed to get inode block.
  ");
  				return err;
  			}
5fc7b1417   Ryusuke Konishi   nilfs2: use mark_...
1814
  			mark_buffer_dirty(ibh);
e912a5b66   Ryusuke Konishi   nilfs2: use root ...
1815
  			nilfs_mdt_mark_dirty(ifile);
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
1816
  			spin_lock(&nilfs->ns_inode_lock);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1817
1818
1819
1820
1821
1822
  			if (likely(!ii->i_bh))
  				ii->i_bh = ibh;
  			else
  				brelse(ibh);
  			goto retry;
  		}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1823
1824
1825
  
  		clear_bit(NILFS_I_QUEUED, &ii->i_state);
  		set_bit(NILFS_I_BUSY, &ii->i_state);
eaae0f37d   Nicolas Kaiser   nilfs2: merge lis...
1826
  		list_move_tail(&ii->i_dirty, &sci->sc_dirty_files);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1827
  	}
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
1828
  	spin_unlock(&nilfs->ns_inode_lock);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1829

9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1830
1831
  	return 0;
  }
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
1832
1833
  static void nilfs_segctor_drop_written_files(struct nilfs_sc_info *sci,
  					     struct the_nilfs *nilfs)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1834
1835
1836
  {
  	struct nilfs_transaction_info *ti = current->journal_info;
  	struct nilfs_inode_info *ii, *n;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1837

693dd3212   Ryusuke Konishi   nilfs2: move s_in...
1838
  	spin_lock(&nilfs->ns_inode_lock);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1839
1840
  	list_for_each_entry_safe(ii, n, &sci->sc_dirty_files, i_dirty) {
  		if (!test_and_clear_bit(NILFS_I_UPDATED, &ii->i_state) ||
6c43f4100   Ryusuke Konishi   nilfs2: keep zero...
1841
  		    test_bit(NILFS_I_DIRTY, &ii->i_state))
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1842
  			continue;
6c43f4100   Ryusuke Konishi   nilfs2: keep zero...
1843

9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1844
1845
1846
  		clear_bit(NILFS_I_BUSY, &ii->i_state);
  		brelse(ii->i_bh);
  		ii->i_bh = NULL;
eaae0f37d   Nicolas Kaiser   nilfs2: merge lis...
1847
  		list_move_tail(&ii->i_dirty, &ti->ti_garbage);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1848
  	}
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
1849
  	spin_unlock(&nilfs->ns_inode_lock);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1850
1851
1852
  }
  
  /*
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1853
1854
1855
1856
   * Main procedure of segment constructor
   */
  static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
  {
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
1857
  	struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
1e2b68bf2   Ryusuke Konishi   nilfs2: move poin...
1858
  	int err;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1859
1860
  
  	sci->sc_stage.scnt = NILFS_ST_INIT;
6c43f4100   Ryusuke Konishi   nilfs2: keep zero...
1861
  	sci->sc_cno = nilfs->ns_cno;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1862

693dd3212   Ryusuke Konishi   nilfs2: move s_in...
1863
  	err = nilfs_segctor_collect_dirty_files(sci, nilfs);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1864
1865
  	if (unlikely(err))
  		goto out;
e912a5b66   Ryusuke Konishi   nilfs2: use root ...
1866
  	if (nilfs_test_metadata_dirty(nilfs, sci->sc_root))
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
  		set_bit(NILFS_SC_DIRTY, &sci->sc_flags);
  
  	if (nilfs_segctor_clean(sci))
  		goto out;
  
  	do {
  		sci->sc_stage.flags &= ~NILFS_CF_HISTORY_MASK;
  
  		err = nilfs_segctor_begin_construction(sci, nilfs);
  		if (unlikely(err))
  			goto out;
  
  		/* Update time stamp */
  		sci->sc_seg_ctime = get_seconds();
  
  		err = nilfs_segctor_collect(sci, nilfs, mode);
  		if (unlikely(err))
  			goto failed;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1885
1886
  		/* Avoid empty segment */
  		if (sci->sc_stage.scnt == NILFS_ST_DONE &&
4762077c7   Ryusuke Konishi   nilfs2: get rid o...
1887
  		    nilfs_segbuf_empty(sci->sc_curseg)) {
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1888
  			nilfs_segctor_abort_construction(sci, nilfs, 1);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1889
1890
1891
1892
1893
1894
  			goto out;
  		}
  
  		err = nilfs_segctor_assign(sci, mode);
  		if (unlikely(err))
  			goto failed;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1895
  		if (sci->sc_stage.flags & NILFS_CF_IFILE_STARTED)
e912a5b66   Ryusuke Konishi   nilfs2: use root ...
1896
  			nilfs_segctor_fill_in_file_bmap(sci);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1897

1e2b68bf2   Ryusuke Konishi   nilfs2: move poin...
1898
1899
  		if (mode == SC_LSEG_SR &&
  		    sci->sc_stage.scnt >= NILFS_ST_CPFILE) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1900
1901
  			err = nilfs_segctor_fill_in_checkpoint(sci);
  			if (unlikely(err))
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1902
  				goto failed_to_write;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1903
1904
1905
1906
1907
1908
  
  			nilfs_segctor_fill_in_super_root(sci, nilfs);
  		}
  		nilfs_segctor_update_segusage(sci, nilfs->ns_sufile);
  
  		/* Write partial segments */
1cb2d38cb   Ryusuke Konishi   nilfs2: get rid o...
1909
  		nilfs_segctor_prepare_write(sci);
aaed1d5bf   Ryusuke Konishi   nilfs2: move out ...
1910
1911
1912
  
  		nilfs_add_checksums_on_logs(&sci->sc_segbufs,
  					    nilfs->ns_crc_seed);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1913

9c965bac1   Ryusuke Konishi   nilfs2: hide nilf...
1914
  		err = nilfs_segctor_write(sci, nilfs);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1915
1916
  		if (unlikely(err))
  			goto failed_to_write;
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
  		if (sci->sc_stage.scnt == NILFS_ST_DONE ||
  		    nilfs->ns_blocksize_bits != PAGE_CACHE_SHIFT) {
  			/*
  			 * At this point, we avoid double buffering
  			 * for blocksize < pagesize because page dirty
  			 * flag is turned off during write and dirty
  			 * buffers are not properly collected for
  			 * pages crossing over segments.
  			 */
  			err = nilfs_segctor_wait(sci);
  			if (err)
  				goto failed_to_write;
  		}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1930
  	} while (sci->sc_stage.scnt != NILFS_ST_DONE);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1931
   out:
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
1932
  	nilfs_segctor_drop_written_files(sci, nilfs);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1933
1934
1935
  	return err;
  
   failed_to_write:
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1936
1937
  	if (sci->sc_stage.flags & NILFS_CF_IFILE_STARTED)
  		nilfs_redirty_inodes(&sci->sc_dirty_files);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1938
1939
1940
1941
  
   failed:
  	if (nilfs_doing_gc())
  		nilfs_redirty_inodes(&sci->sc_gc_inodes);
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1942
  	nilfs_segctor_abort_construction(sci, nilfs, err);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1943
1944
1945
1946
  	goto out;
  }
  
  /**
9ccf56c13   Ryusuke Konishi   nilfs2: fix funct...
1947
   * nilfs_segctor_start_timer - set timer of background write
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1948
1949
1950
1951
1952
1953
1954
1955
1956
   * @sci: nilfs_sc_info
   *
   * If the timer has already been set, it ignores the new request.
   * This function MUST be called within a section locking the segment
   * semaphore.
   */
  static void nilfs_segctor_start_timer(struct nilfs_sc_info *sci)
  {
  	spin_lock(&sci->sc_state_lock);
fdce895ea   Li Hong   nilfs2: change sc...
1957
1958
1959
  	if (!(sci->sc_state & NILFS_SEGCTOR_COMMIT)) {
  		sci->sc_timer.expires = jiffies + sci->sc_interval;
  		add_timer(&sci->sc_timer);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
  		sci->sc_state |= NILFS_SEGCTOR_COMMIT;
  	}
  	spin_unlock(&sci->sc_state_lock);
  }
  
  static void nilfs_segctor_do_flush(struct nilfs_sc_info *sci, int bn)
  {
  	spin_lock(&sci->sc_state_lock);
  	if (!(sci->sc_flush_request & (1 << bn))) {
  		unsigned long prev_req = sci->sc_flush_request;
  
  		sci->sc_flush_request |= (1 << bn);
  		if (!prev_req)
  			wake_up(&sci->sc_wait_daemon);
  	}
  	spin_unlock(&sci->sc_state_lock);
  }
  
  /**
   * nilfs_flush_segment - trigger a segment construction for resource control
   * @sb: super block
   * @ino: inode number of the file to be flushed out.
   */
  void nilfs_flush_segment(struct super_block *sb, ino_t ino)
  {
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
1985
  	struct the_nilfs *nilfs = sb->s_fs_info;
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
1986
  	struct nilfs_sc_info *sci = nilfs->ns_writer;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1987
1988
1989
1990
1991
1992
  
  	if (!sci || nilfs_doing_construction())
  		return;
  	nilfs_segctor_do_flush(sci, NILFS_MDT_INODE(sb, ino) ? ino : 0);
  					/* assign bit 0 to data files */
  }
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
  struct nilfs_segctor_wait_request {
  	wait_queue_t	wq;
  	__u32		seq;
  	int		err;
  	atomic_t	done;
  };
  
  static int nilfs_segctor_sync(struct nilfs_sc_info *sci)
  {
  	struct nilfs_segctor_wait_request wait_req;
  	int err = 0;
  
  	spin_lock(&sci->sc_state_lock);
  	init_wait(&wait_req.wq);
  	wait_req.err = 0;
  	atomic_set(&wait_req.done, 0);
  	wait_req.seq = ++sci->sc_seq_request;
  	spin_unlock(&sci->sc_state_lock);
  
  	init_waitqueue_entry(&wait_req.wq, current);
  	add_wait_queue(&sci->sc_wait_request, &wait_req.wq);
  	set_current_state(TASK_INTERRUPTIBLE);
  	wake_up(&sci->sc_wait_daemon);
  
  	for (;;) {
  		if (atomic_read(&wait_req.done)) {
  			err = wait_req.err;
  			break;
  		}
  		if (!signal_pending(current)) {
  			schedule();
  			continue;
  		}
  		err = -ERESTARTSYS;
  		break;
  	}
  	finish_wait(&sci->sc_wait_request, &wait_req.wq);
  	return err;
  }
  
  static void nilfs_segctor_wakeup(struct nilfs_sc_info *sci, int err)
  {
  	struct nilfs_segctor_wait_request *wrq, *n;
  	unsigned long flags;
  
  	spin_lock_irqsave(&sci->sc_wait_request.lock, flags);
  	list_for_each_entry_safe(wrq, n, &sci->sc_wait_request.task_list,
  				 wq.task_list) {
  		if (!atomic_read(&wrq->done) &&
  		    nilfs_cnt32_ge(sci->sc_seq_done, wrq->seq)) {
  			wrq->err = err;
  			atomic_set(&wrq->done, 1);
  		}
  		if (atomic_read(&wrq->done)) {
  			wrq->wq.func(&wrq->wq,
  				     TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE,
  				     0, NULL);
  		}
  	}
  	spin_unlock_irqrestore(&sci->sc_wait_request.lock, flags);
  }
  
  /**
   * nilfs_construct_segment - construct a logical segment
   * @sb: super block
   *
   * Return Value: On success, 0 is retured. On errors, one of the following
   * negative error code is returned.
   *
   * %-EROFS - Read only filesystem.
   *
   * %-EIO - I/O error
   *
   * %-ENOSPC - No space left on device (only in a panic state).
   *
   * %-ERESTARTSYS - Interrupted.
   *
   * %-ENOMEM - Insufficient memory available.
   */
  int nilfs_construct_segment(struct super_block *sb)
  {
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
2074
  	struct the_nilfs *nilfs = sb->s_fs_info;
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
2075
  	struct nilfs_sc_info *sci = nilfs->ns_writer;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
  	struct nilfs_transaction_info *ti;
  	int err;
  
  	if (!sci)
  		return -EROFS;
  
  	/* A call inside transactions causes a deadlock. */
  	BUG_ON((ti = current->journal_info) && ti->ti_magic == NILFS_TI_MAGIC);
  
  	err = nilfs_segctor_sync(sci);
  	return err;
  }
  
  /**
   * nilfs_construct_dsync_segment - construct a data-only logical segment
   * @sb: super block
f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
2092
2093
2094
   * @inode: inode whose data blocks should be written out
   * @start: start byte offset
   * @end: end byte offset (inclusive)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
   *
   * Return Value: On success, 0 is retured. On errors, one of the following
   * negative error code is returned.
   *
   * %-EROFS - Read only filesystem.
   *
   * %-EIO - I/O error
   *
   * %-ENOSPC - No space left on device (only in a panic state).
   *
   * %-ERESTARTSYS - Interrupted.
   *
   * %-ENOMEM - Insufficient memory available.
   */
f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
2109
2110
  int nilfs_construct_dsync_segment(struct super_block *sb, struct inode *inode,
  				  loff_t start, loff_t end)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2111
  {
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
2112
  	struct the_nilfs *nilfs = sb->s_fs_info;
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
2113
  	struct nilfs_sc_info *sci = nilfs->ns_writer;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2114
2115
2116
2117
2118
2119
  	struct nilfs_inode_info *ii;
  	struct nilfs_transaction_info ti;
  	int err = 0;
  
  	if (!sci)
  		return -EROFS;
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2120
  	nilfs_transaction_lock(sb, &ti, 0);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2121
2122
2123
  
  	ii = NILFS_I(inode);
  	if (test_bit(NILFS_I_INODE_DIRTY, &ii->i_state) ||
3b2ce58b0   Ryusuke Konishi   nilfs2: move moun...
2124
  	    nilfs_test_opt(nilfs, STRICT_ORDER) ||
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2125
  	    test_bit(NILFS_SC_UNCLOSED, &sci->sc_flags) ||
3b2ce58b0   Ryusuke Konishi   nilfs2: move moun...
2126
  	    nilfs_discontinued(nilfs)) {
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2127
  		nilfs_transaction_unlock(sb);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2128
2129
2130
  		err = nilfs_segctor_sync(sci);
  		return err;
  	}
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
2131
  	spin_lock(&nilfs->ns_inode_lock);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2132
2133
  	if (!test_bit(NILFS_I_QUEUED, &ii->i_state) &&
  	    !test_bit(NILFS_I_BUSY, &ii->i_state)) {
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
2134
  		spin_unlock(&nilfs->ns_inode_lock);
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2135
  		nilfs_transaction_unlock(sb);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2136
2137
  		return 0;
  	}
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
2138
  	spin_unlock(&nilfs->ns_inode_lock);
f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
2139
2140
2141
  	sci->sc_dsync_inode = ii;
  	sci->sc_dsync_start = start;
  	sci->sc_dsync_end = end;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2142
2143
  
  	err = nilfs_segctor_do_construct(sci, SC_LSEG_DSYNC);
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2144
  	nilfs_transaction_unlock(sb);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2145
2146
  	return err;
  }
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2147
2148
  #define FLUSH_FILE_BIT	(0x1) /* data file only */
  #define FLUSH_DAT_BIT	(1 << NILFS_DAT_INO) /* DAT only */
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2149
2150
2151
2152
2153
  /**
   * nilfs_segctor_accept - record accepted sequence count of log-write requests
   * @sci: segment constructor object
   */
  static void nilfs_segctor_accept(struct nilfs_sc_info *sci)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2154
  {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2155
  	spin_lock(&sci->sc_state_lock);
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2156
  	sci->sc_seq_accepted = sci->sc_seq_request;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2157
  	spin_unlock(&sci->sc_state_lock);
fdce895ea   Li Hong   nilfs2: change sc...
2158
  	del_timer_sync(&sci->sc_timer);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2159
  }
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2160
2161
2162
2163
2164
2165
2166
  /**
   * nilfs_segctor_notify - notify the result of request to caller threads
   * @sci: segment constructor object
   * @mode: mode of log forming
   * @err: error code to be notified
   */
  static void nilfs_segctor_notify(struct nilfs_sc_info *sci, int mode, int err)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2167
2168
2169
  {
  	/* Clear requests (even when the construction failed) */
  	spin_lock(&sci->sc_state_lock);
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2170
  	if (mode == SC_LSEG_SR) {
aeda7f634   Ryusuke Konishi   nilfs2: fix irreg...
2171
  		sci->sc_state &= ~NILFS_SEGCTOR_COMMIT;
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2172
2173
  		sci->sc_seq_done = sci->sc_seq_accepted;
  		nilfs_segctor_wakeup(sci, err);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2174
  		sci->sc_flush_request = 0;
aeda7f634   Ryusuke Konishi   nilfs2: fix irreg...
2175
  	} else {
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2176
  		if (mode == SC_FLUSH_FILE)
aeda7f634   Ryusuke Konishi   nilfs2: fix irreg...
2177
  			sci->sc_flush_request &= ~FLUSH_FILE_BIT;
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2178
  		else if (mode == SC_FLUSH_DAT)
aeda7f634   Ryusuke Konishi   nilfs2: fix irreg...
2179
2180
2181
  			sci->sc_flush_request &= ~FLUSH_DAT_BIT;
  
  		/* re-enable timer if checkpoint creation was not done */
fdce895ea   Li Hong   nilfs2: change sc...
2182
2183
2184
  		if ((sci->sc_state & NILFS_SEGCTOR_COMMIT) &&
  		    time_before(jiffies, sci->sc_timer.expires))
  			add_timer(&sci->sc_timer);
aeda7f634   Ryusuke Konishi   nilfs2: fix irreg...
2185
  	}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2186
2187
  	spin_unlock(&sci->sc_state_lock);
  }
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2188
2189
2190
2191
2192
2193
  /**
   * nilfs_segctor_construct - form logs and write them to disk
   * @sci: segment constructor object
   * @mode: mode of log forming
   */
  static int nilfs_segctor_construct(struct nilfs_sc_info *sci, int mode)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2194
  {
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
2195
  	struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
d26493b6f   Jiro SEKIBA   nilfs2: introduce...
2196
  	struct nilfs_super_block **sbp;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2197
  	int err = 0;
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2198
  	nilfs_segctor_accept(sci);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2199
  	if (nilfs_discontinued(nilfs))
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2200
2201
2202
  		mode = SC_LSEG_SR;
  	if (!nilfs_segctor_confirm(sci))
  		err = nilfs_segctor_do_construct(sci, mode);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2203
  	if (likely(!err)) {
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2204
  		if (mode != SC_FLUSH_DAT)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2205
2206
2207
2208
  			atomic_set(&nilfs->ns_ndirtyblks, 0);
  		if (test_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags) &&
  		    nilfs_discontinued(nilfs)) {
  			down_write(&nilfs->ns_sem);
d26493b6f   Jiro SEKIBA   nilfs2: introduce...
2209
  			err = -EIO;
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2210
  			sbp = nilfs_prepare_super(sci->sc_super,
b2ac86e1a   Jiro SEKIBA   nilfs2: sync supe...
2211
2212
2213
  						  nilfs_sb_will_flip(nilfs));
  			if (likely(sbp)) {
  				nilfs_set_log_cursor(sbp[0], nilfs);
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2214
2215
  				err = nilfs_commit_super(sci->sc_super,
  							 NILFS_SB_COMMIT);
b2ac86e1a   Jiro SEKIBA   nilfs2: sync supe...
2216
  			}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2217
2218
2219
  			up_write(&nilfs->ns_sem);
  		}
  	}
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2220
2221
  
  	nilfs_segctor_notify(sci, mode, err);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
  	return err;
  }
  
  static void nilfs_construction_timeout(unsigned long data)
  {
  	struct task_struct *p = (struct task_struct *)data;
  	wake_up_process(p);
  }
  
  static void
  nilfs_remove_written_gcinodes(struct the_nilfs *nilfs, struct list_head *head)
  {
  	struct nilfs_inode_info *ii, *n;
  
  	list_for_each_entry_safe(ii, n, head, i_dirty) {
  		if (!test_bit(NILFS_I_UPDATED, &ii->i_state))
  			continue;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2239
  		list_del_init(&ii->i_dirty);
263d90cef   Ryusuke Konishi   nilfs2: remove ow...
2240
  		iput(&ii->vfs_inode);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2241
2242
  	}
  }
4f6b82883   Ryusuke Konishi   nilfs2: fix lock ...
2243
2244
  int nilfs_clean_segments(struct super_block *sb, struct nilfs_argv *argv,
  			 void **kbufs)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2245
  {
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
2246
  	struct the_nilfs *nilfs = sb->s_fs_info;
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
2247
  	struct nilfs_sc_info *sci = nilfs->ns_writer;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2248
  	struct nilfs_transaction_info ti;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2249
2250
2251
2252
  	int err;
  
  	if (unlikely(!sci))
  		return -EROFS;
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2253
  	nilfs_transaction_lock(sb, &ti, 1);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2254

c1c1d7092   Ryusuke Konishi   nilfs2: get rid o...
2255
  	err = nilfs_mdt_save_to_shadow_map(nilfs->ns_dat);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2256
2257
  	if (unlikely(err))
  		goto out_unlock;
071cb4b81   Ryusuke Konishi   nilfs2: eliminate...
2258

4f6b82883   Ryusuke Konishi   nilfs2: fix lock ...
2259
  	err = nilfs_ioctl_prepare_clean_segments(nilfs, argv, kbufs);
c1c1d7092   Ryusuke Konishi   nilfs2: get rid o...
2260
2261
  	if (unlikely(err)) {
  		nilfs_mdt_restore_from_shadow_map(nilfs->ns_dat);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2262
  		goto out_unlock;
c1c1d7092   Ryusuke Konishi   nilfs2: get rid o...
2263
  	}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2264

071cb4b81   Ryusuke Konishi   nilfs2: eliminate...
2265
2266
  	sci->sc_freesegs = kbufs[4];
  	sci->sc_nfreesegs = argv[4].v_nmembs;
0935db747   Ryusuke Konishi   nilfs2: use list_...
2267
  	list_splice_tail_init(&nilfs->ns_gc_inodes, &sci->sc_gc_inodes);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2268
2269
  
  	for (;;) {
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2270
  		err = nilfs_segctor_construct(sci, SC_LSEG_SR);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2271
  		nilfs_remove_written_gcinodes(nilfs, &sci->sc_gc_inodes);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2272
2273
2274
2275
2276
2277
2278
2279
2280
  
  		if (likely(!err))
  			break;
  
  		nilfs_warning(sb, __func__,
  			      "segment construction failed. (err=%d)", err);
  		set_current_state(TASK_INTERRUPTIBLE);
  		schedule_timeout(sci->sc_interval);
  	}
3b2ce58b0   Ryusuke Konishi   nilfs2: move moun...
2281
  	if (nilfs_test_opt(nilfs, DISCARD)) {
e902ec990   Jiro SEKIBA   nilfs2: issue dis...
2282
2283
2284
2285
2286
2287
2288
  		int ret = nilfs_discard_segments(nilfs, sci->sc_freesegs,
  						 sci->sc_nfreesegs);
  		if (ret) {
  			printk(KERN_WARNING
  			       "NILFS warning: error %d on discard request, "
  			       "turning discards off for the device
  ", ret);
3b2ce58b0   Ryusuke Konishi   nilfs2: move moun...
2289
  			nilfs_clear_opt(nilfs, DISCARD);
e902ec990   Jiro SEKIBA   nilfs2: issue dis...
2290
2291
  		}
  	}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2292
2293
  
   out_unlock:
071cb4b81   Ryusuke Konishi   nilfs2: eliminate...
2294
2295
  	sci->sc_freesegs = NULL;
  	sci->sc_nfreesegs = 0;
c1c1d7092   Ryusuke Konishi   nilfs2: get rid o...
2296
  	nilfs_mdt_clear_shadow_map(nilfs->ns_dat);
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2297
  	nilfs_transaction_unlock(sb);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2298
2299
2300
2301
2302
  	return err;
  }
  
  static void nilfs_segctor_thread_construct(struct nilfs_sc_info *sci, int mode)
  {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2303
  	struct nilfs_transaction_info ti;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2304

f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2305
  	nilfs_transaction_lock(sci->sc_super, &ti, 0);
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2306
  	nilfs_segctor_construct(sci, mode);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2307
2308
2309
2310
2311
2312
2313
2314
  
  	/*
  	 * Unclosed segment should be retried.  We do this using sc_timer.
  	 * Timeout of sc_timer will invoke complete construction which leads
  	 * to close the current logical segment.
  	 */
  	if (test_bit(NILFS_SC_UNCLOSED, &sci->sc_flags))
  		nilfs_segctor_start_timer(sci);
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2315
  	nilfs_transaction_unlock(sci->sc_super);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
  }
  
  static void nilfs_segctor_do_immediate_flush(struct nilfs_sc_info *sci)
  {
  	int mode = 0;
  	int err;
  
  	spin_lock(&sci->sc_state_lock);
  	mode = (sci->sc_flush_request & FLUSH_DAT_BIT) ?
  		SC_FLUSH_DAT : SC_FLUSH_FILE;
  	spin_unlock(&sci->sc_state_lock);
  
  	if (mode) {
  		err = nilfs_segctor_do_construct(sci, mode);
  
  		spin_lock(&sci->sc_state_lock);
  		sci->sc_flush_request &= (mode == SC_FLUSH_FILE) ?
  			~FLUSH_FILE_BIT : ~FLUSH_DAT_BIT;
  		spin_unlock(&sci->sc_state_lock);
  	}
  	clear_bit(NILFS_SC_PRIOR_FLUSH, &sci->sc_flags);
  }
  
  static int nilfs_segctor_flush_mode(struct nilfs_sc_info *sci)
  {
  	if (!test_bit(NILFS_SC_UNCLOSED, &sci->sc_flags) ||
  	    time_before(jiffies, sci->sc_lseg_stime + sci->sc_mjcp_freq)) {
  		if (!(sci->sc_flush_request & ~FLUSH_FILE_BIT))
  			return SC_FLUSH_FILE;
  		else if (!(sci->sc_flush_request & ~FLUSH_DAT_BIT))
  			return SC_FLUSH_DAT;
  	}
  	return SC_LSEG_SR;
  }
  
  /**
   * nilfs_segctor_thread - main loop of the segment constructor thread.
   * @arg: pointer to a struct nilfs_sc_info.
   *
   * nilfs_segctor_thread() initializes a timer and serves as a daemon
   * to execute segment constructions.
   */
  static int nilfs_segctor_thread(void *arg)
  {
  	struct nilfs_sc_info *sci = (struct nilfs_sc_info *)arg;
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
2361
  	struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2362
  	int timeout = 0;
fdce895ea   Li Hong   nilfs2: change sc...
2363
2364
  	sci->sc_timer.data = (unsigned long)current;
  	sci->sc_timer.function = nilfs_construction_timeout;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
  
  	/* start sync. */
  	sci->sc_task = current;
  	wake_up(&sci->sc_wait_task); /* for nilfs_segctor_start_thread() */
  	printk(KERN_INFO
  	       "segctord starting. Construction interval = %lu seconds, "
  	       "CP frequency < %lu seconds
  ",
  	       sci->sc_interval / HZ, sci->sc_mjcp_freq / HZ);
  
  	spin_lock(&sci->sc_state_lock);
   loop:
  	for (;;) {
  		int mode;
  
  		if (sci->sc_state & NILFS_SEGCTOR_QUIT)
  			goto end_thread;
  
  		if (timeout || sci->sc_seq_request != sci->sc_seq_done)
  			mode = SC_LSEG_SR;
  		else if (!sci->sc_flush_request)
  			break;
  		else
  			mode = nilfs_segctor_flush_mode(sci);
  
  		spin_unlock(&sci->sc_state_lock);
  		nilfs_segctor_thread_construct(sci, mode);
  		spin_lock(&sci->sc_state_lock);
  		timeout = 0;
  	}
  
  
  	if (freezing(current)) {
  		spin_unlock(&sci->sc_state_lock);
a0acae0e8   Tejun Heo   freezer: unexport...
2399
  		try_to_freeze();
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
  		spin_lock(&sci->sc_state_lock);
  	} else {
  		DEFINE_WAIT(wait);
  		int should_sleep = 1;
  
  		prepare_to_wait(&sci->sc_wait_daemon, &wait,
  				TASK_INTERRUPTIBLE);
  
  		if (sci->sc_seq_request != sci->sc_seq_done)
  			should_sleep = 0;
  		else if (sci->sc_flush_request)
  			should_sleep = 0;
  		else if (sci->sc_state & NILFS_SEGCTOR_COMMIT)
  			should_sleep = time_before(jiffies,
fdce895ea   Li Hong   nilfs2: change sc...
2414
  					sci->sc_timer.expires);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2415
2416
2417
2418
2419
2420
2421
2422
  
  		if (should_sleep) {
  			spin_unlock(&sci->sc_state_lock);
  			schedule();
  			spin_lock(&sci->sc_state_lock);
  		}
  		finish_wait(&sci->sc_wait_daemon, &wait);
  		timeout = ((sci->sc_state & NILFS_SEGCTOR_COMMIT) &&
fdce895ea   Li Hong   nilfs2: change sc...
2423
  			   time_after_eq(jiffies, sci->sc_timer.expires));
e605f0a72   Ryusuke Konishi   nilfs2: get rid o...
2424
2425
  
  		if (nilfs_sb_dirty(nilfs) && nilfs_sb_need_update(nilfs))
1dfa27105   Jiro SEKIBA   nilfs2: stop usin...
2426
  			set_nilfs_discontinued(nilfs);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2427
2428
2429
2430
2431
  	}
  	goto loop;
  
   end_thread:
  	spin_unlock(&sci->sc_state_lock);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
  
  	/* end sync. */
  	sci->sc_task = NULL;
  	wake_up(&sci->sc_wait_task); /* for nilfs_segctor_kill_thread() */
  	return 0;
  }
  
  static int nilfs_segctor_start_thread(struct nilfs_sc_info *sci)
  {
  	struct task_struct *t;
  
  	t = kthread_run(nilfs_segctor_thread, sci, "segctord");
  	if (IS_ERR(t)) {
  		int err = PTR_ERR(t);
  
  		printk(KERN_ERR "NILFS: error %d creating segctord thread
  ",
  		       err);
  		return err;
  	}
  	wait_event(sci->sc_wait_task, sci->sc_task != NULL);
  	return 0;
  }
  
  static void nilfs_segctor_kill_thread(struct nilfs_sc_info *sci)
6b81e14e6   Jiro SEKIBA   nilfs2: eliminate...
2457
2458
  	__acquires(&sci->sc_state_lock)
  	__releases(&sci->sc_state_lock)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
  {
  	sci->sc_state |= NILFS_SEGCTOR_QUIT;
  
  	while (sci->sc_task) {
  		wake_up(&sci->sc_wait_daemon);
  		spin_unlock(&sci->sc_state_lock);
  		wait_event(sci->sc_wait_task, sci->sc_task == NULL);
  		spin_lock(&sci->sc_state_lock);
  	}
  }
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2469
2470
2471
  /*
   * Setup & clean-up functions
   */
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2472
  static struct nilfs_sc_info *nilfs_segctor_new(struct super_block *sb,
e912a5b66   Ryusuke Konishi   nilfs2: use root ...
2473
  					       struct nilfs_root *root)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2474
  {
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
2475
  	struct the_nilfs *nilfs = sb->s_fs_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2476
2477
2478
2479
2480
  	struct nilfs_sc_info *sci;
  
  	sci = kzalloc(sizeof(*sci), GFP_KERNEL);
  	if (!sci)
  		return NULL;
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2481
  	sci->sc_super = sb;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2482

e912a5b66   Ryusuke Konishi   nilfs2: use root ...
2483
2484
  	nilfs_get_root(root);
  	sci->sc_root = root;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2485
2486
2487
2488
2489
2490
  	init_waitqueue_head(&sci->sc_wait_request);
  	init_waitqueue_head(&sci->sc_wait_daemon);
  	init_waitqueue_head(&sci->sc_wait_task);
  	spin_lock_init(&sci->sc_state_lock);
  	INIT_LIST_HEAD(&sci->sc_dirty_files);
  	INIT_LIST_HEAD(&sci->sc_segbufs);
a694291a6   Ryusuke Konishi   nilfs2: separate ...
2491
  	INIT_LIST_HEAD(&sci->sc_write_logs);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2492
  	INIT_LIST_HEAD(&sci->sc_gc_inodes);
fdce895ea   Li Hong   nilfs2: change sc...
2493
  	init_timer(&sci->sc_timer);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2494
2495
2496
2497
  
  	sci->sc_interval = HZ * NILFS_SC_DEFAULT_TIMEOUT;
  	sci->sc_mjcp_freq = HZ * NILFS_SC_DEFAULT_SR_FREQ;
  	sci->sc_watermark = NILFS_SC_DEFAULT_WATERMARK;
574e6c314   Ryusuke Konishi   nilfs2: move para...
2498
  	if (nilfs->ns_interval)
071d73cfe   Ryusuke Konishi   nilfs2: fix probl...
2499
  		sci->sc_interval = HZ * nilfs->ns_interval;
574e6c314   Ryusuke Konishi   nilfs2: move para...
2500
2501
  	if (nilfs->ns_watermark)
  		sci->sc_watermark = nilfs->ns_watermark;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
  	return sci;
  }
  
  static void nilfs_segctor_write_out(struct nilfs_sc_info *sci)
  {
  	int ret, retrycount = NILFS_SC_CLEANUP_RETRY;
  
  	/* The segctord thread was stopped and its timer was removed.
  	   But some tasks remain. */
  	do {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2512
  		struct nilfs_transaction_info ti;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2513

f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2514
  		nilfs_transaction_lock(sci->sc_super, &ti, 0);
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2515
  		ret = nilfs_segctor_construct(sci, SC_LSEG_SR);
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2516
  		nilfs_transaction_unlock(sci->sc_super);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
  
  	} while (ret && retrycount-- > 0);
  }
  
  /**
   * nilfs_segctor_destroy - destroy the segment constructor.
   * @sci: nilfs_sc_info
   *
   * nilfs_segctor_destroy() kills the segctord thread and frees
   * the nilfs_sc_info struct.
   * Caller must hold the segment semaphore.
   */
  static void nilfs_segctor_destroy(struct nilfs_sc_info *sci)
  {
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
2531
  	struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2532
  	int flag;
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
2533
  	up_write(&nilfs->ns_segctor_sem);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2534
2535
2536
2537
2538
2539
  
  	spin_lock(&sci->sc_state_lock);
  	nilfs_segctor_kill_thread(sci);
  	flag = ((sci->sc_state & NILFS_SEGCTOR_COMMIT) || sci->sc_flush_request
  		|| sci->sc_seq_request != sci->sc_seq_done);
  	spin_unlock(&sci->sc_state_lock);
3256a0553   Ryusuke Konishi   nilfs2: fix poten...
2540
  	if (flag || !nilfs_segctor_confirm(sci))
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2541
  		nilfs_segctor_write_out(sci);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2542
  	if (!list_empty(&sci->sc_dirty_files)) {
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
2543
  		nilfs_warning(sci->sc_super, __func__,
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2544
2545
  			      "dirty file(s) after the final construction
  ");
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
2546
  		nilfs_dispose_list(nilfs, &sci->sc_dirty_files, 1);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2547
  	}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2548

1f5abe7e7   Ryusuke Konishi   nilfs2: replace B...
2549
  	WARN_ON(!list_empty(&sci->sc_segbufs));
a694291a6   Ryusuke Konishi   nilfs2: separate ...
2550
  	WARN_ON(!list_empty(&sci->sc_write_logs));
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2551

e912a5b66   Ryusuke Konishi   nilfs2: use root ...
2552
  	nilfs_put_root(sci->sc_root);
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
2553
  	down_write(&nilfs->ns_segctor_sem);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2554

fdce895ea   Li Hong   nilfs2: change sc...
2555
  	del_timer_sync(&sci->sc_timer);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2556
2557
2558
2559
  	kfree(sci);
  }
  
  /**
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2560
2561
   * nilfs_attach_log_writer - attach log writer
   * @sb: super block instance
e912a5b66   Ryusuke Konishi   nilfs2: use root ...
2562
   * @root: root object of the current filesystem tree
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2563
   *
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2564
2565
   * This allocates a log writer object, initializes it, and starts the
   * log writer.
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2566
2567
2568
2569
2570
2571
   *
   * Return Value: On success, 0 is returned. On error, one of the following
   * negative error code is returned.
   *
   * %-ENOMEM - Insufficient memory available.
   */
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2572
  int nilfs_attach_log_writer(struct super_block *sb, struct nilfs_root *root)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2573
  {
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
2574
  	struct the_nilfs *nilfs = sb->s_fs_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2575
  	int err;
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
2576
  	if (nilfs->ns_writer) {
fe5f171bb   Ryusuke Konishi   nilfs2: fix poten...
2577
2578
2579
2580
2581
  		/*
  		 * This happens if the filesystem was remounted
  		 * read/write after nilfs_error degenerated it into a
  		 * read-only mount.
  		 */
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2582
  		nilfs_detach_log_writer(sb);
fe5f171bb   Ryusuke Konishi   nilfs2: fix poten...
2583
  	}
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2584
  	nilfs->ns_writer = nilfs_segctor_new(sb, root);
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
2585
  	if (!nilfs->ns_writer)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2586
  		return -ENOMEM;
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
2587
  	err = nilfs_segctor_start_thread(nilfs->ns_writer);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2588
  	if (err) {
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
2589
2590
  		kfree(nilfs->ns_writer);
  		nilfs->ns_writer = NULL;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2591
2592
2593
2594
2595
  	}
  	return err;
  }
  
  /**
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2596
2597
   * nilfs_detach_log_writer - destroy log writer
   * @sb: super block instance
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2598
   *
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2599
2600
   * This kills log writer daemon, frees the log writer object, and
   * destroys list of dirty files.
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2601
   */
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2602
  void nilfs_detach_log_writer(struct super_block *sb)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2603
  {
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
2604
  	struct the_nilfs *nilfs = sb->s_fs_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2605
2606
2607
  	LIST_HEAD(garbage_list);
  
  	down_write(&nilfs->ns_segctor_sem);
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
2608
2609
2610
  	if (nilfs->ns_writer) {
  		nilfs_segctor_destroy(nilfs->ns_writer);
  		nilfs->ns_writer = NULL;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2611
2612
2613
  	}
  
  	/* Force to free the list of dirty files */
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
2614
2615
2616
  	spin_lock(&nilfs->ns_inode_lock);
  	if (!list_empty(&nilfs->ns_dirty_files)) {
  		list_splice_init(&nilfs->ns_dirty_files, &garbage_list);
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2617
2618
2619
  		nilfs_warning(sb, __func__,
  			      "Hit dirty file after stopped log writer
  ");
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2620
  	}
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
2621
  	spin_unlock(&nilfs->ns_inode_lock);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2622
  	up_write(&nilfs->ns_segctor_sem);
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
2623
  	nilfs_dispose_list(nilfs, &garbage_list, 1);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2624
  }