Blame view

fs/nilfs2/segment.c 74.7 KB
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  /*
   * 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.
   *
4b420ab4e   Ryusuke Konishi   nilfs2: clean up ...
16
   * Written by Ryusuke Konishi.
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
17
18
19
20
21
22
   *
   */
  
  #include <linux/pagemap.h>
  #include <linux/buffer_head.h>
  #include <linux/writeback.h>
ead8ecffa   Ryusuke Konishi   nilfs2: use set_m...
23
  #include <linux/bitops.h>
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
24
25
26
27
28
29
30
31
  #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: ...
32
  #include <linux/slab.h>
174cd4b1e   Ingo Molnar   sched/headers: Pr...
33
  #include <linux/sched/signal.h>
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
34
35
36
37
38
39
40
  #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...
41
42
43
44
45
46
47
  #include "segbuf.h"
  
  
  /*
   * Segment constructor
   */
  #define SC_N_INODEVEC	16   /* Size of locally allocated inode vector */
076a378ba   Ryusuke Konishi   nilfs2: fix block...
48
49
50
51
  #define SC_MAX_SEGDELTA 64   /*
  			      * Upper limit of the number of segments
  			      * appended in collection retry loop
  			      */
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
52
53
54
55
  
  /* Construction mode */
  enum {
  	SC_LSEG_SR = 1,	/* Make a logical segment having a super root */
076a378ba   Ryusuke Konishi   nilfs2: fix block...
56
57
58
59
60
61
62
63
64
65
66
67
  	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.
  			 */
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
68
69
70
71
72
73
74
  };
  
  /* 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...
75
76
77
78
79
80
81
82
  	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,
  };
584977038   Hitoshi Mitake   nilfs2: add a tra...
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
  #define CREATE_TRACE_POINTS
  #include <trace/events/nilfs2.h>
  
  /*
   * nilfs_sc_cstage_inc(), nilfs_sc_cstage_set(), nilfs_sc_cstage_get() are
   * wrapper functions of stage count (nilfs_sc_info->sc_stage.scnt). Users of
   * the variable must use them because transition of stage count must involve
   * trace events (trace_nilfs2_collection_stage_transition).
   *
   * nilfs_sc_cstage_get() isn't required for the above purpose because it doesn't
   * produce tracepoint events. It is provided just for making the intention
   * clear.
   */
  static inline void nilfs_sc_cstage_inc(struct nilfs_sc_info *sci)
  {
  	sci->sc_stage.scnt++;
  	trace_nilfs2_collection_stage_transition(sci);
  }
  
  static inline void nilfs_sc_cstage_set(struct nilfs_sc_info *sci, int next_scnt)
  {
  	sci->sc_stage.scnt = next_scnt;
  	trace_nilfs2_collection_stage_transition(sci);
  }
  
  static inline int nilfs_sc_cstage_get(struct nilfs_sc_info *sci)
  {
  	return sci->sc_stage.scnt;
  }
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
112
113
114
  /* 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...
115
116
  #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...
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
  
  /* 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...
140
  static void nilfs_dispose_list(struct the_nilfs *, struct list_head *, int);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
141
142
143
144
145
146
147
148
149
  
  #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)
feee880fa   Ryusuke Konishi   nilfs2: reduce ba...
150
151
  static int nilfs_prepare_segment_lock(struct super_block *sb,
  				      struct nilfs_transaction_info *ti)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
152
153
154
155
156
157
158
  {
  	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;
7f00184e9   Ryusuke Konishi   nilfs2: remove un...
159
160
161
162
163
164
  
  		/*
  		 * If journal_info field is occupied by other FS,
  		 * it is saved and will be restored on
  		 * nilfs_transaction_commit().
  		 */
feee880fa   Ryusuke Konishi   nilfs2: reduce ba...
165
  		nilfs_msg(sb, KERN_WARNING, "journal info from a different FS");
7f00184e9   Ryusuke Konishi   nilfs2: remove un...
166
  		save = current->journal_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
  	}
  	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...
191
   * exclusive.  The function is used with nilfs_transaction_commit() in pairs.
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
192
193
194
195
196
197
   * 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...
198
   * instead; otherwise a new struct is assigned from a slab.
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
199
200
201
202
203
204
205
206
207
   *
   * 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...
208
209
210
211
212
213
   * %-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...
214
  	struct the_nilfs *nilfs;
feee880fa   Ryusuke Konishi   nilfs2: reduce ba...
215
  	int ret = nilfs_prepare_segment_lock(sb, ti);
44fda1146   Hitoshi Mitake   nilfs2: add a tra...
216
  	struct nilfs_transaction_info *trace_ti;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
217
218
219
  
  	if (unlikely(ret < 0))
  		return ret;
44fda1146   Hitoshi Mitake   nilfs2: add a tra...
220
221
222
223
224
225
  	if (ret > 0) {
  		trace_ti = current->journal_info;
  
  		trace_nilfs2_transaction_transition(sb, trace_ti,
  				    trace_ti->ti_count, trace_ti->ti_flags,
  				    TRACE_NILFS2_TRANSACTION_BEGIN);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
226
  		return 0;
44fda1146   Hitoshi Mitake   nilfs2: add a tra...
227
  	}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
228

2c22b337b   Jan Kara   nilfs2: Convert t...
229
  	sb_start_intwrite(sb);
5beb6e0b2   Ryusuke Konishi   nilfs2: add bdev ...
230

e3154e974   Ryusuke Konishi   nilfs2: get rid o...
231
  	nilfs = sb->s_fs_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
232
233
234
235
236
237
  	down_read(&nilfs->ns_segctor_sem);
  	if (vacancy_check && nilfs_near_disk_full(nilfs)) {
  		up_read(&nilfs->ns_segctor_sem);
  		ret = -ENOSPC;
  		goto failed;
  	}
44fda1146   Hitoshi Mitake   nilfs2: add a tra...
238
239
240
241
242
  
  	trace_ti = current->journal_info;
  	trace_nilfs2_transaction_transition(sb, trace_ti, trace_ti->ti_count,
  					    trace_ti->ti_flags,
  					    TRACE_NILFS2_TRANSACTION_BEGIN);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
243
244
245
246
247
248
249
  	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...
250
  	sb_end_intwrite(sb);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
251
252
253
254
  	return ret;
  }
  
  /**
47420c799   Ryusuke Konishi   nilfs2: avoid dou...
255
   * nilfs_transaction_commit - commit indivisible file operations.
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
256
   * @sb: super block
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
257
   *
47420c799   Ryusuke Konishi   nilfs2: avoid dou...
258
259
260
261
262
263
   * 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...
264
   */
47420c799   Ryusuke Konishi   nilfs2: avoid dou...
265
  int nilfs_transaction_commit(struct super_block *sb)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
266
267
  {
  	struct nilfs_transaction_info *ti = current->journal_info;
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
268
  	struct the_nilfs *nilfs = sb->s_fs_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
269
270
271
  	int err = 0;
  
  	BUG_ON(ti == NULL || ti->ti_magic != NILFS_TI_MAGIC);
47420c799   Ryusuke Konishi   nilfs2: avoid dou...
272
  	ti->ti_flags |= NILFS_TI_COMMIT;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
273
274
  	if (ti->ti_count > 0) {
  		ti->ti_count--;
44fda1146   Hitoshi Mitake   nilfs2: add a tra...
275
276
  		trace_nilfs2_transaction_transition(sb, ti, ti->ti_count,
  			    ti->ti_flags, TRACE_NILFS2_TRANSACTION_COMMIT);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
277
278
  		return 0;
  	}
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
279
280
  	if (nilfs->ns_writer) {
  		struct nilfs_sc_info *sci = nilfs->ns_writer;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
281
282
  		if (ti->ti_flags & NILFS_TI_COMMIT)
  			nilfs_segctor_start_timer(sci);
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
283
  		if (atomic_read(&nilfs->ns_ndirtyblks) > sci->sc_watermark)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
284
285
  			nilfs_segctor_do_flush(sci, 0);
  	}
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
286
  	up_read(&nilfs->ns_segctor_sem);
44fda1146   Hitoshi Mitake   nilfs2: add a tra...
287
288
  	trace_nilfs2_transaction_transition(sb, ti, ti->ti_count,
  			    ti->ti_flags, TRACE_NILFS2_TRANSACTION_COMMIT);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
289
290
291
292
293
294
  	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...
295
  	sb_end_intwrite(sb);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
296
297
  	return err;
  }
