Blame view

fs/nilfs2/segment.c 71.5 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;
2c22b337b   Jan Kara   nilfs2: Convert t...
191
  	sb_start_intwrite(sb);
5beb6e0b2   Ryusuke Konishi   nilfs2: add bdev ...
192

e3154e974   Ryusuke Konishi   nilfs2: get rid o...
193
  	nilfs = sb->s_fs_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
194
195
196
197
198
199
200
201
202
203
204
205
206
  	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);
2c22b337b   Jan Kara   nilfs2: Convert t...
207
  	sb_end_intwrite(sb);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
208
209
210
211
  	return ret;
  }
  
  /**
47420c799   Ryusuke Konishi   nilfs2: avoid dou...
212
   * nilfs_transaction_commit - commit indivisible file operations.
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
213
   * @sb: super block
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
214
   *
47420c799   Ryusuke Konishi   nilfs2: avoid dou...
215
216
217
218
219
220
   * 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...
221
   */
47420c799   Ryusuke Konishi   nilfs2: avoid dou...
222
  int nilfs_transaction_commit(struct super_block *sb)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
223
224
  {
  	struct nilfs_transaction_info *ti = current->journal_info;
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
225
  	struct the_nilfs *nilfs = sb->s_fs_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
226
227
228
  	int err = 0;
  
  	BUG_ON(ti == NULL || ti->ti_magic != NILFS_TI_MAGIC);
47420c799   Ryusuke Konishi   nilfs2: avoid dou...
229
  	ti->ti_flags |= NILFS_TI_COMMIT;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
230
231
232
233
  	if (ti->ti_count > 0) {
  		ti->ti_count--;
  		return 0;
  	}
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
234
235
  	if (nilfs->ns_writer) {
  		struct nilfs_sc_info *sci = nilfs->ns_writer;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
236
237
  		if (ti->ti_flags & NILFS_TI_COMMIT)
  			nilfs_segctor_start_timer(sci);
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
238
  		if (atomic_read(&nilfs->ns_ndirtyblks) > sci->sc_watermark)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
239
240
  			nilfs_segctor_do_flush(sci, 0);
  	}
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
241
  	up_read(&nilfs->ns_segctor_sem);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
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);
2c22b337b   Jan Kara   nilfs2: Convert t...
248
  	sb_end_intwrite(sb);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
249
250
  	return err;
  }
47420c799   Ryusuke Konishi   nilfs2: avoid dou...
251
252
253
  void nilfs_transaction_abort(struct super_block *sb)
  {
  	struct nilfs_transaction_info *ti = current->journal_info;
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
254
  	struct the_nilfs *nilfs = sb->s_fs_info;
47420c799   Ryusuke Konishi   nilfs2: avoid dou...
255
256
257
258
259
260
  
  	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...
261
  	up_read(&nilfs->ns_segctor_sem);
47420c799   Ryusuke Konishi   nilfs2: avoid dou...
262
263
264
265
  
  	current->journal_info = ti->ti_save;
  	if (ti->ti_flags & NILFS_TI_DYNAMIC_ALLOC)
  		kmem_cache_free(nilfs_transaction_cachep, ti);
2c22b337b   Jan Kara   nilfs2: Convert t...
266
  	sb_end_intwrite(sb);
47420c799   Ryusuke Konishi   nilfs2: avoid dou...
267
  }
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
268
269
  void nilfs_relax_pressure_in_lock(struct super_block *sb)
  {
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
270
  	struct the_nilfs *nilfs = sb->s_fs_info;
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
271
  	struct nilfs_sc_info *sci = nilfs->ns_writer;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
  
  	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...
290
  static void nilfs_transaction_lock(struct super_block *sb,
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
291
292
293
294
  				   struct nilfs_transaction_info *ti,
  				   int gcflag)
  {
  	struct nilfs_transaction_info *cur_ti = current->journal_info;
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
295
  	struct the_nilfs *nilfs = sb->s_fs_info;
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
296
  	struct nilfs_sc_info *sci = nilfs->ns_writer;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
297

1f5abe7e7   Ryusuke Konishi   nilfs2: replace B...
298
  	WARN_ON(cur_ti);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
299
300
301
302
303
304
305
306
  	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 ...
307
308
  		down_write(&nilfs->ns_segctor_sem);
  		if (!test_bit(NILFS_SC_PRIOR_FLUSH, &sci->sc_flags))
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
309
  			break;
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
310
  		nilfs_segctor_do_immediate_flush(sci);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
311

f7545144c   Ryusuke Konishi   nilfs2: use sb in...
312
  		up_write(&nilfs->ns_segctor_sem);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
313
314
315
316
317
  		yield();
  	}
  	if (gcflag)
  		ti->ti_flags |= NILFS_TI_GC;
  }
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
318
  static void nilfs_transaction_unlock(struct super_block *sb)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
319
320
  {
  	struct nilfs_transaction_info *ti = current->journal_info;
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
321
  	struct the_nilfs *nilfs = sb->s_fs_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
322
323
324
  
  	BUG_ON(ti == NULL || ti->ti_magic != NILFS_TI_MAGIC);
  	BUG_ON(ti->ti_count > 0);
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
325
  	up_write(&nilfs->ns_segctor_sem);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
326
327
  	current->journal_info = ti->ti_save;
  	if (!list_empty(&ti->ti_garbage))
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
328
  		nilfs_dispose_list(nilfs, &ti->ti_garbage, 0);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
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
360
361
362
363
  }
  
  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...
364
  	err = nilfs_segbuf_reset(segbuf, flags, sci->sc_seg_ctime, sci->sc_cno);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
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
393
394
395
396
  	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...
397
  	err = nilfs_segbuf_extend_payload(segbuf, &segbuf->sb_super_root);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
  	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...
425

72746ac64   Ryusuke Konishi   nilfs2: fix regre...
426
427
  	if (NILFS_I(inode)->i_root &&
  	    !test_bit(NILFS_SC_HAVE_DELTA, &sci->sc_flags))
c96fa464a   Ryusuke Konishi   nilfs2: mark mino...
428
  		set_bit(NILFS_SC_HAVE_DELTA, &sci->sc_flags);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
