Hi,
On Sun, 14 Mar 2010 09:47:55 +0100, David Arendt wrote:
> Hi,
> 
> In order to avoid working both at the same thing, do you think about
> implementing this yourself in near future or do you prefer that I try
> implementing it myself and send you a patch ?

I'd appreciate it if you try it yourself.  I cannot commit time to
this at least for a few weeks.

> For the case where you prefer that I try implementing it, here a quick
> information in natural language how I would implement this in order to
> see if I am thinking it correctly (line beginning with *** are changed):
> 
> 1166 /**
> 1167  * nilfs_cleanerd_clean_loop - main loop of the cleaner daemon
> 1168  * @cleanerd: cleanerd object
> 1169  */
> 1170 static int nilfs_cleanerd_clean_loop(struct nilfs_cleanerd *cleanerd)
> 1171 {
> 1172         struct nilfs_sustat sustat;
> 1173         __u64 prev_nongc_ctime = 0, prottime = 0, oldest = 0;
> 1174         __u64 segnums[NILFS_CLDCONFIG_NSEGMENTS_PER_CLEAN_MAX];
> 
> ***            _u64 previousfirstsegnum = max value of _u64;
> 
> 1175         struct timespec timeout;
> 1176         sigset_t sigset;
> 1177         int ns, ret;
> 1178
> 1179         sigemptyset(&sigset);
> 1180         if (sigprocmask(SIG_SETMASK, &sigset, NULL) < 0) {
> 1181                 syslog(LOG_ERR, "cannot set signal mask: %m");
> 1182                 return -1;
> 1183         }
> 1184         sigaddset(&sigset, SIGHUP);
> 1185
> 1186         if (set_sigterm_handler() < 0) {
> 1187                 syslog(LOG_ERR, "cannot set SIGTERM signal handler:
> %m");
> 1188                 return -1;
> 1189         }
> 1190         if (set_sighup_handler() < 0) {
> 1191                 syslog(LOG_ERR, "cannot set SIGHUP signal handler:
> %m");
> 1192                 return -1;
> 1193         }
> 1194
> 1195         nilfs_cleanerd_reload_config = 0;
> 1196
> 1197         ret = nilfs_cleanerd_init_interval(cleanerd);
> 1198         if (ret < 0)
> 1199                 return -1;
> 1200
> 1201         cleanerd->c_running = 1;
> 1202         cleanerd->c_ncleansegs =
> cleanerd->c_config.cf_nsegments_per_clean;
> 1203
> 1204         while (1) {
> 1205                 if (sigprocmask(SIG_BLOCK, &sigset, NULL) < 0) {
> 1206                         syslog(LOG_ERR, "cannot set signal mask: %m");
> 1207                         return -1;
> 1208                 }
> 1209
> 1210                 if (nilfs_cleanerd_reload_config) {
> 1211                         if (nilfs_cleanerd_reconfig(cleanerd)) {
> 1212                                 syslog(LOG_ERR, "cannot configure:
> %m");
> 1213                                 return -1;
> 1214                         }
> 1215                         nilfs_cleanerd_reload_config = 0;
> 1216                         syslog(LOG_INFO, "configuration file
> reloaded");
> 1217                 }
> 1218
> 1219                 if (nilfs_get_sustat(cleanerd->c_nilfs, &sustat) < 0) {
> 1220                         syslog(LOG_ERR, "cannot get segment usage
> stat: %m");
> 1221                         return -1;
> 1222                 }
> 1223                 if (sustat.ss_nongc_ctime != prev_nongc_ctime) {
> 1224                         cleanerd->c_running = 1;
> 1225                         prev_nongc_ctime = sustat.ss_nongc_ctime;
> 1226                 }
> 1227                 if (!cleanerd->c_running)
> 1228                         goto sleep;
> 1229
> 1230                 syslog(LOG_DEBUG, "ncleansegs = %llu",
> 1231                        (unsigned long long)sustat.ss_ncleansegs);
> 1232
> 1233                 ns = nilfs_cleanerd_select_segments(
> 1234                         cleanerd, &sustat, segnums, &prottime,
> &oldest);
> 1235                 if (ns < 0) {
> 1236                         syslog(LOG_ERR, "cannot select segments: %m");
> 1237                         return -1;
> 1238                 }
> 
> ***                    if ((in_configfile_defined_treshold > 0) &&
> (segnums[0] < previousfirstsegnum)) // one full pass finished or first pass
>                          {
>                             if more than in_configfile_defined_treshold
> space available (defined in configfile)
>                             {
>                                set timout to
> in_configfile_definied_checktime secs;
>                                goto sleep;
>                             }
>                          }
> 
>                          previousfirstsegum = segnums[0];
> 
> 1239                 syslog(LOG_DEBUG, "%d segment%s selected to be
> cleaned",
> 1240                        ns, (ns <= 1) ? "" : "s");
> 1241                 if (ns > 0) {
> 1242                         ret = nilfs_cleanerd_clean_segments(
> 1243                                 cleanerd, &sustat, segnums, ns,
> prottime);
> 1244                         if (ret < 0)
> 1245                                 return -1;
> 1246                 }
> 1247
> 1248                 ret = nilfs_cleanerd_recalc_interval(
> 1249                         cleanerd, ns, prottime, oldest, &timeout);
> 1250                 if (ret < 0)
> 1251                         return -1;
> 1252                 else if (ret > 0)
> 1253                         continue;
> 1254  sleep:
> 1255                 if (sigprocmask(SIG_UNBLOCK, &sigset, NULL) < 0) {
> 1256                         syslog(LOG_ERR, "cannot set signal mask: %m");
> 1257                         return -1;
> 1258                 }
> 1259
> 1260                 ret = nilfs_cleanerd_sleep(cleanerd, &timeout);
> 1261                 if (ret < 0)
> 1262                         return -1;
> 1263         }
> 1264 }
> 
> I suppose that calling nilfs_get_sustat and
> nilfs_cleanerd_select_segments without actually cleaning wouldn't cause
> problems

Yes, this is correct.

> and nilfs_cleanerd_select_segments would always return the
> first segment equal or less than the one from last call
> or am I wrong with this ?

Seems misunderstanding.

nilfs_cleanerd_select_segments returns the number of selected segments
for a shot of cleaning; if you set nsegments_per_clean = 2, this
function returns equal or less than two.

> Is there a nilfs specific function I should use to determine the
> free space available or should I use statfs ?

Actually, the free space reported by statfs is calculated from the
number of free segments.  So it's internally equivalent.

You can refer to sustat.ss_ncleansegs for the number of free segments
and sustat.ss_nsegs for the total number of segments.  I think
nilfs_get_sustat() is appropriate for your purpose because it's
already used in the loop function.

> Thanks in advance,
> Bye,
> David Arendt

With regards,
Ryusuke Konishi

 
> On 03/14/10 06:26, Ryusuke Konishi wrote:
> > Hi,
> > On Sat, 13 Mar 2010 21:49:43 +0100, David Arendt wrote:
> >   
> >> Hi,
> >>
> >> In order to reduce cleaner io, I am thinking it could be usefull to
> >> implement a parameter where you can specify the minimum free space. If
> >> this parameter is set, instead of normal cleaning operation, the cleaner
> >> would wait until there is less than minimum free space available and
> >> then run one cleaning pass (from first to last segment). If after that,
> >> there is again more than minimum free space available, continue waiting,
> >> otherwise run cleaning passes until there is more than minimum free
> >> space available.
> >>
> >> What would you think about this idea ?
> >>
> >> Bye,
> >> David Arendt
> >>     
> > Well, I think this is one of what cleaner should take in.  It can
> > prevent cleanerd from moving in-use blocks too often unless the actual
> > free space is less than the threshold.
> >
> > It may be the first thing to do since it's not difficult in principle.
> >
> > I recognize there are more fundamental defects in the current cleaner:
> >
> >  * It moves blocks in selected segments even if all of their blocks
> >    are in-use.
> >
> >  * It doesn't give priority to reclaiming segments which have many
> >    obsolete blocks.
> >
> >  * It keeps working without considering io workload of the time.
> >
> > But, I'd rather take a quick fix like your proposal.
> >
> > Regards,
> > Ryusuke Konishi
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-nilfs" in
> > the body of a message to majord...@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-nilfs" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to