47420c799   Ryusuke Konishi   nilfs2: avoid dou...
298
299
300
  void nilfs_transaction_abort(struct super_block *sb)
  {
  	struct nilfs_transaction_info *ti = current->journal_info;
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
301
  	struct the_nilfs *nilfs = sb->s_fs_info;
47420c799   Ryusuke Konishi   nilfs2: avoid dou...
302
303
304
305
  
  	BUG_ON(ti == NULL || ti->ti_magic != NILFS_TI_MAGIC);
  	if (ti->ti_count > 0) {
  		ti->ti_count--;
44fda1146   Hitoshi Mitake   nilfs2: add a tra...
306
307
  		trace_nilfs2_transaction_transition(sb, ti, ti->ti_count,
  			    ti->ti_flags, TRACE_NILFS2_TRANSACTION_ABORT);
47420c799   Ryusuke Konishi   nilfs2: avoid dou...
308
309
  		return;
  	}
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
310
  	up_read(&nilfs->ns_segctor_sem);
47420c799   Ryusuke Konishi   nilfs2: avoid dou...
311

44fda1146   Hitoshi Mitake   nilfs2: add a tra...
312
313
  	trace_nilfs2_transaction_transition(sb, ti, ti->ti_count,
  		    ti->ti_flags, TRACE_NILFS2_TRANSACTION_ABORT);
47420c799   Ryusuke Konishi   nilfs2: avoid dou...
314
315
316
  	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...
317
  	sb_end_intwrite(sb);
47420c799   Ryusuke Konishi   nilfs2: avoid dou...
318
  }
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
319
320
  void nilfs_relax_pressure_in_lock(struct super_block *sb)
  {
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
321
  	struct the_nilfs *nilfs = sb->s_fs_info;
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
322
  	struct nilfs_sc_info *sci = nilfs->ns_writer;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
  
  	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...
341
  static void nilfs_transaction_lock(struct super_block *sb,
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
342
343
344
345
  				   struct nilfs_transaction_info *ti,
  				   int gcflag)
  {
  	struct nilfs_transaction_info *cur_ti = current->journal_info;
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
346
  	struct the_nilfs *nilfs = sb->s_fs_info;
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
347
  	struct nilfs_sc_info *sci = nilfs->ns_writer;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
348

1f5abe7e7   Ryusuke Konishi   nilfs2: replace B...
349
  	WARN_ON(cur_ti);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
350
351
352
353
  	ti->ti_flags = NILFS_TI_WRITER;
  	ti->ti_count = 0;
  	ti->ti_save = cur_ti;
  	ti->ti_magic = NILFS_TI_MAGIC;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
354
355
356
  	current->journal_info = ti;
  
  	for (;;) {
44fda1146   Hitoshi Mitake   nilfs2: add a tra...
357
358
  		trace_nilfs2_transaction_transition(sb, ti, ti->ti_count,
  			    ti->ti_flags, TRACE_NILFS2_TRANSACTION_TRYLOCK);
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
359
360
  		down_write(&nilfs->ns_segctor_sem);
  		if (!test_bit(NILFS_SC_PRIOR_FLUSH, &sci->sc_flags))
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
361
  			break;
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
362
  		nilfs_segctor_do_immediate_flush(sci);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
363

f7545144c   Ryusuke Konishi   nilfs2: use sb in...
364
  		up_write(&nilfs->ns_segctor_sem);
aceb4170b   Ryusuke Konishi   nilfs2: do not us...
365
  		cond_resched();
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
366
367
368
  	}
  	if (gcflag)
  		ti->ti_flags |= NILFS_TI_GC;
44fda1146   Hitoshi Mitake   nilfs2: add a tra...
369
370
371
  
  	trace_nilfs2_transaction_transition(sb, ti, ti->ti_count,
  			    ti->ti_flags, TRACE_NILFS2_TRANSACTION_LOCK);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
372
  }
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
373
  static void nilfs_transaction_unlock(struct super_block *sb)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
374
375
  {
  	struct nilfs_transaction_info *ti = current->journal_info;
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
376
  	struct the_nilfs *nilfs = sb->s_fs_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
377
378
379
  
  	BUG_ON(ti == NULL || ti->ti_magic != NILFS_TI_MAGIC);
  	BUG_ON(ti->ti_count > 0);
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
380
  	up_write(&nilfs->ns_segctor_sem);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
381
  	current->journal_info = ti->ti_save;
44fda1146   Hitoshi Mitake   nilfs2: add a tra...
382
383
384
  
  	trace_nilfs2_transaction_transition(sb, ti, ti->ti_count,
  			    ti->ti_flags, TRACE_NILFS2_TRANSACTION_UNLOCK);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
385
386
387
388
  }
  
  static void *nilfs_segctor_map_segsum_entry(struct nilfs_sc_info *sci,
  					    struct nilfs_segsum_pointer *ssp,
0c6c44cb9   Ryusuke Konishi   nilfs2: avoid bar...
389
  					    unsigned int bytes)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
390
391
  {
  	struct nilfs_segment_buffer *segbuf = sci->sc_curseg;
0c6c44cb9   Ryusuke Konishi   nilfs2: avoid bar...
392
  	unsigned int blocksize = sci->sc_super->s_blocksize;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
  	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;
0c6c44cb9   Ryusuke Konishi   nilfs2: avoid bar...
414
415
  	unsigned int sumbytes;
  	unsigned int flags = 0;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
416
417
418
419
  	int err;
  
  	if (nilfs_doing_gc())
  		flags = NILFS_SS_GC;
6c43f4100   Ryusuke Konishi   nilfs2: keep zero...
420
  	err = nilfs_segbuf_reset(segbuf, flags, sci->sc_seg_ctime, sci->sc_cno);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
  	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))
076a378ba   Ryusuke Konishi   nilfs2: fix block...
436
437
438
439
  		return -E2BIG; /*
  				* The current segment is filled up
  				* (internal code)
  				*/
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
  	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...
455
  	err = nilfs_segbuf_extend_payload(segbuf, &segbuf->sb_super_root);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
456
457
458
459
460
461
462
463
464
465
  	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,
0c6c44cb9   Ryusuke Konishi   nilfs2: avoid bar...
466
  	unsigned int binfo_size)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