429
430
431
432
433
434
435
436
437
  	/* 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...
438
  	__u64 cno;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
439
440
441
442
443
  
  	if (sci->sc_blk_cnt == 0)
  		return;
  
  	ii = NILFS_I(inode);
6c43f4100   Ryusuke Konishi   nilfs2: keep zero...
444
445
446
447
448
449
450
  
  	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...
451
452
453
454
455
  	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...
456
  	finfo->fi_cno = cpu_to_le64(cno);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
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
495
496
497
498
  
  	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...
499
500
501
502
503
504
505
  /*
   * 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...
506
  	err = nilfs_bmap_propagate(NILFS_I(inode)->i_bmap, bh);
e828949e5   Ryusuke Konishi   nilfs2: call nilf...
507
508
  	if (err < 0)
  		return err;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
509
510
511
512
513
514
515
516
517
518
519
520
  
  	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...
521
  	return nilfs_bmap_propagate(NILFS_I(inode)->i_bmap, bh);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
522
523
524
525
526
527
  }
  
  static int nilfs_collect_file_bmap(struct nilfs_sc_info *sci,
  				   struct buffer_head *bh,
  				   struct inode *inode)
  {
1f5abe7e7   Ryusuke Konishi   nilfs2: replace B...
528
  	WARN_ON(!buffer_dirty(bh));
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
  	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...
549
  static struct nilfs_sc_operations nilfs_sc_file_ops = {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
550
551
552
553
554
555
556
557
558
559
560
561
562
  	.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...
563
564
  	if (err < 0)
  		return err;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
565
566
567
568
569
570
571
572
573
574
  
  	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...
575
  	WARN_ON(!buffer_dirty(bh));
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
  	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...
597
  static struct nilfs_sc_operations nilfs_sc_dat_ops = {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
598
599
600
601
602
603
  	.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...
604
  static struct nilfs_sc_operations nilfs_sc_dsync_ops = {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
605
606
607
608
609
610
  	.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...
611
612
613
614
  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...
615
  {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
616
617
  	struct address_space *mapping = inode->i_mapping;
  	struct pagevec pvec;
f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
618
619
620
  	pgoff_t index = 0, last = ULONG_MAX;
  	size_t ndirties = 0;
  	int i;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
621

f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
622
623
624
625
626
627
628
629
630
  	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...
631
632
  	pagevec_init(&pvec, 0);
   repeat:
f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
633
634
635
636
637
  	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...
638
639
640
641
  
  	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...
642
643
  		if (unlikely(page->index > last))
  			break;
aa405b1f4   Ryusuke Konishi   nilfs2: always se...
644
645
646
647
  		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...
648
649
650
  
  		bh = head = page_buffers(page);
  		do {
7f42ec394   Vyacheslav Dubeyko   nilfs2: fix issue...
651
  			if (!buffer_dirty(bh) || buffer_async_write(bh))
f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
652
653
654
655
656
657
658
659
  				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...
660
  			}
f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
661
  		} while (bh = bh->b_this_page, bh != head);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
662
663
664
  	}
  	pagevec_release(&pvec);
  	cond_resched();
f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
665
  	goto repeat;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
  }
  
  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 {
7f42ec394   Vyacheslav Dubeyko   nilfs2: fix issue...
685
686
  				if (buffer_dirty(bh) &&
  						!buffer_async_write(bh)) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
687
688
689
690
691
692
693
694
695
696
697
  					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...
698
  static void nilfs_dispose_list(struct the_nilfs *nilfs,
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
699
700
701
702
703
704
705
  			       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...
706
  		spin_lock(&nilfs->ns_inode_lock);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
707
708
709
710
711
712
713
714
715
716
  		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...
717
  					      &nilfs->ns_dirty_files);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
718
719
720
721
722
723
  				continue;
  			}
  			ivec[nv++] = ii;
  			if (nv == SC_N_INODEVEC)
  				break;
  		}
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
724
  		spin_unlock(&nilfs->ns_inode_lock);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
725
726
727
728
729
  
  		for (pii = ivec; nv > 0; pii++, nv--)
  			iput(&(*pii)->vfs_inode);
  	}
  }
e912a5b66   Ryusuke Konishi   nilfs2: use root ...
730
731
  static int nilfs_test_metadata_dirty(struct the_nilfs *nilfs,
  				     struct nilfs_root *root)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
732
  {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
733
  	int ret = 0;
e912a5b66   Ryusuke Konishi   nilfs2: use root ...
734
  	if (nilfs_mdt_fetch_dirty(root->ifile))
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
735
736
737
738
739
  		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...
740
741
  	if ((ret || nilfs_doing_gc()) && nilfs_mdt_fetch_dirty(nilfs->ns_dat))
  		ret++;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
742
743
744
745
746
747
748
  	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...
749
  		sci->sc_nfreesegs == 0 &&
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
750
751
752
753
754
  		(!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...
755
  	struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
756
  	int ret = 0;
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
757
  	if (nilfs_test_metadata_dirty(nilfs, sci->sc_root))
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
758
  		set_bit(NILFS_SC_DIRTY, &sci->sc_flags);
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
759
760
  	spin_lock(&nilfs->ns_inode_lock);
  	if (list_empty(&nilfs->ns_dirty_files) && nilfs_segctor_clean(sci))
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
761
  		ret++;
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
762
  	spin_unlock(&nilfs->ns_inode_lock);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
763
764
765
766
767
  	return ret;
  }
  
  static void nilfs_segctor_clear_metadata_dirty(struct nilfs_sc_info *sci)
  {
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
768
  	struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
769

e912a5b66   Ryusuke Konishi   nilfs2: use root ...
770
  	nilfs_mdt_clear_dirty(sci->sc_root->ifile);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
771
772
  	nilfs_mdt_clear_dirty(nilfs->ns_cpfile);
  	nilfs_mdt_clear_dirty(nilfs->ns_sufile);
365e215ce   Ryusuke Konishi   nilfs2: unfold ni...
773
  	nilfs_mdt_clear_dirty(nilfs->ns_dat);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
774
775
776
777
  }
  
  static int nilfs_segctor_create_checkpoint(struct nilfs_sc_info *sci)
  {
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
778
  	struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
779
780
781
782
783
784
785
786
787
788
789
  	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_...
790
  		mark_buffer_dirty(bh_cp);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
791
792
793
  		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...
794
795
  	} else
  		WARN_ON(err == -EINVAL || err == -ENOENT);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
796
797
798
799
800
  	return err;
  }
  
  static int nilfs_segctor_fill_in_checkpoint(struct nilfs_sc_info *sci)
  {
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
801
  	struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
802
803
804
805
806
807
808
  	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...
809
  		WARN_ON(err == -EINVAL || err == -ENOENT);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
810
811
812
813
814
  		goto failed_ibh;
  	}
  	raw_cp->cp_snapshot_list.ssl_next = 0;
  	raw_cp->cp_snapshot_list.ssl_prev = 0;
  	raw_cp->cp_inodes_count =
e5f7f8484   Vyacheslav Dubeyko   ] nilfs2: use ato...
815
  		cpu_to_le64(atomic64_read(&sci->sc_root->inodes_count));
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
816
  	raw_cp->cp_blocks_count =
e5f7f8484   Vyacheslav Dubeyko   ] nilfs2: use ato...
817
  		cpu_to_le64(atomic64_read(&sci->sc_root->blocks_count));
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
818
819
820
821
  	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 ...
822

c96fa464a   Ryusuke Konishi   nilfs2: mark mino...
823
824
825
826
  	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 ...
827
828
  	nilfs_write_inode_common(sci->sc_root->ifile,
  				 &raw_cp->cp_ifile_inode, 1);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
  	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 ...
852
  static void nilfs_segctor_fill_in_file_bmap(struct nilfs_sc_info *sci)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
853
854
855
856
  {
  	struct nilfs_inode_info *ii;
  
  	list_for_each_entry(ii, &sci->sc_dirty_files, i_dirty) {
e912a5b66   Ryusuke Konishi   nilfs2: use root ...
857
  		nilfs_fill_in_file_bmap(sci->sc_root->ifile, ii);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
858
859
  		set_bit(NILFS_I_COLLECTED, &ii->i_state);
  	}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
860
  }
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
861
862
863
  static void nilfs_segctor_fill_in_super_root(struct nilfs_sc_info *sci,
  					     struct the_nilfs *nilfs)
  {
1e2b68bf2   Ryusuke Konishi   nilfs2: move poin...
864
865
  	struct buffer_head *bh_sr;
  	struct nilfs_super_root *raw_sr;
56eb55388   Ryusuke Konishi   nilfs2: zero fill...
866
  	unsigned isz, srsz;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
867

1e2b68bf2   Ryusuke Konishi   nilfs2: move poin...
868
869
  	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...
870
871
  	isz = nilfs->ns_inode_size;
  	srsz = NILFS_SR_BYTES(isz);
1e2b68bf2   Ryusuke Konishi   nilfs2: move poin...
872

56eb55388   Ryusuke Konishi   nilfs2: zero fill...
873
  	raw_sr->sr_bytes = cpu_to_le16(srsz);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
874
875
876
877
  	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...
878
  	nilfs_write_inode_common(nilfs->ns_dat, (void *)raw_sr +
3961f0e27   Ryusuke Konishi   nilfs2: eliminate...
879
880
881
882
883
  				 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...
884
  	memset((void *)raw_sr + srsz, 0, nilfs->ns_blocksize - srsz);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
  }
  
  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...
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
  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_...
932
933
  		bh = list_first_entry(listp, struct buffer_head,
  				      b_assoc_buffers);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
934
935
936
937
938
  		list_del_init(&bh->b_assoc_buffers);
  		brelse(bh);
  	}
  	return err;
  }
f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
939
940
941
942
943
944
  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...
945
946
947
948
949
950
  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...
951
  	int err;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
952
953
  
  	if (!(sci->sc_stage.flags & NILFS_CF_NODE)) {
f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
954
955
956
957
958
959
  		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...
960
  				sci, inode, &data_buffers,
f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
961
962
  				sc_ops->collect_data);
  			BUG_ON(!err); /* always receive -E2BIG or true error */
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
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
997
998
999
1000
1001
  			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...
