示例#1
0
文件: lssu.c 项目: konis/nilfs-utils
static ssize_t lssu_print_suinfo(struct nilfs *nilfs, uint64_t segnum,
				 ssize_t nsi, uint64_t protseq)
{
	struct tm tm;
	time_t t;
	char timebuf[LSSU_BUFSIZE];
	ssize_t i, n = 0, ret;
	int ratio;
	int protected;
	size_t nliveblks;

	for (i = 0; i < nsi; i++, segnum++) {
		if (!all && nilfs_suinfo_clean(&suinfos[i]))
			continue;

		t = (time_t)suinfos[i].sui_lastmod;
		if (t != 0) {
			localtime_r(&t, &tm);
			strftime(timebuf, LSSU_BUFSIZE, "%F %T", &tm);
		} else
			snprintf(timebuf, LSSU_BUFSIZE,
				 "---------- --:--:--");

		switch (disp_mode) {
		case LSSU_MODE_NORMAL:
			printf(lssu_format[disp_mode].body,
			       (unsigned long long)segnum,
			       timebuf,
			       nilfs_suinfo_active(&suinfos[i]) ? 'a' : '-',
			       nilfs_suinfo_dirty(&suinfos[i]) ? 'd' : '-',
			       nilfs_suinfo_error(&suinfos[i]) ? 'e' : '-',
			       suinfos[i].sui_nblocks);
			break;
		case LSSU_MODE_LATEST_USAGE:
			nliveblks = 0;
			ratio = 0;
			protected = (t >= prottime && t <= now);

			if (!nilfs_suinfo_dirty(&suinfos[i]) ||
			    nilfs_suinfo_error(&suinfos[i]))
				goto skip_scan;

			ret = lssu_get_latest_usage(nilfs, segnum, protseq,
						    protcno);
			if (ret >= 0) {
				nliveblks = ret;
				ratio = (ret * 100 + 99) / blocks_per_segment;
			} else if (likely(ret == -2)) {
				nliveblks = suinfos[i].sui_nblocks;
				ratio = 100;
				protected = 1;
			} else {
示例#2
0
static ssize_t lssu_print_suinfo(__u64 segnum, ssize_t nsi, int all)
{
	struct tm tm;
	time_t t;
	char timebuf[LSSU_BUFSIZE];
	ssize_t i, n = 0;

	for (i = 0; i < nsi; i++, segnum++) {
		if (all || !nilfs_suinfo_clean(&suinfos[i])) {
			t = (time_t)suinfos[i].sui_lastmod;
			if (t != 0) {
				localtime_r(&t, &tm);
				strftime(timebuf, LSSU_BUFSIZE, "%F %T", &tm);
			} else
				snprintf(timebuf, LSSU_BUFSIZE,
					 "---------- --:--:--");

			printf("%20llu  %s  %c%c%c  %10u\n",
			       (unsigned long long)segnum,
			       timebuf,
			       nilfs_suinfo_active(&suinfos[i]) ? 'a' : '-',
			       nilfs_suinfo_dirty(&suinfos[i]) ? 'd' : '-',
			       nilfs_suinfo_error(&suinfos[i]) ? 'e' : '-',
			       suinfos[i].sui_nblocks);
			n++;
		}
	}
	return n;
}
示例#3
0
static ssize_t lssu_print_suinfo(struct nilfs *nilfs, __u64 segnum,
				 ssize_t nsi, __u64 protseq,
				 unsigned long* bitmap)
{
	ssize_t i, n = 0;
	int all = 1;

	for (i = 0; i < nsi; i++, segnum++) {
		if (!all && nilfs_suinfo_clean(&suinfos[i]))
			continue;

			log_mesg(3, 0, 0, fs_opt.debug, "%s: seg %llu, %c %c %c , %i\n",
			       __FILE__, (unsigned long long)segnum,
			       nilfs_suinfo_active(&suinfos[i]) ? 'a' : '-',
			       nilfs_suinfo_dirty(&suinfos[i]) ? 'd' : '-',
			       nilfs_suinfo_error(&suinfos[i]) ? 'e' : '-',
			       suinfos[i].sui_nblocks);
		if  (nilfs_suinfo_active(&suinfos[i]) || nilfs_suinfo_dirty(&suinfos[i])){
		    set_bitmap(bitmap, (unsigned long long)segnum,  suinfos[i].sui_nblocks);
		}
		n++;
	}
	return n;
}
示例#4
0
/**
 * nilfs_sufile_set_suinfo - sets segment usage info
 * @sufile: inode of segment usage file
 * @buf: array of suinfo_update
 * @supsz: byte size of suinfo_update
 * @nsup: size of suinfo_update array
 *
 * Description: Takes an array of nilfs_suinfo_update structs and updates
 * segment usage accordingly. Only the fields indicated by the sup_flags
 * are updated.
 *
 * Return Value: On success, 0 is returned. On error, one of the
 * following negative error codes is returned.
 *
 * %-EIO - I/O error.
 *
 * %-ENOMEM - Insufficient amount of memory available.
 *
 * %-EINVAL - Invalid values in input (segment number, flags or nblocks)
 */
ssize_t nilfs_sufile_set_suinfo(struct inode *sufile, void *buf,
				unsigned int supsz, size_t nsup)
{
	struct the_nilfs *nilfs = sufile->i_sb->s_fs_info;
	struct buffer_head *header_bh, *bh;
	struct nilfs_suinfo_update *sup, *supend = buf + supsz * nsup;
	struct nilfs_segment_usage *su;
	void *kaddr;
	unsigned long blkoff, prev_blkoff;
	int cleansi, cleansu, dirtysi, dirtysu;
	long ncleaned = 0, ndirtied = 0;
	int ret = 0;

	if (unlikely(nsup == 0))
		return ret;

	for (sup = buf; sup < supend; sup = (void *)sup + supsz) {
		if (sup->sup_segnum >= nilfs->ns_nsegments
			|| (sup->sup_flags &
				(~0UL << __NR_NILFS_SUINFO_UPDATE_FIELDS))
			|| (nilfs_suinfo_update_nblocks(sup) &&
				sup->sup_sui.sui_nblocks >
				nilfs->ns_blocks_per_segment))
			return -EINVAL;
	}

	down_write(&NILFS_MDT(sufile)->mi_sem);

	ret = nilfs_sufile_get_header_block(sufile, &header_bh);
	if (ret < 0)
		goto out_sem;

	sup = buf;
	blkoff = nilfs_sufile_get_blkoff(sufile, sup->sup_segnum);
	ret = nilfs_mdt_get_block(sufile, blkoff, 1, NULL, &bh);
	if (ret < 0)
		goto out_header;

	for (;;) {
		kaddr = kmap_atomic(bh->b_page, KM_USER0);
		su = nilfs_sufile_block_get_segment_usage(
			sufile, sup->sup_segnum, bh, kaddr);

		if (nilfs_suinfo_update_lastmod(sup))
			su->su_lastmod = cpu_to_le64(sup->sup_sui.sui_lastmod);

		if (nilfs_suinfo_update_nblocks(sup))
			su->su_nblocks = cpu_to_le32(sup->sup_sui.sui_nblocks);

		if (nilfs_suinfo_update_flags(sup)) {
			/*
			 * Active flag is a virtual flag projected by running
			 * nilfs kernel code - drop it not to write it to
			 * disk.
			 */
			sup->sup_sui.sui_flags &=
					~(1UL << NILFS_SEGMENT_USAGE_ACTIVE);

			cleansi = nilfs_suinfo_clean(&sup->sup_sui);
			cleansu = nilfs_segment_usage_clean(su);
			dirtysi = nilfs_suinfo_dirty(&sup->sup_sui);
			dirtysu = nilfs_segment_usage_dirty(su);

			if (cleansi && !cleansu)
				++ncleaned;
			else if (!cleansi && cleansu)
				--ncleaned;

			if (dirtysi && !dirtysu)
				++ndirtied;
			else if (!dirtysi && dirtysu)
				--ndirtied;

			su->su_flags = cpu_to_le32(sup->sup_sui.sui_flags);
		}

		kunmap_atomic(kaddr, KM_USER0);

		sup = (void *)sup + supsz;
		if (sup >= supend)
			break;

		prev_blkoff = blkoff;
		blkoff = nilfs_sufile_get_blkoff(sufile, sup->sup_segnum);
		if (blkoff == prev_blkoff)
			continue;

		/* get different block */
		mark_buffer_dirty(bh);
		put_bh(bh);
		ret = nilfs_mdt_get_block(sufile, blkoff, 1, NULL, &bh);
		if (unlikely(ret < 0))
			goto out_mark;
	}
	mark_buffer_dirty(bh);
	put_bh(bh);

 out_mark:
	if (ncleaned || ndirtied) {
		nilfs_sufile_mod_counter(header_bh, (u64)ncleaned,
				(u64)ndirtied);
		NILFS_SUI(sufile)->ncleansegs += ncleaned;
	}
	nilfs_mdt_mark_dirty(sufile);
 out_header:
	put_bh(header_bh);
 out_sem:
	up_write(&NILFS_MDT(sufile)->mi_sem);
	return ret;
}