467
  {
0c6c44cb9   Ryusuke Konishi   nilfs2: avoid bar...
468
  	unsigned int blocksize = sci->sc_super->s_blocksize;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
469
470
471
472
473
474
475
476
477
478
479
480
481
482
  	/* 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...
483

72746ac64   Ryusuke Konishi   nilfs2: fix regre...
484
485
  	if (NILFS_I(inode)->i_root &&
  	    !test_bit(NILFS_SC_HAVE_DELTA, &sci->sc_flags))
c96fa464a   Ryusuke Konishi   nilfs2: mark mino...
486
  		set_bit(NILFS_SC_HAVE_DELTA, &sci->sc_flags);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
487
488
489
490
491
492
493
494
495
  	/* 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...
496
  	__u64 cno;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
497
498
499
500
501
  
  	if (sci->sc_blk_cnt == 0)
  		return;
  
  	ii = NILFS_I(inode);
6c43f4100   Ryusuke Konishi   nilfs2: keep zero...
502
503
504
505
506
507
508
  
  	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...
509
510
511
512
513
  	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...
514
  	finfo->fi_cno = cpu_to_le64(cno);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
515
516
517
518
519
520
521
522
523
524
525
  
  	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,
0c6c44cb9   Ryusuke Konishi   nilfs2: avoid bar...
526
  					unsigned int binfo_size)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
  {
  	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...
557
558
559
560
561
562
563
  /*
   * 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...
564
  	err = nilfs_bmap_propagate(NILFS_I(inode)->i_bmap, bh);
e828949e5   Ryusuke Konishi   nilfs2: call nilf...
565
566
  	if (err < 0)
  		return err;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
567
568
569
570
571
572
573
574
575
576
577
578
  
  	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...
579
  	return nilfs_bmap_propagate(NILFS_I(inode)->i_bmap, bh);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
580
581
582
583
584
585
  }
  
  static int nilfs_collect_file_bmap(struct nilfs_sc_info *sci,
  				   struct buffer_head *bh,
  				   struct inode *inode)
  {
1f5abe7e7   Ryusuke Konishi   nilfs2: replace B...
586
  	WARN_ON(!buffer_dirty(bh));
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
  	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;
  }
1c613cb98   Julia Lawall   nilfs2: constify ...
607
  static const struct nilfs_sc_operations nilfs_sc_file_ops = {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
608
609
610
611
612
613
614
615
616
617
618
619
620
  	.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...
621
622
  	if (err < 0)
  		return err;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
623
624
625
626
627
628
629
630
631
632
  
  	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...
633
  	WARN_ON(!buffer_dirty(bh));
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
  	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;
  }
1c613cb98   Julia Lawall   nilfs2: constify ...
655
  static const struct nilfs_sc_operations nilfs_sc_dat_ops = {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
656
657
658
659
660
661
  	.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,
  };
1c613cb98   Julia Lawall   nilfs2: constify ...
662
  static const struct nilfs_sc_operations nilfs_sc_dsync_ops = {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
663
664
665
666
667
668
  	.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...
669
670
671
672
  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...
673
  {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
674
675
  	struct address_space *mapping = inode->i_mapping;
  	struct pagevec pvec;
f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
676
677
678
  	pgoff_t index = 0, last = ULONG_MAX;
  	size_t ndirties = 0;
  	int i;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
679

f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
680
681
682
683
684
685
686
687
688
  	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...
689
690
  	pagevec_init(&pvec, 0);
   repeat:
f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
691
692
693
694
695
  	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...
696
697
698
699
  
  	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...
700
701
  		if (unlikely(page->index > last))
  			break;
aa405b1f4   Ryusuke Konishi   nilfs2: always se...
702
703
  		lock_page(page);
  		if (!page_has_buffers(page))
93407472a   Fabian Frederick   fs: add i_blocksi...
704
  			create_empty_buffers(page, i_blocksize(inode), 0);
aa405b1f4   Ryusuke Konishi   nilfs2: always se...
705
  		unlock_page(page);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
706
707
708
  
  		bh = head = page_buffers(page);
  		do {
7f42ec394   Vyacheslav Dubeyko   nilfs2: fix issue...
709
  			if (!buffer_dirty(bh) || buffer_async_write(bh))
f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
710
711
712
713
714
715
716
717
  				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...
718
  			}
f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
719
  		} while (bh = bh->b_this_page, bh != head);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
720
721
722
  	}
  	pagevec_release(&pvec);
  	cond_resched();
f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
723
  	goto repeat;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
  }
  
  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...
743
744
  				if (buffer_dirty(bh) &&
  						!buffer_async_write(bh)) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
745
746
747
748
749
750
751
752
753
754
755
  					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...
756
  static void nilfs_dispose_list(struct the_nilfs *nilfs,
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
757
758
759
760
  			       struct list_head *head, int force)
  {
  	struct nilfs_inode_info *ii, *n;
  	struct nilfs_inode_info *ivec[SC_N_INODEVEC], **pii;
0c6c44cb9   Ryusuke Konishi   nilfs2: avoid bar...
761
  	unsigned int nv = 0;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
762
763
  
  	while (!list_empty(head)) {
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
764
  		spin_lock(&nilfs->ns_inode_lock);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
765
766
767
768
769
770
771
772
773
774
  		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...
775
  					      &nilfs->ns_dirty_files);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
776
777
778
779
780
781
  				continue;
  			}
  			ivec[nv++] = ii;
  			if (nv == SC_N_INODEVEC)
  				break;
  		}
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
782
  		spin_unlock(&nilfs->ns_inode_lock);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
783
784
785
786
787
  
  		for (pii = ivec; nv > 0; pii++, nv--)
  			iput(&(*pii)->vfs_inode);
  	}
  }
7ef3ff2fe   Ryusuke Konishi   nilfs2: fix deadl...
788
789
790
791
792
793
794
795
  static void nilfs_iput_work_func(struct work_struct *work)
  {
  	struct nilfs_sc_info *sci = container_of(work, struct nilfs_sc_info,
  						 sc_iput_work);
  	struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
  
  	nilfs_dispose_list(nilfs, &sci->sc_iput_queue, 0);
  }
e912a5b66   Ryusuke Konishi   nilfs2: use root ...
796
797
  static int nilfs_test_metadata_dirty(struct the_nilfs *nilfs,
  				     struct nilfs_root *root)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
798
  {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
799
  	int ret = 0;
e912a5b66   Ryusuke Konishi   nilfs2: use root ...
800
  	if (nilfs_mdt_fetch_dirty(root->ifile))
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
801
802
803
804
805
  		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...
806
807
  	if ((ret || nilfs_doing_gc()) && nilfs_mdt_fetch_dirty(nilfs->ns_dat))
  		ret++;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
808
809
810
811
812
813
814
  	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...
815
  		sci->sc_nfreesegs == 0 &&
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
816
817
818
819
820
  		(!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...
821
  	struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
822
  	int ret = 0;
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
823
  	if (nilfs_test_metadata_dirty(nilfs, sci->sc_root))
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
824
  		set_bit(NILFS_SC_DIRTY, &sci->sc_flags);
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
825
826
  	spin_lock(&nilfs->ns_inode_lock);
  	if (list_empty(&nilfs->ns_dirty_files) && nilfs_segctor_clean(sci))
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
827
  		ret++;
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
828
  	spin_unlock(&nilfs->ns_inode_lock);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
829
830
831
832
833
  	return ret;
  }
  
  static void nilfs_segctor_clear_metadata_dirty(struct nilfs_sc_info *sci)
  {
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
834
  	struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
835

e912a5b66   Ryusuke Konishi   nilfs2: use root ...
836
  	nilfs_mdt_clear_dirty(sci->sc_root->ifile);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
837
838
  	nilfs_mdt_clear_dirty(nilfs->ns_cpfile);
  	nilfs_mdt_clear_dirty(nilfs->ns_sufile);
365e215ce   Ryusuke Konishi   nilfs2: unfold ni...
839
  	nilfs_mdt_clear_dirty(nilfs->ns_dat);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
840
841
842
843
  }
  
  static int nilfs_segctor_create_checkpoint(struct nilfs_sc_info *sci)
  {
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
844
  	struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
845
846
847
848
849
850
851
852
  	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)) {
076a378ba   Ryusuke Konishi   nilfs2: fix block...
853
854
855
856
857
  		/*
  		 * 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_...
858
  		mark_buffer_dirty(bh_cp);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
859
860
861
  		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...
862
863
  	} else
  		WARN_ON(err == -EINVAL || err == -ENOENT);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
864
865
866
867
868
  	return err;
  }
  
  static int nilfs_segctor_fill_in_checkpoint(struct nilfs_sc_info *sci)
  {
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
869
  	struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
870
871
872
873
874
875
876
  	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...
877
  		WARN_ON(err == -EINVAL || err == -ENOENT);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
878
879
880
881
882
  		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...
883
  		cpu_to_le64(atomic64_read(&sci->sc_root->inodes_count));
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
884
  	raw_cp->cp_blocks_count =
e5f7f8484   Vyacheslav Dubeyko   ] nilfs2: use ato...
885
  		cpu_to_le64(atomic64_read(&sci->sc_root->blocks_count));
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
886
887
888
889
  	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 ...
890

c96fa464a   Ryusuke Konishi   nilfs2: mark mino...
891
892
893
894
  	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 ...
895
896
  	nilfs_write_inode_common(sci->sc_root->ifile,
  				 &raw_cp->cp_ifile_inode, 1);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
  	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 ...
920
  static void nilfs_segctor_fill_in_file_bmap(struct nilfs_sc_info *sci)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
921
922
923
924
  {
  	struct nilfs_inode_info *ii;
  
  	list_for_each_entry(ii, &sci->sc_dirty_files, i_dirty) {
e912a5b66   Ryusuke Konishi   nilfs2: use root ...
925
  		nilfs_fill_in_file_bmap(sci->sc_root->ifile, ii);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
926
927
  		set_bit(NILFS_I_COLLECTED, &ii->i_state);
  	}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
928
  }
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
929
930
931
  static void nilfs_segctor_fill_in_super_root(struct nilfs_sc_info *sci,
  					     struct the_nilfs *nilfs)
  {
1e2b68bf2   Ryusuke Konishi   nilfs2: move poin...
932
933
  	struct buffer_head *bh_sr;
  	struct nilfs_super_root *raw_sr;
0c6c44cb9   Ryusuke Konishi   nilfs2: avoid bar...
934
  	unsigned int isz, srsz;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
935

1e2b68bf2   Ryusuke Konishi   nilfs2: move poin...
936
937
  	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...
938
939
  	isz = nilfs->ns_inode_size;
  	srsz = NILFS_SR_BYTES(isz);
1e2b68bf2   Ryusuke Konishi   nilfs2: move poin...
940

56eb55388   Ryusuke Konishi   nilfs2: zero fill...
941
  	raw_sr->sr_bytes = cpu_to_le16(srsz);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
942
943
944
945
  	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...
946
  	nilfs_write_inode_common(nilfs->ns_dat, (void *)raw_sr +
3961f0e27   Ryusuke Konishi   nilfs2: eliminate...
947
948
949
950
951
  				 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...
952
  	memset((void *)raw_sr + srsz, 0, nilfs->ns_blocksize - srsz);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
  }
  
  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;
b9f661407   Andreas Rohner   nilfs2: improve t...
972
  		clear_bit(NILFS_I_INODE_SYNC, &ii->i_state);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
973
974
975
  		set_bit(NILFS_I_UPDATED, &ii->i_state);
  	}
  }
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
  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_...
999
1000
  		bh = list_first_entry(listp, struct buffer_head,
  				      b_assoc_buffers);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1001
1002
1003
1004
1005
  		list_del_init(&bh->b_assoc_buffers);
  		brelse(bh);
  	}
  	return err;
  }
f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
1006
1007
1008
1009
1010
1011
  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...
1012
1013
  static int nilfs_segctor_scan_file(struct nilfs_sc_info *sci,
  				   struct inode *inode,
1c613cb98   Julia Lawall   nilfs2: constify ...
1014
  				   const struct nilfs_sc_operations *sc_ops)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1015
1016
1017
  {
  	LIST_HEAD(data_buffers);
  	LIST_HEAD(node_buffers);
f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
1018
  	int err;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1019
1020
  
  	if (!(sci->sc_stage.flags & NILFS_CF_NODE)) {
f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
1021
1022
1023
1024
1025
1026
  		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...
1027
  				sci, inode, &data_buffers,
f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
1028
1029
  				sc_ops->collect_data);
  			BUG_ON(!err); /* always receive -E2BIG or true error */
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
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
  			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...
1069
1070
  	size_t n, rest = nilfs_segctor_buffer_rest(sci);
  	int err;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1071

f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
1072
1073
1074
1075
1076
1077
1078
  	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...
1079
  		nilfs_segctor_end_finfo(sci, inode);
f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
1080
1081
1082
  		BUG_ON(n > rest);
  		/* always receive -E2BIG or true error if n > rest */
  	}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1083
1084
1085
1086
1087
  	return err;
  }
  
  static int nilfs_segctor_collect_blocks(struct nilfs_sc_info *sci, int mode)
  {
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
1088
  	struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1089
1090
  	struct list_head *head;
  	struct nilfs_inode_info *ii;
071cb4b81   Ryusuke Konishi   nilfs2: eliminate...
1091
  	size_t ndone;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1092
  	int err = 0;
584977038   Hitoshi Mitake   nilfs2: add a tra...
1093
  	switch (nilfs_sc_cstage_get(sci)) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1094
1095
1096
1097
1098
1099
1100
1101
  	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) {
584977038   Hitoshi Mitake   nilfs2: add a tra...
1102
  				nilfs_sc_cstage_set(sci, NILFS_ST_DSYNC);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1103
1104
1105
1106
1107
1108
1109
  				goto dsync_mode;
  			}
  		}
  
  		sci->sc_stage.dirty_file_ptr = NULL;
  		sci->sc_stage.gc_inode_ptr = NULL;
  		if (mode == SC_FLUSH_DAT) {
584977038   Hitoshi Mitake   nilfs2: add a tra...
1110
  			nilfs_sc_cstage_set(sci, NILFS_ST_DAT);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1111
1112
  			goto dat_stage;
  		}
584977038   Hitoshi Mitake   nilfs2: add a tra...
1113
  		nilfs_sc_cstage_inc(sci);  /* Fall through */
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
  	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;
  		}
584977038   Hitoshi Mitake   nilfs2: add a tra...
1134
  		nilfs_sc_cstage_inc(sci);  /* Fall through */
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
  	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) {
584977038   Hitoshi Mitake   nilfs2: add a tra...
1156
  			nilfs_sc_cstage_set(sci, NILFS_ST_DONE);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1157
1158
  			return 0;
  		}
584977038   Hitoshi Mitake   nilfs2: add a tra...
1159
  		nilfs_sc_cstage_inc(sci);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1160
1161
1162
  		sci->sc_stage.flags |= NILFS_CF_IFILE_STARTED;
  		/* Fall through */
  	case NILFS_ST_IFILE:
e912a5b66   Ryusuke Konishi   nilfs2: use root ...
1163
  		err = nilfs_segctor_scan_file(sci, sci->sc_root->ifile,
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1164
1165
1166
  					      &nilfs_sc_file_ops);
  		if (unlikely(err))
  			break;
584977038   Hitoshi Mitake   nilfs2: add a tra...
1167
  		nilfs_sc_cstage_inc(sci);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
  		/* 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;
584977038   Hitoshi Mitake   nilfs2: add a tra...
1178
  		nilfs_sc_cstage_inc(sci);  /* Fall through */
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1179
  	case NILFS_ST_SUFILE:
071cb4b81   Ryusuke Konishi   nilfs2: eliminate...
1180
1181
1182
1183
1184
1185
  		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...
1186
  			break;
071cb4b81   Ryusuke Konishi   nilfs2: eliminate...
1187
1188
  		}
  		sci->sc_stage.flags |= NILFS_CF_SUFREED;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1189
1190
1191
1192
  		err = nilfs_segctor_scan_file(sci, nilfs->ns_sufile,
  					      &nilfs_sc_file_ops);
  		if (unlikely(err))
  			break;
584977038   Hitoshi Mitake   nilfs2: add a tra...
1193
  		nilfs_sc_cstage_inc(sci);  /* Fall through */
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1194
1195
  	case NILFS_ST_DAT:
   dat_stage:
365e215ce   Ryusuke Konishi   nilfs2: unfold ni...
1196
  		err = nilfs_segctor_scan_file(sci, nilfs->ns_dat,
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1197
1198
1199
1200
  					      &nilfs_sc_dat_ops);
  		if (unlikely(err))
  			break;
  		if (mode == SC_FLUSH_DAT) {
584977038   Hitoshi Mitake   nilfs2: add a tra...
1201
  			nilfs_sc_cstage_set(sci, NILFS_ST_DONE);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1202
1203
  			return 0;
  		}
584977038   Hitoshi Mitake   nilfs2: add a tra...
1204
  		nilfs_sc_cstage_inc(sci);  /* Fall through */
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1205
1206
1207
1208
1209
1210
1211
1212
1213
  	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;
584977038   Hitoshi Mitake   nilfs2: add a tra...
1214
  		nilfs_sc_cstage_set(sci, NILFS_ST_DONE);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1215
1216
1217
1218
  		return 0;
  	case NILFS_ST_DSYNC:
   dsync_mode:
  		sci->sc_curseg->sb_sum.flags |= NILFS_SS_SYNDT;
f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
1219
  		ii = sci->sc_dsync_inode;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1220
1221
1222
1223
1224
1225
  		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...
1226
  		sci->sc_curseg->sb_sum.flags |= NILFS_SS_LOGEND;
584977038   Hitoshi Mitake   nilfs2: add a tra...
1227
  		nilfs_sc_cstage_set(sci, NILFS_ST_DONE);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
  		return 0;
  	case NILFS_ST_DONE:
  		return 0;
  	default:
  		BUG();
  	}
  
   break_or_fail:
  	return err;
  }
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1238
1239
1240
1241
1242
  /**
   * 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...
1243
1244
1245
  static int nilfs_segctor_begin_construction(struct nilfs_sc_info *sci,
  					    struct the_nilfs *nilfs)
  {
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1246
  	struct nilfs_segment_buffer *segbuf, *prev;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1247
  	__u64 nextnum;
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1248
  	int err, alloc = 0;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1249

a694291a6   Ryusuke Konishi   nilfs2: separate ...
1250
1251
1252
  	segbuf = nilfs_segbuf_new(sci->sc_super);
  	if (unlikely(!segbuf))
  		return -ENOMEM;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1253

a694291a6   Ryusuke Konishi   nilfs2: separate ...
1254
1255
1256
1257
1258
1259
1260
  	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...
1261

a694291a6   Ryusuke Konishi   nilfs2: separate ...
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
  		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...
1280
  	}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1281

61a189e9c   Ryusuke Konishi   nilfs2: move rout...
1282
  	err = nilfs_sufile_mark_dirty(nilfs->ns_sufile, segbuf->sb_segnum);
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1283
1284
  	if (err)
  		goto failed;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1285

a694291a6   Ryusuke Konishi   nilfs2: separate ...
1286
  	if (alloc) {
cece55207   Ryusuke Konishi   nilfs2: simplify ...
1287
  		err = nilfs_sufile_alloc(nilfs->ns_sufile, &nextnum);
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1288
1289
1290
  		if (err)
  			goto failed;
  	}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1291
  	nilfs_segbuf_set_next_segnum(segbuf, nextnum, nilfs);
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1292
1293
1294
  	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 ...
1295
  	return 0;
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1296
1297
1298
1299
  
   failed:
  	nilfs_segbuf_free(segbuf);
  	return err;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1300
1301
1302
1303
1304
  }
  
  static int nilfs_segctor_extend_segments(struct nilfs_sc_info *sci,
  					 struct the_nilfs *nilfs, int nadd)
  {
e29df395b   Ryusuke Konishi   nilfs2: add itera...
1305
  	struct nilfs_segment_buffer *segbuf, *prev;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
  	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...
1318
  	err = nilfs_sufile_mark_dirty(sufile, prev->sb_nextnum);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
  	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 ...
1330
  		nilfs_segbuf_map(segbuf, prev->sb_nextnum, 0, nilfs);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
  		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_...
1344
  	list_splice_tail(&list, &sci->sc_segbufs);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1345
1346
1347
1348
1349
  	return 0;
  
   failed_segbuf:
  	nilfs_segbuf_free(segbuf);
   failed:
e29df395b   Ryusuke Konishi   nilfs2: add itera...
1350
  	list_for_each_entry(segbuf, &list, sb_list) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1351
  		ret = nilfs_sufile_free(sufile, segbuf->sb_nextnum);
1f5abe7e7   Ryusuke Konishi   nilfs2: replace B...
1352
  		WARN_ON(ret); /* never fails */
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1353
  	}
e29df395b   Ryusuke Konishi   nilfs2: add itera...
1354
  	nilfs_destroy_logs(&list);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1355
1356
  	return err;
  }
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1357
1358
  static void nilfs_free_incomplete_logs(struct list_head *logs,
  				       struct the_nilfs *nilfs)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1359
  {
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1360
1361
  	struct nilfs_segment_buffer *segbuf, *prev;
  	struct inode *sufile = nilfs->ns_sufile;
9284ad2a9   Ryusuke Konishi   nilfs2: relocate ...
1362
  	int ret;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1363

a694291a6   Ryusuke Konishi   nilfs2: separate ...
1364
  	segbuf = NILFS_FIRST_SEGBUF(logs);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1365
  	if (nilfs->ns_nextnum != segbuf->sb_nextnum) {
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1366
  		ret = nilfs_sufile_free(sufile, segbuf->sb_nextnum);
1f5abe7e7   Ryusuke Konishi   nilfs2: replace B...
1367
  		WARN_ON(ret); /* never fails */
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1368
  	}
9284ad2a9   Ryusuke Konishi   nilfs2: relocate ...
1369
  	if (atomic_read(&segbuf->sb_err)) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1370
1371
  		/* Case 1: The first segment failed */
  		if (segbuf->sb_pseg_start != segbuf->sb_fseg_start)
076a378ba   Ryusuke Konishi   nilfs2: fix block...
1372
1373
1374
1375
  			/*
  			 * Case 1a:  Partial segment appended into an existing
  			 * segment
  			 */
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1376
1377
1378
1379
  			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...
1380
  	}
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1381
1382
1383
1384
1385
1386
  	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 ...
1387
1388
1389
  		if (atomic_read(&segbuf->sb_err) &&
  		    segbuf->sb_segnum != nilfs->ns_nextnum)
  			/* Case 2: extended segment (!= next) failed */
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1390
1391
  			nilfs_sufile_set_error(sufile, segbuf->sb_segnum);
  		prev = segbuf;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1392
  	}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1393
1394
1395
1396
1397
1398
  }
  
  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...
1399
1400
1401
1402
  	unsigned long live_blocks;
  	int ret;
  
  	list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1403
1404
  		live_blocks = segbuf->sb_sum.nblocks +
  			(segbuf->sb_pseg_start - segbuf->sb_fseg_start);
071ec54dd   Ryusuke Konishi   nilfs2: move rout...
1405
1406
1407
1408
  		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...
1409
1410
  	}
  }
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1411
  static void nilfs_cancel_segusage(struct list_head *logs, struct inode *sufile)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1412
1413
  {
  	struct nilfs_segment_buffer *segbuf;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1414
  	int ret;
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1415
  	segbuf = NILFS_FIRST_SEGBUF(logs);
071ec54dd   Ryusuke Konishi   nilfs2: move rout...
1416
1417
1418
1419
  	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...
1420

a694291a6   Ryusuke Konishi   nilfs2: separate ...
1421
  	list_for_each_entry_continue(segbuf, logs, sb_list) {
071ec54dd   Ryusuke Konishi   nilfs2: move rout...
1422
1423
  		ret = nilfs_sufile_set_segment_usage(sufile, segbuf->sb_segnum,
  						     0, 0);
1f5abe7e7   Ryusuke Konishi   nilfs2: replace B...
1424
  		WARN_ON(ret); /* always succeed */
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1425
1426
1427
1428
1429
1430
1431
  	}
  }
  
  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...
1432
  	struct nilfs_segment_buffer *segbuf = last;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1433
  	int ret;
e29df395b   Ryusuke Konishi   nilfs2: add itera...
1434
  	list_for_each_entry_continue(segbuf, &sci->sc_segbufs, sb_list) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1435
1436
  		sci->sc_segbuf_nblocks -= segbuf->sb_rest_blocks;
  		ret = nilfs_sufile_free(sufile, segbuf->sb_nextnum);
1f5abe7e7   Ryusuke Konishi   nilfs2: replace B...
1437
  		WARN_ON(ret);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1438
  	}
e29df395b   Ryusuke Konishi   nilfs2: add itera...
1439
  	nilfs_truncate_logs(&sci->sc_segbufs, last);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
  }
  
  
  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...
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
  		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 */
584977038   Hitoshi Mitake   nilfs2: add a tra...
1467
1468
  		if (mode != SC_LSEG_SR ||
  		    nilfs_sc_cstage_get(sci) < NILFS_ST_CPFILE)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1469
  			break;
2d8428aca   Ryusuke Konishi   nilfs2: fix dupli...
1470
  		nilfs_clear_logs(&sci->sc_segbufs);
071cb4b81   Ryusuke Konishi   nilfs2: eliminate...
1471
1472
1473
1474
1475
1476
  		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...
1477
  			sci->sc_stage.flags &= ~NILFS_CF_SUFREED;
071cb4b81   Ryusuke Konishi   nilfs2: eliminate...
1478
  		}
70f2fe3a2   Andreas Rohner   nilfs2: fix segct...
1479
1480
1481
1482
  
  		err = nilfs_segctor_extend_segments(sci, nilfs, nadd);
  		if (unlikely(err))
  			return err;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
  		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;
1c613cb98   Julia Lawall   nilfs2: constify ...
1511
  	const struct nilfs_sc_operations *sc_op = NULL;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
  	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...
1527
  		if (bh == segbuf->sb_super_root)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1528
1529
1530
1531
1532
1533
1534
  			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...
1535
  			inode = bh->b_page->mapping->host;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
  
  			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...
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
  	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...
1587
  static void nilfs_begin_page_io(struct page *page)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1588