1002
1003
  	size_t n, rest = nilfs_segctor_buffer_rest(sci);
  	int err;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1004

f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
1005
1006
1007
1008
1009
1010
1011
  	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...
1012
  		nilfs_segctor_end_finfo(sci, inode);
f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
1013
1014
1015
  		BUG_ON(n > rest);
  		/* always receive -E2BIG or true error if n > rest */
  	}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1016
1017
1018
1019
1020
  	return err;
  }
  
  static int nilfs_segctor_collect_blocks(struct nilfs_sc_info *sci, int mode)
  {
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
1021
  	struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1022
1023
  	struct list_head *head;
  	struct nilfs_inode_info *ii;
071cb4b81   Ryusuke Konishi   nilfs2: eliminate...
1024
  	size_t ndone;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
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
1088
1089
1090
1091
1092
  	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...
1093
1094
1095
1096
  		sci->sc_stage.scnt++;
  		sci->sc_stage.flags |= NILFS_CF_IFILE_STARTED;
  		/* Fall through */
  	case NILFS_ST_IFILE:
e912a5b66   Ryusuke Konishi   nilfs2: use root ...
1097
  		err = nilfs_segctor_scan_file(sci, sci->sc_root->ifile,
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
  					      &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...
1114
1115
1116
1117
1118
1119
  		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...
1120
  			break;
071cb4b81   Ryusuke Konishi   nilfs2: eliminate...
1121
1122
  		}
  		sci->sc_stage.flags |= NILFS_CF_SUFREED;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1123
1124
1125
1126
1127
1128
1129
  		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...
1130
  		err = nilfs_segctor_scan_file(sci, nilfs->ns_dat,
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
  					      &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...
1153
  		ii = sci->sc_dsync_inode;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1154
1155
1156
1157
1158
1159
  		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...
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
  		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 ...
1172
1173
1174
1175
1176
  /**
   * 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...
1177
1178
1179
  static int nilfs_segctor_begin_construction(struct nilfs_sc_info *sci,
  					    struct the_nilfs *nilfs)
  {
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1180
  	struct nilfs_segment_buffer *segbuf, *prev;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1181
  	__u64 nextnum;
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1182
  	int err, alloc = 0;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1183

a694291a6   Ryusuke Konishi   nilfs2: separate ...
1184
1185
1186
  	segbuf = nilfs_segbuf_new(sci->sc_super);
  	if (unlikely(!segbuf))
  		return -ENOMEM;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1187

a694291a6   Ryusuke Konishi   nilfs2: separate ...
1188
1189
1190
1191
1192
1193
1194
  	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...
1195

a694291a6   Ryusuke Konishi   nilfs2: separate ...
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
  		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...
1214
  	}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1215

61a189e9c   Ryusuke Konishi   nilfs2: move rout...
1216
  	err = nilfs_sufile_mark_dirty(nilfs->ns_sufile, segbuf->sb_segnum);
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1217
1218
  	if (err)
  		goto failed;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1219

a694291a6   Ryusuke Konishi   nilfs2: separate ...
1220
  	if (alloc) {
cece55207   Ryusuke Konishi   nilfs2: simplify ...
1221
  		err = nilfs_sufile_alloc(nilfs->ns_sufile, &nextnum);
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1222
1223
1224
  		if (err)
  			goto failed;
  	}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1225
  	nilfs_segbuf_set_next_segnum(segbuf, nextnum, nilfs);
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1226
1227
1228
  	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 ...
1229
  	return 0;
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1230
1231
1232
1233
  
   failed:
  	nilfs_segbuf_free(segbuf);
  	return err;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1234
1235
1236
1237
1238
  }
  
  static int nilfs_segctor_extend_segments(struct nilfs_sc_info *sci,
  					 struct the_nilfs *nilfs, int nadd)
  {
e29df395b   Ryusuke Konishi   nilfs2: add itera...
1239
  	struct nilfs_segment_buffer *segbuf, *prev;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
  	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...
1252
  	err = nilfs_sufile_mark_dirty(sufile, prev->sb_nextnum);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
  	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 ...
1264
  		nilfs_segbuf_map(segbuf, prev->sb_nextnum, 0, nilfs);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
  		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_...
1278
  	list_splice_tail(&list, &sci->sc_segbufs);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1279
1280
1281
1282
1283
  	return 0;
  
   failed_segbuf:
  	nilfs_segbuf_free(segbuf);
   failed:
e29df395b   Ryusuke Konishi   nilfs2: add itera...
1284
  	list_for_each_entry(segbuf, &list, sb_list) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1285
  		ret = nilfs_sufile_free(sufile, segbuf->sb_nextnum);
1f5abe7e7   Ryusuke Konishi   nilfs2: replace B...
1286
  		WARN_ON(ret); /* never fails */
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1287
  	}
e29df395b   Ryusuke Konishi   nilfs2: add itera...
1288
  	nilfs_destroy_logs(&list);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1289
1290
  	return err;
  }
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1291
1292
  static void nilfs_free_incomplete_logs(struct list_head *logs,
  				       struct the_nilfs *nilfs)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1293
  {
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1294
1295
  	struct nilfs_segment_buffer *segbuf, *prev;
  	struct inode *sufile = nilfs->ns_sufile;
9284ad2a9   Ryusuke Konishi   nilfs2: relocate ...
1296
  	int ret;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1297

a694291a6   Ryusuke Konishi   nilfs2: separate ...
1298
  	segbuf = NILFS_FIRST_SEGBUF(logs);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1299
  	if (nilfs->ns_nextnum != segbuf->sb_nextnum) {
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1300
  		ret = nilfs_sufile_free(sufile, segbuf->sb_nextnum);
1f5abe7e7   Ryusuke Konishi   nilfs2: replace B...
1301
  		WARN_ON(ret); /* never fails */
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1302
  	}
9284ad2a9   Ryusuke Konishi   nilfs2: relocate ...
1303
  	if (atomic_read(&segbuf->sb_err)) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1304
1305
1306
1307
1308
1309
1310
1311
  		/* 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...
1312
  	}
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1313
1314
1315
1316
1317
1318
  	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 ...
1319
1320
1321
  		if (atomic_read(&segbuf->sb_err) &&
  		    segbuf->sb_segnum != nilfs->ns_nextnum)
  			/* Case 2: extended segment (!= next) failed */
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1322
1323
  			nilfs_sufile_set_error(sufile, segbuf->sb_segnum);
  		prev = segbuf;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1324
  	}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1325
1326
1327
1328
1329
1330
  }
  
  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...
1331
1332
1333
1334
  	unsigned long live_blocks;
  	int ret;
  
  	list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1335
1336
  		live_blocks = segbuf->sb_sum.nblocks +
  			(segbuf->sb_pseg_start - segbuf->sb_fseg_start);
071ec54dd   Ryusuke Konishi   nilfs2: move rout...
1337
1338
1339
1340
  		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...
1341
1342
  	}
  }
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1343
  static void nilfs_cancel_segusage(struct list_head *logs, struct inode *sufile)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1344
1345
  {
  	struct nilfs_segment_buffer *segbuf;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1346
  	int ret;
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1347
  	segbuf = NILFS_FIRST_SEGBUF(logs);
071ec54dd   Ryusuke Konishi   nilfs2: move rout...
1348
1349
1350
1351
  	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...
1352

a694291a6   Ryusuke Konishi   nilfs2: separate ...
1353
  	list_for_each_entry_continue(segbuf, logs, sb_list) {
071ec54dd   Ryusuke Konishi   nilfs2: move rout...
1354
1355
  		ret = nilfs_sufile_set_segment_usage(sufile, segbuf->sb_segnum,
  						     0, 0);
1f5abe7e7   Ryusuke Konishi   nilfs2: replace B...
1356
  		WARN_ON(ret); /* always succeed */
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1357
1358
1359
1360
1361
1362
1363
  	}
  }
  
  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...
1364
  	struct nilfs_segment_buffer *segbuf = last;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1365
  	int ret;
e29df395b   Ryusuke Konishi   nilfs2: add itera...
1366
  	list_for_each_entry_continue(segbuf, &sci->sc_segbufs, sb_list) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1367
1368
  		sci->sc_segbuf_nblocks -= segbuf->sb_rest_blocks;
  		ret = nilfs_sufile_free(sufile, segbuf->sb_nextnum);
1f5abe7e7   Ryusuke Konishi   nilfs2: replace B...
1369
  		WARN_ON(ret);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1370
  	}
e29df395b   Ryusuke Konishi   nilfs2: add itera...
1371
  	nilfs_truncate_logs(&sci->sc_segbufs, last);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
  }
  
  
  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...
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
  		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...
1401
  		nilfs_clear_logs(&sci->sc_segbufs);
071cb4b81   Ryusuke Konishi   nilfs2: eliminate...
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 */
70f2fe3a2   Andreas Rohner   nilfs2: fix segct...
1408
  			sci->sc_stage.flags &= ~NILFS_CF_SUFREED;
071cb4b81   Ryusuke Konishi   nilfs2: eliminate...
1409
  		}
70f2fe3a2   Andreas Rohner   nilfs2: fix segct...
1410
1411
1412
1413
  
  		err = nilfs_segctor_extend_segments(sci, nilfs, nadd);
  		if (unlikely(err))
  			return err;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
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
1452
1453
1454
1455
1456
1457
  		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...
1458
  		if (bh == segbuf->sb_super_root)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1459
1460
1461
1462
1463
1464
1465
  			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...
1466
  			inode = bh->b_page->mapping->host;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
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
1496
1497
1498
1499
1500
1501
  
  			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...
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
  	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...
1518
  static void nilfs_begin_page_io(struct page *page)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1519
1520
1521
1522
  {
  	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...
1523
  		return;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1524
1525
1526
1527
1528
  
  	lock_page(page);
  	clear_page_dirty_for_io(page);
  	set_page_writeback(page);
  	unlock_page(page);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1529
  }
1cb2d38cb   Ryusuke Konishi   nilfs2: get rid o...
1530
  static void nilfs_segctor_prepare_write(struct nilfs_sc_info *sci)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1531