1589
  {
  	if (!page || PageWriteback(page))
076a378ba   Ryusuke Konishi   nilfs2: fix block...
1590
1591
1592
1593
  		/*
  		 * 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...
1594
  		return;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1595
1596
1597
1598
1599
  
  	lock_page(page);
  	clear_page_dirty_for_io(page);
  	set_page_writeback(page);
  	unlock_page(page);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1600
  }
1cb2d38cb   Ryusuke Konishi   nilfs2: get rid o...
1601
  static void nilfs_segctor_prepare_write(struct nilfs_sc_info *sci)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1602
1603
1604
  {
  	struct nilfs_segment_buffer *segbuf;
  	struct page *bd_page = NULL, *fs_page = NULL;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1605

9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
  	list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) {
  		struct buffer_head *bh;
  
  		list_for_each_entry(bh, &segbuf->sb_segsum_buffers,
  				    b_assoc_buffers) {
  			if (bh->b_page != bd_page) {
  				if (bd_page) {
  					lock_page(bd_page);
  					clear_page_dirty_for_io(bd_page);
  					set_page_writeback(bd_page);
  					unlock_page(bd_page);
  				}
  				bd_page = bh->b_page;
  			}
  		}
  
  		list_for_each_entry(bh, &segbuf->sb_payload_buffers,
  				    b_assoc_buffers) {
7f42ec394   Vyacheslav Dubeyko   nilfs2: fix issue...
1624
  			set_buffer_async_write(bh);
1e2b68bf2   Ryusuke Konishi   nilfs2: move poin...
1625
  			if (bh == segbuf->sb_super_root) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
  				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...
1636
  				nilfs_begin_page_io(fs_page);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
  				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...
1647
  	nilfs_begin_page_io(fs_page);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1648
1649
1650
  }
  
  static int nilfs_segctor_write(struct nilfs_sc_info *sci,
9c965bac1   Ryusuke Konishi   nilfs2: hide nilf...
1651
  			       struct the_nilfs *nilfs)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1652
  {
d1c6b72a7   Ryusuke Konishi   nilfs2: move iter...
1653
  	int ret;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1654

d1c6b72a7   Ryusuke Konishi   nilfs2: move iter...
1655
  	ret = nilfs_write_logs(&sci->sc_segbufs, nilfs);
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1656
1657
  	list_splice_tail_init(&sci->sc_segbufs, &sci->sc_write_logs);
  	return ret;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1658
  }
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1659
1660
1661
1662
  static void nilfs_end_page_io(struct page *page, int err)
  {
  	if (!page)
  		return;
a97778457   Ryusuke Konishi   nilfs2: fix oops ...
1663
  	if (buffer_nilfs_node(page_buffers(page)) && !PageWriteback(page)) {
8227b2972   Ryusuke Konishi   nilfs2: fix hang ...
1664
1665
1666
1667
  		/*
  		 * 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 ...
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
  		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...
1681
  		return;
a97778457   Ryusuke Konishi   nilfs2: fix oops ...
1682
  	}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1683

1cb2d38cb   Ryusuke Konishi   nilfs2: get rid o...
1684
1685
1686
1687
1688
1689
1690
  	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...
1691
  	}
1cb2d38cb   Ryusuke Konishi   nilfs2: get rid o...
1692
1693
  
  	end_page_writeback(page);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1694
  }
1cb2d38cb   Ryusuke Konishi   nilfs2: get rid o...
1695
  static void nilfs_abort_logs(struct list_head *logs, int err)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1696
1697
1698
  {
  	struct nilfs_segment_buffer *segbuf;
  	struct page *bd_page = NULL, *fs_page = NULL;
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1699
  	struct buffer_head *bh;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1700

a694291a6   Ryusuke Konishi   nilfs2: separate ...
1701
1702
  	if (list_empty(logs))
  		return;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1703

a694291a6   Ryusuke Konishi   nilfs2: separate ...
1704
  	list_for_each_entry(segbuf, logs, sb_list) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
  		list_for_each_entry(bh, &segbuf->sb_segsum_buffers,
  				    b_assoc_buffers) {
  			if (bh->b_page != bd_page) {
  				if (bd_page)
  					end_page_writeback(bd_page);
  				bd_page = bh->b_page;
  			}
  		}
  
  		list_for_each_entry(bh, &segbuf->sb_payload_buffers,
  				    b_assoc_buffers) {
7f42ec394   Vyacheslav Dubeyko   nilfs2: fix issue...
1716
  			clear_buffer_async_write(bh);
1e2b68bf2   Ryusuke Konishi   nilfs2: move poin...
1717
  			if (bh == segbuf->sb_super_root) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1718
1719
1720
1721
1722
1723
1724
1725
  				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...
1726
1727
1728
1729
1730
1731
1732
1733
  				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 ...
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
  }
  
  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...
1744
  	nilfs_abort_logs(&logs, ret ? : err);
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1745
1746
1747
1748
  
  	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 ...
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
  
  	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...
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
  }
  
  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...
1776
  	struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
1e2b68bf2   Ryusuke Konishi   nilfs2: move poin...
1777
  	int update_sr = false;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1778

a694291a6   Ryusuke Konishi   nilfs2: separate ...
1779
  	list_for_each_entry(segbuf, &sci->sc_write_logs, sb_list) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
  		struct buffer_head *bh;
  
  		list_for_each_entry(bh, &segbuf->sb_segsum_buffers,
  				    b_assoc_buffers) {
  			set_buffer_uptodate(bh);
  			clear_buffer_dirty(bh);
  			if (bh->b_page != bd_page) {
  				if (bd_page)
  					end_page_writeback(bd_page);
  				bd_page = bh->b_page;
  			}
  		}
  		/*
  		 * We assume that the buffers which belong to the same page
  		 * continue over the buffer list.
  		 * Under this assumption, the last BHs of pages is
  		 * identifiable by the discontinuity of bh->b_page
  		 * (page != fs_page).
  		 *
  		 * For B-tree node blocks, however, this assumption is not
  		 * guaranteed.  The cleanup code of B-tree node pages needs
  		 * special care.
  		 */
  		list_for_each_entry(bh, &segbuf->sb_payload_buffers,
  				    b_assoc_buffers) {
4ce5c3426   Ryusuke Konishi   nilfs2: use BIT()...
1805
  			const unsigned long set_bits = BIT(BH_Uptodate);
ead8ecffa   Ryusuke Konishi   nilfs2: use set_m...
1806
  			const unsigned long clear_bits =
4ce5c3426   Ryusuke Konishi   nilfs2: use BIT()...
1807
1808
1809
  				(BIT(BH_Dirty) | BIT(BH_Async_Write) |
  				 BIT(BH_Delay) | BIT(BH_NILFS_Volatile) |
  				 BIT(BH_NILFS_Redirected));
ead8ecffa   Ryusuke Konishi   nilfs2: use set_m...
1810
1811
  
  			set_mask_bits(&bh->b_state, clear_bits, set_bits);
1e2b68bf2   Ryusuke Konishi   nilfs2: move poin...
1812
  			if (bh == segbuf->sb_super_root) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1813
1814
1815
1816
  				if (bh->b_page != bd_page) {
  					end_page_writeback(bd_page);
  					bd_page = bh->b_page;
  				}
1e2b68bf2   Ryusuke Konishi   nilfs2: move poin...
1817
  				update_sr = true;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1818
1819
1820
1821
1822
1823
1824
  				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...
1825
1826
  		if (!nilfs_segbuf_simplex(segbuf)) {
  			if (segbuf->sb_sum.flags & NILFS_SS_LOGBGN) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1827
1828
1829
  				set_bit(NILFS_SC_UNCLOSED, &sci->sc_flags);
  				sci->sc_lseg_stime = jiffies;
  			}
4762077c7   Ryusuke Konishi   nilfs2: get rid o...
1830
  			if (segbuf->sb_sum.flags & NILFS_SS_LOGEND)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
  				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...
1842
  	nilfs_drop_collected_inodes(&sci->sc_dirty_files);
c1c1d7092   Ryusuke Konishi   nilfs2: get rid o...
1843
  	if (nilfs_doing_gc())
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1844
  		nilfs_drop_collected_inodes(&sci->sc_gc_inodes);
c1c1d7092   Ryusuke Konishi   nilfs2: get rid o...
1845
  	else
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1846
  		nilfs->ns_nongc_ctime = sci->sc_seg_ctime;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1847
1848
  
  	sci->sc_nblk_inc += sci->sc_nblk_this_inc;
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1849
  	segbuf = NILFS_LAST_SEGBUF(&sci->sc_write_logs);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1850
1851
1852
  	nilfs_set_next_segment(nilfs, segbuf);
  
  	if (update_sr) {
e2c7617ae   Andreas Rohner   nilfs2: add missi...
1853
  		nilfs->ns_flushed_device = 0;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1854
  		nilfs_set_last_segment(nilfs, segbuf->sb_pseg_start,
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
1855
  				       segbuf->sb_sum.seg_seq, nilfs->ns_cno++);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1856

c96fa464a   Ryusuke Konishi   nilfs2: mark mino...
1857
  		clear_bit(NILFS_SC_HAVE_DELTA, &sci->sc_flags);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1858
1859
  		clear_bit(NILFS_SC_DIRTY, &sci->sc_flags);
  		set_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags);
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1860
  		nilfs_segctor_clear_metadata_dirty(sci);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1861
1862
1863
  	} else
  		clear_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags);
  }
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
  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...
1875
1876
  static int nilfs_segctor_collect_dirty_files(struct nilfs_sc_info *sci,
  					     struct the_nilfs *nilfs)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1877