1532
1533
  {
  	struct nilfs_segment_buffer *segbuf;
  	struct page *bd_page = NULL, *fs_page = NULL;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1534

9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1535
1536
1537
1538
1539
  	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) {
7f42ec394   Vyacheslav Dubeyko   nilfs2: fix issue...
1540
  			set_buffer_async_write(bh);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
  			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) {
7f42ec394   Vyacheslav Dubeyko   nilfs2: fix issue...
1554
  			set_buffer_async_write(bh);
1e2b68bf2   Ryusuke Konishi   nilfs2: move poin...
1555
  			if (bh == segbuf->sb_super_root) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
  				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...
1566
  				nilfs_begin_page_io(fs_page);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
  				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...
1577
  	nilfs_begin_page_io(fs_page);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1578
1579
1580
  }
  
  static int nilfs_segctor_write(struct nilfs_sc_info *sci,
9c965bac1   Ryusuke Konishi   nilfs2: hide nilf...
1581
  			       struct the_nilfs *nilfs)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1582
  {
d1c6b72a7   Ryusuke Konishi   nilfs2: move iter...
1583
  	int ret;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1584

d1c6b72a7   Ryusuke Konishi   nilfs2: move iter...
1585
  	ret = nilfs_write_logs(&sci->sc_segbufs, nilfs);
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1586
1587
  	list_splice_tail_init(&sci->sc_segbufs, &sci->sc_write_logs);
  	return ret;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1588
  }
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1589
1590
1591
1592
  static void nilfs_end_page_io(struct page *page, int err)
  {
  	if (!page)
  		return;
a97778457   Ryusuke Konishi   nilfs2: fix oops ...
1593
  	if (buffer_nilfs_node(page_buffers(page)) && !PageWriteback(page)) {
8227b2972   Ryusuke Konishi   nilfs2: fix hang ...
1594
1595
1596
1597
  		/*
  		 * 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 ...
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
  		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...
1611
  		return;
a97778457   Ryusuke Konishi   nilfs2: fix oops ...
1612
  	}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1613

1cb2d38cb   Ryusuke Konishi   nilfs2: get rid o...
1614
1615
1616
1617
1618
1619
1620
  	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...
1621
  	}
1cb2d38cb   Ryusuke Konishi   nilfs2: get rid o...
1622
1623
  
  	end_page_writeback(page);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1624
  }
1cb2d38cb   Ryusuke Konishi   nilfs2: get rid o...
1625
  static void nilfs_abort_logs(struct list_head *logs, int err)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1626
1627
1628
  {
  	struct nilfs_segment_buffer *segbuf;
  	struct page *bd_page = NULL, *fs_page = NULL;
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1629
  	struct buffer_head *bh;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1630

a694291a6   Ryusuke Konishi   nilfs2: separate ...
1631
1632
  	if (list_empty(logs))
  		return;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1633

a694291a6   Ryusuke Konishi   nilfs2: separate ...
1634
  	list_for_each_entry(segbuf, logs, sb_list) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1635
1636
  		list_for_each_entry(bh, &segbuf->sb_segsum_buffers,
  				    b_assoc_buffers) {
7f42ec394   Vyacheslav Dubeyko   nilfs2: fix issue...
1637
  			clear_buffer_async_write(bh);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1638
1639
1640
1641
1642
1643
1644
1645
1646
  			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) {
7f42ec394   Vyacheslav Dubeyko   nilfs2: fix issue...
1647
  			clear_buffer_async_write(bh);
1e2b68bf2   Ryusuke Konishi   nilfs2: move poin...
1648
  			if (bh == segbuf->sb_super_root) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1649
1650
1651
1652
1653
1654
1655
1656
  				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...
1657
1658
1659
1660
1661
1662
1663
1664
  				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 ...
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
  }
  
  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...
1675
  	nilfs_abort_logs(&logs, ret ? : err);
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1676
1677
1678
1679
  
  	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 ...
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
  
  	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...
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
  }
  
  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...
1707
  	struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
1e2b68bf2   Ryusuke Konishi   nilfs2: move poin...
1708
  	int update_sr = false;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1709

a694291a6   Ryusuke Konishi   nilfs2: separate ...
1710
  	list_for_each_entry(segbuf, &sci->sc_write_logs, sb_list) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1711
1712
1713
1714
1715
1716
  		struct buffer_head *bh;
  
  		list_for_each_entry(bh, &segbuf->sb_segsum_buffers,
  				    b_assoc_buffers) {
  			set_buffer_uptodate(bh);
  			clear_buffer_dirty(bh);
7f42ec394   Vyacheslav Dubeyko   nilfs2: fix issue...
1717
  			clear_buffer_async_write(bh);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
  			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);
7f42ec394   Vyacheslav Dubeyko   nilfs2: fix issue...
1739
  			clear_buffer_async_write(bh);
27e6c7a3c   Ryusuke Konishi   nilfs2: mark buff...
1740
  			clear_buffer_delay(bh);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1741
  			clear_buffer_nilfs_volatile(bh);
b1f6a4f29   Ryusuke Konishi   nilfs2: add routi...
1742
  			clear_buffer_nilfs_redirected(bh);
1e2b68bf2   Ryusuke Konishi   nilfs2: move poin...
1743
  			if (bh == segbuf->sb_super_root) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1744
1745
1746
1747
  				if (bh->b_page != bd_page) {
  					end_page_writeback(bd_page);
  					bd_page = bh->b_page;
  				}
1e2b68bf2   Ryusuke Konishi   nilfs2: move poin...
1748
  				update_sr = true;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1749
1750
1751
1752
1753
1754
1755
  				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...
1756
1757
  		if (!nilfs_segbuf_simplex(segbuf)) {
  			if (segbuf->sb_sum.flags & NILFS_SS_LOGBGN) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1758
1759
1760
  				set_bit(NILFS_SC_UNCLOSED, &sci->sc_flags);
  				sci->sc_lseg_stime = jiffies;
  			}
4762077c7   Ryusuke Konishi   nilfs2: get rid o...
1761
  			if (segbuf->sb_sum.flags & NILFS_SS_LOGEND)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
  				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...
1773
  	nilfs_drop_collected_inodes(&sci->sc_dirty_files);
c1c1d7092   Ryusuke Konishi   nilfs2: get rid o...
1774
  	if (nilfs_doing_gc())
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1775
  		nilfs_drop_collected_inodes(&sci->sc_gc_inodes);
c1c1d7092   Ryusuke Konishi   nilfs2: get rid o...
1776
  	else
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1777
  		nilfs->ns_nongc_ctime = sci->sc_seg_ctime;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1778
1779
  
  	sci->sc_nblk_inc += sci->sc_nblk_this_inc;
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1780
  	segbuf = NILFS_LAST_SEGBUF(&sci->sc_write_logs);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1781
1782
1783
1784
  	nilfs_set_next_segment(nilfs, segbuf);
  
  	if (update_sr) {
  		nilfs_set_last_segment(nilfs, segbuf->sb_pseg_start,
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
1785
  				       segbuf->sb_sum.seg_seq, nilfs->ns_cno++);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1786

c96fa464a   Ryusuke Konishi   nilfs2: mark mino...
1787
  		clear_bit(NILFS_SC_HAVE_DELTA, &sci->sc_flags);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1788
1789
  		clear_bit(NILFS_SC_DIRTY, &sci->sc_flags);
  		set_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags);
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1790
  		nilfs_segctor_clear_metadata_dirty(sci);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1791
1792
1793
  	} else
  		clear_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags);
  }
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
  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...
1805
1806
  static int nilfs_segctor_collect_dirty_files(struct nilfs_sc_info *sci,
  					     struct the_nilfs *nilfs)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1807
1808
  {
  	struct nilfs_inode_info *ii, *n;
e912a5b66   Ryusuke Konishi   nilfs2: use root ...
1809
  	struct inode *ifile = sci->sc_root->ifile;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1810

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

9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1842
1843
  	return 0;
  }
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
1844
1845
  static void nilfs_segctor_drop_written_files(struct nilfs_sc_info *sci,
  					     struct the_nilfs *nilfs)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1846
1847
1848
  {
  	struct nilfs_transaction_info *ti = current->journal_info;
  	struct nilfs_inode_info *ii, *n;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1849

693dd3212   Ryusuke Konishi   nilfs2: move s_in...
1850
  	spin_lock(&nilfs->ns_inode_lock);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1851
1852
  	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...
1853
  		    test_bit(NILFS_I_DIRTY, &ii->i_state))
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1854
  			continue;
6c43f4100   Ryusuke Konishi   nilfs2: keep zero...
1855

9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1856
1857
1858
  		clear_bit(NILFS_I_BUSY, &ii->i_state);
  		brelse(ii->i_bh);
  		ii->i_bh = NULL;
eaae0f37d   Nicolas Kaiser   nilfs2: merge lis...
1859
  		list_move_tail(&ii->i_dirty, &ti->ti_garbage);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1860
  	}
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
1861
  	spin_unlock(&nilfs->ns_inode_lock);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1862
1863
1864
  }
  
  /*
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1865
1866
1867
1868
   * 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...
1869
  	struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
1e2b68bf2   Ryusuke Konishi   nilfs2: move poin...
1870
  	int err;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1871
1872
  
  	sci->sc_stage.scnt = NILFS_ST_INIT;
6c43f4100   Ryusuke Konishi   nilfs2: keep zero...
1873
  	sci->sc_cno = nilfs->ns_cno;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1874

693dd3212   Ryusuke Konishi   nilfs2: move s_in...
1875
  	err = nilfs_segctor_collect_dirty_files(sci, nilfs);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1876
1877
  	if (unlikely(err))
  		goto out;
e912a5b66   Ryusuke Konishi   nilfs2: use root ...
1878
  	if (nilfs_test_metadata_dirty(nilfs, sci->sc_root))
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
  		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...
1897
1898
  		/* Avoid empty segment */
  		if (sci->sc_stage.scnt == NILFS_ST_DONE &&
4762077c7   Ryusuke Konishi   nilfs2: get rid o...
1899
  		    nilfs_segbuf_empty(sci->sc_curseg)) {
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1900
  			nilfs_segctor_abort_construction(sci, nilfs, 1);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1901
1902
1903
1904
1905
1906
  			goto out;
  		}
  
  		err = nilfs_segctor_assign(sci, mode);
  		if (unlikely(err))
  			goto failed;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1907
  		if (sci->sc_stage.flags & NILFS_CF_IFILE_STARTED)
e912a5b66   Ryusuke Konishi   nilfs2: use root ...
1908
  			nilfs_segctor_fill_in_file_bmap(sci);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1909

1e2b68bf2   Ryusuke Konishi   nilfs2: move poin...
1910
1911
  		if (mode == SC_LSEG_SR &&
  		    sci->sc_stage.scnt >= NILFS_ST_CPFILE) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1912
1913
  			err = nilfs_segctor_fill_in_checkpoint(sci);
  			if (unlikely(err))
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1914
  				goto failed_to_write;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1915
1916
1917
1918
1919
1920
  
  			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...
1921
  		nilfs_segctor_prepare_write(sci);
aaed1d5bf   Ryusuke Konishi   nilfs2: move out ...
1922
1923
1924
  
  		nilfs_add_checksums_on_logs(&sci->sc_segbufs,
  					    nilfs->ns_crc_seed);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1925

9c965bac1   Ryusuke Konishi   nilfs2: hide nilf...
1926
  		err = nilfs_segctor_write(sci, nilfs);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1927
1928
  		if (unlikely(err))
  			goto failed_to_write;
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
  		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...
1942
  	} while (sci->sc_stage.scnt != NILFS_ST_DONE);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1943
   out:
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
1944
  	nilfs_segctor_drop_written_files(sci, nilfs);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1945
1946
1947
  	return err;
  
   failed_to_write:
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1948
1949
  	if (sci->sc_stage.flags & NILFS_CF_IFILE_STARTED)
  		nilfs_redirty_inodes(&sci->sc_dirty_files);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1950
1951
1952
1953
  
   failed:
  	if (nilfs_doing_gc())
  		nilfs_redirty_inodes(&sci->sc_gc_inodes);
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1954
  	nilfs_segctor_abort_construction(sci, nilfs, err);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1955
1956
1957
1958
  	goto out;
  }
  
  /**
9ccf56c13   Ryusuke Konishi   nilfs2: fix funct...
1959
   * nilfs_segctor_start_timer - set timer of background write
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1960
1961
1962
1963
1964
1965
1966
1967
1968
   * @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...
1969
1970
1971
  	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...
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
  		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...
1997
  	struct the_nilfs *nilfs = sb->s_fs_info;
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
1998
  	struct nilfs_sc_info *sci = nilfs->ns_writer;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1999
2000
2001
2002
2003
2004
  
  	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...
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
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
  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...
2086
  	struct the_nilfs *nilfs = sb->s_fs_info;
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
2087
  	struct nilfs_sc_info *sci = nilfs->ns_writer;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
  	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...
2104
2105
2106
   * @inode: inode whose data blocks should be written out
   * @start: start byte offset
   * @end: end byte offset (inclusive)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
   *
   * 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...
2121
2122
  int nilfs_construct_dsync_segment(struct super_block *sb, struct inode *inode,
  				  loff_t start, loff_t end)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2123
  {
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
2124
  	struct the_nilfs *nilfs = sb->s_fs_info;
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
2125
  	struct nilfs_sc_info *sci = nilfs->ns_writer;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2126
2127
2128
2129
2130
2131
  	struct nilfs_inode_info *ii;
  	struct nilfs_transaction_info ti;
  	int err = 0;
  
  	if (!sci)
  		return -EROFS;
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2132
  	nilfs_transaction_lock(sb, &ti, 0);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2133
2134
2135
  
  	ii = NILFS_I(inode);
  	if (test_bit(NILFS_I_INODE_DIRTY, &ii->i_state) ||
3b2ce58b0   Ryusuke Konishi   nilfs2: move moun...
2136
  	    nilfs_test_opt(nilfs, STRICT_ORDER) ||
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2137
  	    test_bit(NILFS_SC_UNCLOSED, &sci->sc_flags) ||
3b2ce58b0   Ryusuke Konishi   nilfs2: move moun...
2138
  	    nilfs_discontinued(nilfs)) {
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2139
  		nilfs_transaction_unlock(sb);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2140
2141
2142
  		err = nilfs_segctor_sync(sci);
  		return err;
  	}
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
2143
  	spin_lock(&nilfs->ns_inode_lock);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2144
2145
  	if (!test_bit(NILFS_I_QUEUED, &ii->i_state) &&
  	    !test_bit(NILFS_I_BUSY, &ii->i_state)) {
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
2146
  		spin_unlock(&nilfs->ns_inode_lock);
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2147
  		nilfs_transaction_unlock(sb);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2148
2149
  		return 0;
  	}
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
2150
  	spin_unlock(&nilfs->ns_inode_lock);
f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
2151
2152
2153
  	sci->sc_dsync_inode = ii;
  	sci->sc_dsync_start = start;
  	sci->sc_dsync_end = end;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2154
2155
  
  	err = nilfs_segctor_do_construct(sci, SC_LSEG_DSYNC);
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2156
  	nilfs_transaction_unlock(sb);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2157
2158
  	return err;
  }
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2159
2160
  #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...
2161
2162
2163
2164
2165
  /**
   * 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...
2166
  {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2167
  	spin_lock(&sci->sc_state_lock);
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2168
  	sci->sc_seq_accepted = sci->sc_seq_request;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2169
  	spin_unlock(&sci->sc_state_lock);
fdce895ea   Li Hong   nilfs2: change sc...
2170
  	del_timer_sync(&sci->sc_timer);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2171
  }
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2172
2173
2174
2175
2176
2177
2178
  /**
   * 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...
2179
2180
2181
  {
  	/* Clear requests (even when the construction failed) */
  	spin_lock(&sci->sc_state_lock);
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2182
  	if (mode == SC_LSEG_SR) {
aeda7f634   Ryusuke Konishi   nilfs2: fix irreg...
2183
  		sci->sc_state &= ~NILFS_SEGCTOR_COMMIT;
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2184
2185
  		sci->sc_seq_done = sci->sc_seq_accepted;
  		nilfs_segctor_wakeup(sci, err);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2186
  		sci->sc_flush_request = 0;
aeda7f634   Ryusuke Konishi   nilfs2: fix irreg...
2187
  	} else {
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2188
  		if (mode == SC_FLUSH_FILE)
aeda7f634   Ryusuke Konishi   nilfs2: fix irreg...
2189
  			sci->sc_flush_request &= ~FLUSH_FILE_BIT;
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2190
  		else if (mode == SC_FLUSH_DAT)
aeda7f634   Ryusuke Konishi   nilfs2: fix irreg...
2191
2192
2193
  			sci->sc_flush_request &= ~FLUSH_DAT_BIT;
  
  		/* re-enable timer if checkpoint creation was not done */
fdce895ea   Li Hong   nilfs2: change sc...
2194
2195
2196
  		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...
2197
  	}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2198