1878
  {
  	struct nilfs_inode_info *ii, *n;
e912a5b66   Ryusuke Konishi   nilfs2: use root ...
1879
  	struct inode *ifile = sci->sc_root->ifile;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1880

693dd3212   Ryusuke Konishi   nilfs2: move s_in...
1881
  	spin_lock(&nilfs->ns_inode_lock);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1882
   retry:
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
1883
  	list_for_each_entry_safe(ii, n, &nilfs->ns_dirty_files, i_dirty) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1884
1885
1886
  		if (!ii->i_bh) {
  			struct buffer_head *ibh;
  			int err;
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
1887
  			spin_unlock(&nilfs->ns_inode_lock);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1888
  			err = nilfs_ifile_get_inode_block(
e912a5b66   Ryusuke Konishi   nilfs2: use root ...
1889
  				ifile, ii->vfs_inode.i_ino, &ibh);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1890
  			if (unlikely(err)) {
d6517deb0   Ryusuke Konishi   nilfs2: replace n...
1891
1892
1893
  				nilfs_msg(sci->sc_super, KERN_WARNING,
  					  "log writer: error %d getting inode block (ino=%lu)",
  					  err, ii->vfs_inode.i_ino);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1894
1895
  				return err;
  			}
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
1896
  			spin_lock(&nilfs->ns_inode_lock);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1897
1898
1899
1900
1901
1902
  			if (likely(!ii->i_bh))
  				ii->i_bh = ibh;
  			else
  				brelse(ibh);
  			goto retry;
  		}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1903

f94782668   Andreas Rohner   nilfs2: fix race ...
1904
1905
1906
  		// Always redirty the buffer to avoid race condition
  		mark_buffer_dirty(ii->i_bh);
  		nilfs_mdt_mark_dirty(ifile);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1907
1908
  		clear_bit(NILFS_I_QUEUED, &ii->i_state);
  		set_bit(NILFS_I_BUSY, &ii->i_state);
eaae0f37d   Nicolas Kaiser   nilfs2: merge lis...
1909
  		list_move_tail(&ii->i_dirty, &sci->sc_dirty_files);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1910
  	}
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
1911
  	spin_unlock(&nilfs->ns_inode_lock);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1912

9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1913
1914
  	return 0;
  }
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
1915
1916
  static void nilfs_segctor_drop_written_files(struct nilfs_sc_info *sci,
  					     struct the_nilfs *nilfs)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1917
  {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1918
  	struct nilfs_inode_info *ii, *n;
283ee1482   Ryusuke Konishi   nilfs2: fix deadl...
1919
  	int during_mount = !(sci->sc_super->s_flags & MS_ACTIVE);
7ef3ff2fe   Ryusuke Konishi   nilfs2: fix deadl...
1920
  	int defer_iput = false;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1921

693dd3212   Ryusuke Konishi   nilfs2: move s_in...
1922
  	spin_lock(&nilfs->ns_inode_lock);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1923
1924
  	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...
1925
  		    test_bit(NILFS_I_DIRTY, &ii->i_state))
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1926
  			continue;
6c43f4100   Ryusuke Konishi   nilfs2: keep zero...
1927

9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1928
1929
1930
  		clear_bit(NILFS_I_BUSY, &ii->i_state);
  		brelse(ii->i_bh);
  		ii->i_bh = NULL;
7ef3ff2fe   Ryusuke Konishi   nilfs2: fix deadl...
1931
  		list_del_init(&ii->i_dirty);
283ee1482   Ryusuke Konishi   nilfs2: fix deadl...
1932
  		if (!ii->vfs_inode.i_nlink || during_mount) {
7ef3ff2fe   Ryusuke Konishi   nilfs2: fix deadl...
1933
  			/*
283ee1482   Ryusuke Konishi   nilfs2: fix deadl...
1934
1935
  			 * Defer calling iput() to avoid deadlocks if
  			 * i_nlink == 0 or mount is not yet finished.
7ef3ff2fe   Ryusuke Konishi   nilfs2: fix deadl...
1936
1937
1938
1939
1940
1941
1942
1943
  			 */
  			list_add_tail(&ii->i_dirty, &sci->sc_iput_queue);
  			defer_iput = true;
  		} else {
  			spin_unlock(&nilfs->ns_inode_lock);
  			iput(&ii->vfs_inode);
  			spin_lock(&nilfs->ns_inode_lock);
  		}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1944
  	}
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
1945
  	spin_unlock(&nilfs->ns_inode_lock);
7ef3ff2fe   Ryusuke Konishi   nilfs2: fix deadl...
1946
1947
1948
  
  	if (defer_iput)
  		schedule_work(&sci->sc_iput_work);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1949
1950
1951
  }
  
  /*
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1952
1953
1954
1955
   * 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...
1956
  	struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
1e2b68bf2   Ryusuke Konishi   nilfs2: move poin...
1957
  	int err;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1958

584977038   Hitoshi Mitake   nilfs2: add a tra...
1959
  	nilfs_sc_cstage_set(sci, NILFS_ST_INIT);
6c43f4100   Ryusuke Konishi   nilfs2: keep zero...
1960
  	sci->sc_cno = nilfs->ns_cno;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1961

693dd3212   Ryusuke Konishi   nilfs2: move s_in...
1962
  	err = nilfs_segctor_collect_dirty_files(sci, nilfs);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1963
1964
  	if (unlikely(err))
  		goto out;
e912a5b66   Ryusuke Konishi   nilfs2: use root ...
1965
  	if (nilfs_test_metadata_dirty(nilfs, sci->sc_root))
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
  		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...
1984
  		/* Avoid empty segment */
584977038   Hitoshi Mitake   nilfs2: add a tra...
1985
  		if (nilfs_sc_cstage_get(sci) == NILFS_ST_DONE &&
4762077c7   Ryusuke Konishi   nilfs2: get rid o...
1986
  		    nilfs_segbuf_empty(sci->sc_curseg)) {
a694291a6   Ryusuke Konishi   nilfs2: separate ...
1987
  			nilfs_segctor_abort_construction(sci, nilfs, 1);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1988
1989
1990
1991
1992
1993
  			goto out;
  		}
  
  		err = nilfs_segctor_assign(sci, mode);
  		if (unlikely(err))
  			goto failed;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1994
  		if (sci->sc_stage.flags & NILFS_CF_IFILE_STARTED)
e912a5b66   Ryusuke Konishi   nilfs2: use root ...
1995
  			nilfs_segctor_fill_in_file_bmap(sci);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1996

1e2b68bf2   Ryusuke Konishi   nilfs2: move poin...
1997
  		if (mode == SC_LSEG_SR &&
584977038   Hitoshi Mitake   nilfs2: add a tra...
1998
  		    nilfs_sc_cstage_get(sci) >= NILFS_ST_CPFILE) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
1999
2000
  			err = nilfs_segctor_fill_in_checkpoint(sci);
  			if (unlikely(err))
a694291a6   Ryusuke Konishi   nilfs2: separate ...
2001
  				goto failed_to_write;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2002
2003
2004
2005
2006
2007
  
  			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...
2008
  		nilfs_segctor_prepare_write(sci);
aaed1d5bf   Ryusuke Konishi   nilfs2: move out ...
2009
2010
2011
  
  		nilfs_add_checksums_on_logs(&sci->sc_segbufs,
  					    nilfs->ns_crc_seed);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2012

9c965bac1   Ryusuke Konishi   nilfs2: hide nilf...
2013
  		err = nilfs_segctor_write(sci, nilfs);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2014
2015
  		if (unlikely(err))
  			goto failed_to_write;
584977038   Hitoshi Mitake   nilfs2: add a tra...
2016
  		if (nilfs_sc_cstage_get(sci) == NILFS_ST_DONE ||
09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
2017
  		    nilfs->ns_blocksize_bits != PAGE_SHIFT) {
a694291a6   Ryusuke Konishi   nilfs2: separate ...
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
  			/*
  			 * 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;
  		}
584977038   Hitoshi Mitake   nilfs2: add a tra...
2029
  	} while (nilfs_sc_cstage_get(sci) != NILFS_ST_DONE);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2030

9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2031
   out:
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
2032
  	nilfs_segctor_drop_written_files(sci, nilfs);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2033
2034
2035
  	return err;
  
   failed_to_write:
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2036
2037
  	if (sci->sc_stage.flags & NILFS_CF_IFILE_STARTED)
  		nilfs_redirty_inodes(&sci->sc_dirty_files);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2038
2039
2040
2041
  
   failed:
  	if (nilfs_doing_gc())
  		nilfs_redirty_inodes(&sci->sc_gc_inodes);
a694291a6   Ryusuke Konishi   nilfs2: separate ...
2042
  	nilfs_segctor_abort_construction(sci, nilfs, err);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2043
2044
2045
2046
  	goto out;
  }
  
  /**
9ccf56c13   Ryusuke Konishi   nilfs2: fix funct...
2047
   * nilfs_segctor_start_timer - set timer of background write
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2048
2049
2050
2051
2052
2053
2054
2055
2056
   * @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...
2057
2058
2059
  	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...
2060
2061
2062
2063
2064
2065
2066
2067
  		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);
4ce5c3426   Ryusuke Konishi   nilfs2: use BIT()...
2068
  	if (!(sci->sc_flush_request & BIT(bn))) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2069
  		unsigned long prev_req = sci->sc_flush_request;
4ce5c3426   Ryusuke Konishi   nilfs2: use BIT()...
2070
  		sci->sc_flush_request |= BIT(bn);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
  		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...
2084
  	struct the_nilfs *nilfs = sb->s_fs_info;
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
2085
  	struct nilfs_sc_info *sci = nilfs->ns_writer;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2086
2087
2088
2089
2090
2091
  
  	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...
2092
  struct nilfs_segctor_wait_request {
ac6424b98   Ingo Molnar   sched/wait: Renam...
2093
  	wait_queue_entry_t	wq;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
  	__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);
2055da973   Ingo Molnar   sched/wait: Disam...
2138
  	list_for_each_entry_safe(wrq, n, &sci->sc_wait_request.head, wq.entry) {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
  		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...
2172
  	struct the_nilfs *nilfs = sb->s_fs_info;
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
2173
  	struct nilfs_sc_info *sci = nilfs->ns_writer;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
  	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...
2190
2191
2192
   * @inode: inode whose data blocks should be written out
   * @start: start byte offset
   * @end: end byte offset (inclusive)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
   *
   * 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...
2207
2208
  int nilfs_construct_dsync_segment(struct super_block *sb, struct inode *inode,
  				  loff_t start, loff_t end)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2209
  {
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
2210
  	struct the_nilfs *nilfs = sb->s_fs_info;
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
2211
  	struct nilfs_sc_info *sci = nilfs->ns_writer;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2212
2213
2214
2215
2216
2217
  	struct nilfs_inode_info *ii;
  	struct nilfs_transaction_info ti;
  	int err = 0;
  
  	if (!sci)
  		return -EROFS;
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2218
  	nilfs_transaction_lock(sb, &ti, 0);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2219
2220
  
  	ii = NILFS_I(inode);
b9f661407   Andreas Rohner   nilfs2: improve t...
2221
  	if (test_bit(NILFS_I_INODE_SYNC, &ii->i_state) ||
3b2ce58b0   Ryusuke Konishi   nilfs2: move moun...
2222
  	    nilfs_test_opt(nilfs, STRICT_ORDER) ||
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2223
  	    test_bit(NILFS_SC_UNCLOSED, &sci->sc_flags) ||
3b2ce58b0   Ryusuke Konishi   nilfs2: move moun...
2224
  	    nilfs_discontinued(nilfs)) {
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2225
  		nilfs_transaction_unlock(sb);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2226
2227
2228
  		err = nilfs_segctor_sync(sci);
  		return err;
  	}
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
2229
  	spin_lock(&nilfs->ns_inode_lock);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2230
2231
  	if (!test_bit(NILFS_I_QUEUED, &ii->i_state) &&
  	    !test_bit(NILFS_I_BUSY, &ii->i_state)) {
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
2232
  		spin_unlock(&nilfs->ns_inode_lock);
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2233
  		nilfs_transaction_unlock(sb);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2234
2235
  		return 0;
  	}
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
2236
  	spin_unlock(&nilfs->ns_inode_lock);
f30bf3e40   Ryusuke Konishi   nilfs2: fix misse...
2237
2238
2239
  	sci->sc_dsync_inode = ii;
  	sci->sc_dsync_start = start;
  	sci->sc_dsync_end = end;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2240
2241
  
  	err = nilfs_segctor_do_construct(sci, SC_LSEG_DSYNC);
e2c7617ae   Andreas Rohner   nilfs2: add missi...
2242
2243
  	if (!err)
  		nilfs->ns_flushed_device = 0;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2244

f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2245
  	nilfs_transaction_unlock(sb);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2246
2247
  	return err;
  }
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2248
  #define FLUSH_FILE_BIT	(0x1) /* data file only */
4ce5c3426   Ryusuke Konishi   nilfs2: use BIT()...
2249
  #define FLUSH_DAT_BIT	BIT(NILFS_DAT_INO) /* DAT only */
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2250

dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2251
2252
2253
2254
2255
  /**
   * 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...
2256
  {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2257
  	spin_lock(&sci->sc_state_lock);
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2258
  	sci->sc_seq_accepted = sci->sc_seq_request;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2259
  	spin_unlock(&sci->sc_state_lock);
fdce895ea   Li Hong   nilfs2: change sc...
2260
  	del_timer_sync(&sci->sc_timer);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2261
  }
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2262
2263
2264
2265
2266
2267
2268
  /**
   * 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...
2269
2270
2271
  {
  	/* Clear requests (even when the construction failed) */
  	spin_lock(&sci->sc_state_lock);
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2272
  	if (mode == SC_LSEG_SR) {
aeda7f634   Ryusuke Konishi   nilfs2: fix irreg...
2273
  		sci->sc_state &= ~NILFS_SEGCTOR_COMMIT;
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2274
2275
  		sci->sc_seq_done = sci->sc_seq_accepted;
  		nilfs_segctor_wakeup(sci, err);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2276
  		sci->sc_flush_request = 0;
aeda7f634   Ryusuke Konishi   nilfs2: fix irreg...
2277
  	} else {
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2278
  		if (mode == SC_FLUSH_FILE)
aeda7f634   Ryusuke Konishi   nilfs2: fix irreg...
2279
  			sci->sc_flush_request &= ~FLUSH_FILE_BIT;
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2280
  		else if (mode == SC_FLUSH_DAT)
aeda7f634   Ryusuke Konishi   nilfs2: fix irreg...
2281
2282
2283
  			sci->sc_flush_request &= ~FLUSH_DAT_BIT;
  
  		/* re-enable timer if checkpoint creation was not done */
fdce895ea   Li Hong   nilfs2: change sc...
2284
2285
2286
  		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...
2287
  	}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2288
2289
  	spin_unlock(&sci->sc_state_lock);
  }
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2290
2291
2292
2293
2294
2295
  /**
   * 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...
2296
  {
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
2297
  	struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
d26493b6f   Jiro SEKIBA   nilfs2: introduce...
2298
  	struct nilfs_super_block **sbp;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2299
  	int err = 0;
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2300
  	nilfs_segctor_accept(sci);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2301
  	if (nilfs_discontinued(nilfs))
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2302
2303
2304
  		mode = SC_LSEG_SR;
  	if (!nilfs_segctor_confirm(sci))
  		err = nilfs_segctor_do_construct(sci, mode);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2305
  	if (likely(!err)) {
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2306
  		if (mode != SC_FLUSH_DAT)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2307
2308
2309
2310
  			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...
2311
  			err = -EIO;
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2312
  			sbp = nilfs_prepare_super(sci->sc_super,
b2ac86e1a   Jiro SEKIBA   nilfs2: sync supe...
2313
2314
2315
  						  nilfs_sb_will_flip(nilfs));
  			if (likely(sbp)) {
  				nilfs_set_log_cursor(sbp[0], nilfs);
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2316
2317
  				err = nilfs_commit_super(sci->sc_super,
  							 NILFS_SB_COMMIT);
b2ac86e1a   Jiro SEKIBA   nilfs2: sync supe...
2318
  			}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2319
2320
2321
  			up_write(&nilfs->ns_sem);
  		}
  	}
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2322
2323
  
  	nilfs_segctor_notify(sci, mode, err);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2324
2325
2326
2327
2328
2329
  	return err;
  }
  
  static void nilfs_construction_timeout(unsigned long data)
  {
  	struct task_struct *p = (struct task_struct *)data;
4ad364ca1   Ryusuke Konishi   nilfs2: add missi...
2330

9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
  	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...
2342
  		list_del_init(&ii->i_dirty);
fbb24a3a9   Ryusuke Konishi   nilfs2: ensure pr...
2343
2344
  		truncate_inode_pages(&ii->vfs_inode.i_data, 0);
  		nilfs_btnode_cache_clear(&ii->i_btnode_cache);
263d90cef   Ryusuke Konishi   nilfs2: remove ow...
2345
  		iput(&ii->vfs_inode);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2346
2347
  	}
  }
4f6b82883   Ryusuke Konishi   nilfs2: fix lock ...
2348
2349
  int nilfs_clean_segments(struct super_block *sb, struct nilfs_argv *argv,
  			 void **kbufs)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2350
  {
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
2351
  	struct the_nilfs *nilfs = sb->s_fs_info;
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
2352
  	struct nilfs_sc_info *sci = nilfs->ns_writer;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2353
  	struct nilfs_transaction_info ti;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2354
2355
2356
2357
  	int err;
  
  	if (unlikely(!sci))
  		return -EROFS;
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2358
  	nilfs_transaction_lock(sb, &ti, 1);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2359

c1c1d7092   Ryusuke Konishi   nilfs2: get rid o...
2360
  	err = nilfs_mdt_save_to_shadow_map(nilfs->ns_dat);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2361
2362
  	if (unlikely(err))
  		goto out_unlock;
071cb4b81   Ryusuke Konishi   nilfs2: eliminate...
2363

4f6b82883   Ryusuke Konishi   nilfs2: fix lock ...
2364
  	err = nilfs_ioctl_prepare_clean_segments(nilfs, argv, kbufs);
c1c1d7092   Ryusuke Konishi   nilfs2: get rid o...
2365
2366
  	if (unlikely(err)) {
  		nilfs_mdt_restore_from_shadow_map(nilfs->ns_dat);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2367
  		goto out_unlock;
c1c1d7092   Ryusuke Konishi   nilfs2: get rid o...
2368
  	}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2369

071cb4b81   Ryusuke Konishi   nilfs2: eliminate...
2370
2371
  	sci->sc_freesegs = kbufs[4];
  	sci->sc_nfreesegs = argv[4].v_nmembs;
0935db747   Ryusuke Konishi   nilfs2: use list_...
2372
  	list_splice_tail_init(&nilfs->ns_gc_inodes, &sci->sc_gc_inodes);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2373
2374
  
  	for (;;) {
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2375
  		err = nilfs_segctor_construct(sci, SC_LSEG_SR);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2376
  		nilfs_remove_written_gcinodes(nilfs, &sci->sc_gc_inodes);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2377
2378
2379
  
  		if (likely(!err))
  			break;
d6517deb0   Ryusuke Konishi   nilfs2: replace n...
2380
  		nilfs_msg(sb, KERN_WARNING, "error %d cleaning segments", err);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2381
2382
2383
  		set_current_state(TASK_INTERRUPTIBLE);
  		schedule_timeout(sci->sc_interval);
  	}
3b2ce58b0   Ryusuke Konishi   nilfs2: move moun...
2384
  	if (nilfs_test_opt(nilfs, DISCARD)) {
e902ec990   Jiro SEKIBA   nilfs2: issue dis...
2385
2386
2387
  		int ret = nilfs_discard_segments(nilfs, sci->sc_freesegs,
  						 sci->sc_nfreesegs);
  		if (ret) {
feee880fa   Ryusuke Konishi   nilfs2: reduce ba...
2388
2389
2390
  			nilfs_msg(sb, KERN_WARNING,
  				  "error %d on discard request, turning discards off for the device",
  				  ret);
3b2ce58b0   Ryusuke Konishi   nilfs2: move moun...
2391
  			nilfs_clear_opt(nilfs, DISCARD);
e902ec990   Jiro SEKIBA   nilfs2: issue dis...
2392
2393
  		}
  	}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2394
2395
  
   out_unlock:
071cb4b81   Ryusuke Konishi   nilfs2: eliminate...
2396
2397
  	sci->sc_freesegs = NULL;
  	sci->sc_nfreesegs = 0;
c1c1d7092   Ryusuke Konishi   nilfs2: get rid o...
2398
  	nilfs_mdt_clear_shadow_map(nilfs->ns_dat);
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2399
  	nilfs_transaction_unlock(sb);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2400
2401
2402
2403
2404
  	return err;
  }
  
  static void nilfs_segctor_thread_construct(struct nilfs_sc_info *sci, int mode)
  {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2405
  	struct nilfs_transaction_info ti;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2406

f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2407
  	nilfs_transaction_lock(sci->sc_super, &ti, 0);
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2408
  	nilfs_segctor_construct(sci, mode);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2409
2410
2411
2412
2413
2414
2415
2416
  
  	/*
  	 * 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...
2417
  	nilfs_transaction_unlock(sci->sc_super);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2418
2419
2420
2421
2422
  }
  
  static void nilfs_segctor_do_immediate_flush(struct nilfs_sc_info *sci)
  {
  	int mode = 0;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2423
2424
2425
2426
2427
2428
2429
  
  	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) {
09ef29e0f   Ryusuke Konishi   nilfs2: fix gcc u...
2430
  		nilfs_segctor_do_construct(sci, mode);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
  
  		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...
2462
  	struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2463
  	int timeout = 0;
fdce895ea   Li Hong   nilfs2: change sc...
2464
2465
  	sci->sc_timer.data = (unsigned long)current;
  	sci->sc_timer.function = nilfs_construction_timeout;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2466
2467
2468
2469
  
  	/* start sync. */
  	sci->sc_task = current;
  	wake_up(&sci->sc_wait_task); /* for nilfs_segctor_start_thread() */