2199
  	spin_unlock(&sci->sc_state_lock);
  }
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2200
2201
2202
2203
2204
2205
  /**
   * 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...
2206
  {
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
2207
  	struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
d26493b6f   Jiro SEKIBA   nilfs2: introduce...
2208
  	struct nilfs_super_block **sbp;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2209
  	int err = 0;
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2210
  	nilfs_segctor_accept(sci);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2211
  	if (nilfs_discontinued(nilfs))
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2212
2213
2214
  		mode = SC_LSEG_SR;
  	if (!nilfs_segctor_confirm(sci))
  		err = nilfs_segctor_do_construct(sci, mode);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2215
  	if (likely(!err)) {
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2216
  		if (mode != SC_FLUSH_DAT)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2217
2218
2219
2220
  			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...
2221
  			err = -EIO;
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2222
  			sbp = nilfs_prepare_super(sci->sc_super,
b2ac86e1a   Jiro SEKIBA   nilfs2: sync supe...
2223
2224
2225
  						  nilfs_sb_will_flip(nilfs));
  			if (likely(sbp)) {
  				nilfs_set_log_cursor(sbp[0], nilfs);
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2226
2227
  				err = nilfs_commit_super(sci->sc_super,
  							 NILFS_SB_COMMIT);
b2ac86e1a   Jiro SEKIBA   nilfs2: sync supe...
2228
  			}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2229
2230
2231
  			up_write(&nilfs->ns_sem);
  		}
  	}
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2232
2233
  
  	nilfs_segctor_notify(sci, mode, err);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
  	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...
2251
  		list_del_init(&ii->i_dirty);
fbb24a3a9   Ryusuke Konishi   nilfs2: ensure pr...
2252
2253
  		truncate_inode_pages(&ii->vfs_inode.i_data, 0);
  		nilfs_btnode_cache_clear(&ii->i_btnode_cache);
263d90cef   Ryusuke Konishi   nilfs2: remove ow...
2254
  		iput(&ii->vfs_inode);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2255
2256
  	}
  }
4f6b82883   Ryusuke Konishi   nilfs2: fix lock ...
2257
2258
  int nilfs_clean_segments(struct super_block *sb, struct nilfs_argv *argv,
  			 void **kbufs)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2259
  {
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
2260
  	struct the_nilfs *nilfs = sb->s_fs_info;
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
2261
  	struct nilfs_sc_info *sci = nilfs->ns_writer;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2262
  	struct nilfs_transaction_info ti;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2263
2264
2265
2266
  	int err;
  
  	if (unlikely(!sci))
  		return -EROFS;
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2267
  	nilfs_transaction_lock(sb, &ti, 1);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2268

c1c1d7092   Ryusuke Konishi   nilfs2: get rid o...
2269
  	err = nilfs_mdt_save_to_shadow_map(nilfs->ns_dat);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2270
2271
  	if (unlikely(err))
  		goto out_unlock;
071cb4b81   Ryusuke Konishi   nilfs2: eliminate...
2272

4f6b82883   Ryusuke Konishi   nilfs2: fix lock ...
2273
  	err = nilfs_ioctl_prepare_clean_segments(nilfs, argv, kbufs);
c1c1d7092   Ryusuke Konishi   nilfs2: get rid o...
2274
2275
  	if (unlikely(err)) {
  		nilfs_mdt_restore_from_shadow_map(nilfs->ns_dat);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2276
  		goto out_unlock;
c1c1d7092   Ryusuke Konishi   nilfs2: get rid o...
2277
  	}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2278

071cb4b81   Ryusuke Konishi   nilfs2: eliminate...
2279
2280
  	sci->sc_freesegs = kbufs[4];
  	sci->sc_nfreesegs = argv[4].v_nmembs;
0935db747   Ryusuke Konishi   nilfs2: use list_...
2281
  	list_splice_tail_init(&nilfs->ns_gc_inodes, &sci->sc_gc_inodes);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2282
2283
  
  	for (;;) {
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2284
  		err = nilfs_segctor_construct(sci, SC_LSEG_SR);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2285
  		nilfs_remove_written_gcinodes(nilfs, &sci->sc_gc_inodes);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2286
2287
2288
2289
2290
2291
2292
2293
2294
  
  		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...
2295
  	if (nilfs_test_opt(nilfs, DISCARD)) {
e902ec990   Jiro SEKIBA   nilfs2: issue dis...
2296
2297
2298
2299
2300
2301
2302
  		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...
2303
  			nilfs_clear_opt(nilfs, DISCARD);
e902ec990   Jiro SEKIBA   nilfs2: issue dis...
2304
2305
  		}
  	}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2306
2307
  
   out_unlock:
071cb4b81   Ryusuke Konishi   nilfs2: eliminate...
2308
2309
  	sci->sc_freesegs = NULL;
  	sci->sc_nfreesegs = 0;
c1c1d7092   Ryusuke Konishi   nilfs2: get rid o...
2310
  	nilfs_mdt_clear_shadow_map(nilfs->ns_dat);
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2311
  	nilfs_transaction_unlock(sb);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2312
2313
2314
2315
2316
  	return err;
  }
  
  static void nilfs_segctor_thread_construct(struct nilfs_sc_info *sci, int mode)
  {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2317
  	struct nilfs_transaction_info ti;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2318

f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2319
  	nilfs_transaction_lock(sci->sc_super, &ti, 0);
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2320
  	nilfs_segctor_construct(sci, mode);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2321
2322
2323
2324
2325
2326
2327
2328
  
  	/*
  	 * 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...
2329
  	nilfs_transaction_unlock(sci->sc_super);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
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
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
  }
  
  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...
2375
  	struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2376
  	int timeout = 0;
fdce895ea   Li Hong   nilfs2: change sc...
2377
2378
  	sci->sc_timer.data = (unsigned long)current;
  	sci->sc_timer.function = nilfs_construction_timeout;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
  
  	/* 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...
2413
  		try_to_freeze();
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
  		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...
2428
  					sci->sc_timer.expires);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2429
2430
2431
2432
2433
2434
2435
2436
  
  		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...
2437
  			   time_after_eq(jiffies, sci->sc_timer.expires));
e605f0a72   Ryusuke Konishi   nilfs2: get rid o...
2438
2439
  
  		if (nilfs_sb_dirty(nilfs) && nilfs_sb_need_update(nilfs))
1dfa27105   Jiro SEKIBA   nilfs2: stop usin...
2440
  			set_nilfs_discontinued(nilfs);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2441
2442
2443
2444
2445
  	}
  	goto loop;
  
   end_thread:
  	spin_unlock(&sci->sc_state_lock);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
  
  	/* 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...
2471
2472
  	__acquires(&sci->sc_state_lock)
  	__releases(&sci->sc_state_lock)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
  {
  	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...
2483
2484
2485
  /*
   * Setup & clean-up functions
   */
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2486
  static struct nilfs_sc_info *nilfs_segctor_new(struct super_block *sb,
e912a5b66   Ryusuke Konishi   nilfs2: use root ...
2487
  					       struct nilfs_root *root)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2488
  {
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
2489
  	struct the_nilfs *nilfs = sb->s_fs_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2490
2491
2492
2493
2494
  	struct nilfs_sc_info *sci;
  
  	sci = kzalloc(sizeof(*sci), GFP_KERNEL);
  	if (!sci)
  		return NULL;
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2495
  	sci->sc_super = sb;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2496

e912a5b66   Ryusuke Konishi   nilfs2: use root ...
2497
2498
  	nilfs_get_root(root);
  	sci->sc_root = root;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2499
2500
2501
2502
2503
2504
  	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 ...
2505
  	INIT_LIST_HEAD(&sci->sc_write_logs);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2506
  	INIT_LIST_HEAD(&sci->sc_gc_inodes);
fdce895ea   Li Hong   nilfs2: change sc...
2507
  	init_timer(&sci->sc_timer);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2508
2509
2510
2511
  
  	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...
2512
  	if (nilfs->ns_interval)
071d73cfe   Ryusuke Konishi   nilfs2: fix probl...
2513
  		sci->sc_interval = HZ * nilfs->ns_interval;
574e6c314   Ryusuke Konishi   nilfs2: move para...
2514
2515
  	if (nilfs->ns_watermark)
  		sci->sc_watermark = nilfs->ns_watermark;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
  	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...
2526
  		struct nilfs_transaction_info ti;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2527

f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2528
  		nilfs_transaction_lock(sci->sc_super, &ti, 0);
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2529
  		ret = nilfs_segctor_construct(sci, SC_LSEG_SR);
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2530
  		nilfs_transaction_unlock(sci->sc_super);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
  
  	} 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...