feee880fa   Ryusuke Konishi   nilfs2: reduce ba...
2470
2471
2472
  	nilfs_msg(sci->sc_super, KERN_INFO,
  		  "segctord starting. Construction interval = %lu seconds, CP frequency < %lu seconds",
  		  sci->sc_interval / HZ, sci->sc_mjcp_freq / HZ);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
  
  	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;
7f00184e9   Ryusuke Konishi   nilfs2: remove un...
2484
  		else if (sci->sc_flush_request)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2485
  			mode = nilfs_segctor_flush_mode(sci);
7f00184e9   Ryusuke Konishi   nilfs2: remove un...
2486
2487
  		else
  			break;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
  
  		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...
2498
  		try_to_freeze();
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
  		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...
2513
  					sci->sc_timer.expires);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2514
2515
2516
2517
2518
2519
2520
2521
  
  		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...
2522
  			   time_after_eq(jiffies, sci->sc_timer.expires));
e605f0a72   Ryusuke Konishi   nilfs2: get rid o...
2523
2524
  
  		if (nilfs_sb_dirty(nilfs) && nilfs_sb_need_update(nilfs))
1dfa27105   Jiro SEKIBA   nilfs2: stop usin...
2525
  			set_nilfs_discontinued(nilfs);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2526
2527
2528
2529
2530
  	}
  	goto loop;
  
   end_thread:
  	spin_unlock(&sci->sc_state_lock);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
  
  	/* 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);
feee880fa   Ryusuke Konishi   nilfs2: reduce ba...
2545
2546
  		nilfs_msg(sci->sc_super, KERN_ERR,
  			  "error %d creating segctord thread", err);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2547
2548
2549
2550
2551
2552
2553
  		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...
2554
2555
  	__acquires(&sci->sc_state_lock)
  	__releases(&sci->sc_state_lock)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
  {
  	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...
2566
2567
2568
  /*
   * Setup & clean-up functions
   */
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2569
  static struct nilfs_sc_info *nilfs_segctor_new(struct super_block *sb,
e912a5b66   Ryusuke Konishi   nilfs2: use root ...
2570
  					       struct nilfs_root *root)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2571
  {
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
2572
  	struct the_nilfs *nilfs = sb->s_fs_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2573
2574
2575
2576
2577
  	struct nilfs_sc_info *sci;
  
  	sci = kzalloc(sizeof(*sci), GFP_KERNEL);
  	if (!sci)
  		return NULL;
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2578
  	sci->sc_super = sb;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2579

e912a5b66   Ryusuke Konishi   nilfs2: use root ...
2580
2581
  	nilfs_get_root(root);
  	sci->sc_root = root;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2582
2583
2584
2585
2586
2587
  	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 ...
2588
  	INIT_LIST_HEAD(&sci->sc_write_logs);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2589
  	INIT_LIST_HEAD(&sci->sc_gc_inodes);
7ef3ff2fe   Ryusuke Konishi   nilfs2: fix deadl...
2590
2591
  	INIT_LIST_HEAD(&sci->sc_iput_queue);
  	INIT_WORK(&sci->sc_iput_work, nilfs_iput_work_func);
fdce895ea   Li Hong   nilfs2: change sc...
2592
  	init_timer(&sci->sc_timer);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2593
2594
2595
2596
  
  	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...
2597
  	if (nilfs->ns_interval)
071d73cfe   Ryusuke Konishi   nilfs2: fix probl...
2598
  		sci->sc_interval = HZ * nilfs->ns_interval;
574e6c314   Ryusuke Konishi   nilfs2: move para...
2599
2600
  	if (nilfs->ns_watermark)
  		sci->sc_watermark = nilfs->ns_watermark;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2601
2602
2603
2604
2605
2606
  	return sci;
  }
  
  static void nilfs_segctor_write_out(struct nilfs_sc_info *sci)
  {
  	int ret, retrycount = NILFS_SC_CLEANUP_RETRY;
076a378ba   Ryusuke Konishi   nilfs2: fix block...
2607
2608
2609
2610
  	/*
  	 * The segctord thread was stopped and its timer was removed.
  	 * But some tasks remain.
  	 */
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2611
  	do {
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2612
  		struct nilfs_transaction_info ti;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2613

f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2614
  		nilfs_transaction_lock(sci->sc_super, &ti, 0);
dcd761869   Ryusuke Konishi   nilfs2: get rid o...
2615
  		ret = nilfs_segctor_construct(sci, SC_LSEG_SR);
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2616
  		nilfs_transaction_unlock(sci->sc_super);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2617

7ef3ff2fe   Ryusuke Konishi   nilfs2: fix deadl...
2618
  		flush_work(&sci->sc_iput_work);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
  	} 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...
2632
  	struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2633
  	int flag;
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
2634
  	up_write(&nilfs->ns_segctor_sem);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2635
2636
2637
2638
2639
2640
  
  	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);
7ef3ff2fe   Ryusuke Konishi   nilfs2: fix deadl...
2641
2642
  	if (flush_work(&sci->sc_iput_work))
  		flag = true;
3256a0553   Ryusuke Konishi   nilfs2: fix poten...
2643
  	if (flag || !nilfs_segctor_confirm(sci))
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2644
  		nilfs_segctor_write_out(sci);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2645
  	if (!list_empty(&sci->sc_dirty_files)) {
d6517deb0   Ryusuke Konishi   nilfs2: replace n...
2646
2647
  		nilfs_msg(sci->sc_super, KERN_WARNING,
  			  "disposed unprocessed dirty file(s) when stopping log writer");
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
2648
  		nilfs_dispose_list(nilfs, &sci->sc_dirty_files, 1);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2649
  	}
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2650

7ef3ff2fe   Ryusuke Konishi   nilfs2: fix deadl...
2651
  	if (!list_empty(&sci->sc_iput_queue)) {
d6517deb0   Ryusuke Konishi   nilfs2: replace n...
2652
2653
  		nilfs_msg(sci->sc_super, KERN_WARNING,
  			  "disposed unprocessed inode(s) in iput queue when stopping log writer");
7ef3ff2fe   Ryusuke Konishi   nilfs2: fix deadl...
2654
2655
  		nilfs_dispose_list(nilfs, &sci->sc_iput_queue, 1);
  	}
1f5abe7e7   Ryusuke Konishi   nilfs2: replace B...
2656
  	WARN_ON(!list_empty(&sci->sc_segbufs));
a694291a6   Ryusuke Konishi   nilfs2: separate ...
2657
  	WARN_ON(!list_empty(&sci->sc_write_logs));
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2658

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

fdce895ea   Li Hong   nilfs2: change sc...
2662
  	del_timer_sync(&sci->sc_timer);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2663
2664
2665
2666
  	kfree(sci);
  }
  
  /**
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2667
2668
   * nilfs_attach_log_writer - attach log writer
   * @sb: super block instance
e912a5b66   Ryusuke Konishi   nilfs2: use root ...
2669
   * @root: root object of the current filesystem tree
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2670
   *
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2671
2672
   * This allocates a log writer object, initializes it, and starts the
   * log writer.
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2673
2674
2675
2676
2677
2678
   *
   * 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...
2679
  int nilfs_attach_log_writer(struct super_block *sb, struct nilfs_root *root)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2680
  {
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
2681
  	struct the_nilfs *nilfs = sb->s_fs_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2682
  	int err;
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
2683
  	if (nilfs->ns_writer) {
fe5f171bb   Ryusuke Konishi   nilfs2: fix poten...
2684
2685
2686
2687
2688
  		/*
  		 * 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...
2689
  		nilfs_detach_log_writer(sb);
fe5f171bb   Ryusuke Konishi   nilfs2: fix poten...
2690
  	}
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2691
  	nilfs->ns_writer = nilfs_segctor_new(sb, root);
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
2692
  	if (!nilfs->ns_writer)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2693
  		return -ENOMEM;
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
2694
  	err = nilfs_segctor_start_thread(nilfs->ns_writer);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2695
  	if (err) {
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
2696
2697
  		kfree(nilfs->ns_writer);
  		nilfs->ns_writer = NULL;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2698
2699
2700
2701
2702
  	}
  	return err;
  }
  
  /**
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2703
2704
   * nilfs_detach_log_writer - destroy log writer
   * @sb: super block instance
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2705
   *
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2706
2707
   * This kills log writer daemon, frees the log writer object, and
   * destroys list of dirty files.
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2708
   */
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
2709
  void nilfs_detach_log_writer(struct super_block *sb)
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2710
  {
e3154e974   Ryusuke Konishi   nilfs2: get rid o...
2711
  	struct the_nilfs *nilfs = sb->s_fs_info;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2712
2713
2714
  	LIST_HEAD(garbage_list);
  
  	down_write(&nilfs->ns_segctor_sem);
3fd3fe5ae   Ryusuke Konishi   nilfs2: move log ...
2715
2716
2717
  	if (nilfs->ns_writer) {
  		nilfs_segctor_destroy(nilfs->ns_writer);
  		nilfs->ns_writer = NULL;
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2718
2719
2720
  	}
  
  	/* Force to free the list of dirty files */
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
2721
2722
2723
  	spin_lock(&nilfs->ns_inode_lock);
  	if (!list_empty(&nilfs->ns_dirty_files)) {
  		list_splice_init(&nilfs->ns_dirty_files, &garbage_list);
d6517deb0   Ryusuke Konishi   nilfs2: replace n...
2724
2725
  		nilfs_msg(sb, KERN_WARNING,
  			  "disposed unprocessed dirty file(s) when detaching log writer");
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2726
  	}
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
2727
  	spin_unlock(&nilfs->ns_inode_lock);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2728
  	up_write(&nilfs->ns_segctor_sem);
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
2729
  	nilfs_dispose_list(nilfs, &garbage_list, 1);
9ff05123e   Ryusuke Konishi   nilfs2: segment c...
2730
  }