2545
  	struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2546
  	int flag;
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
2547
  	up_write(&nilfs->ns_segctor_sem);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2548
2549
2550
2551
2552
2553
  
  	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...
2554
  	if (flag || !nilfs_segctor_confirm(sci))
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2555
  		nilfs_segctor_write_out(sci);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2556
  	if (!list_empty(&sci->sc_dirty_files)) {
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
2557
  		nilfs_warning(sci->sc_super, __func__,
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2558
2559
  			      "dirty file(s) after the final construction
  ");
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
2560
  		nilfs_dispose_list(nilfs, &sci->sc_dirty_files, 1);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2561
  	}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2562

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

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

fdce895ea   Li Hong   nilfs2: change sc...
2569
  	del_timer_sync(&sci->sc_timer);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2570
2571
2572
2573
  	kfree(sci);
  }
  
  /**
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2574
2575
   * nilfs_attach_log_writer - attach log writer
   * @sb: super block instance
e912a5b66   Ryusuke Konishi   nilfs2: use root ...
2576
   * @root: root object of the current filesystem tree
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2577
   *
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2578
2579
   * This allocates a log writer object, initializes it, and starts the
   * log writer.
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2580
2581
2582
2583
2584
2585
   *
   * 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...
2586
  int nilfs_attach_log_writer(struct super_block *sb, struct nilfs_root *root)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2587
  {
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
2588
  	struct the_nilfs *nilfs = sb->s_fs_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2589
  	int err;
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
2590
  	if (nilfs->ns_writer) {
fe5f171bb   Ryusuke Konishi   nilfs2: fix poten...
2591
2592
2593
2594
2595
  		/*
  		 * 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...
2596
  		nilfs_detach_log_writer(sb);
fe5f171bb   Ryusuke Konishi   nilfs2: fix poten...
2597
  	}
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2598
  	nilfs->ns_writer = nilfs_segctor_new(sb, root);
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
2599
  	if (!nilfs->ns_writer)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2600
  		return -ENOMEM;
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
2601
  	err = nilfs_segctor_start_thread(nilfs->ns_writer);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2602
  	if (err) {
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
2603
2604
  		kfree(nilfs->ns_writer);
  		nilfs->ns_writer = NULL;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2605
2606
2607
2608
2609
  	}
  	return err;
  }
  
  /**
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2610
2611
   * nilfs_detach_log_writer - destroy log writer
   * @sb: super block instance
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2612
   *
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2613
2614
   * This kills log writer daemon, frees the log writer object, and
   * destroys list of dirty files.
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2615
   */
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2616
  void nilfs_detach_log_writer(struct super_block *sb)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2617
  {
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
2618
  	struct the_nilfs *nilfs = sb->s_fs_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2619
2620
2621
  	LIST_HEAD(garbage_list);
  
  	down_write(&nilfs->ns_segctor_sem);
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
2622
2623
2624
  	if (nilfs->ns_writer) {
  		nilfs_segctor_destroy(nilfs->ns_writer);
  		nilfs->ns_writer = NULL;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2625
2626
2627
  	}
  
  	/* Force to free the list of dirty files */
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
2628
2629
2630
  	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...
2631
2632
2633
  		nilfs_warning(sb, __func__,
  			      "Hit dirty file after stopped log writer
  ");
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2634
  	}
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
2635
  	spin_unlock(&nilfs->ns_inode_lock);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2636
  	up_write(&nilfs->ns_segctor_sem);
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
2637
  	nilfs_dispose_list(nilfs, &garbage_list, 1);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2638
  }