I need to remove millions of directories recursively on a NFS share and to avoid any performance issues, I ran the command with:

ionice -c 3 -t find /dir -type f -exec rm {};

which will delete all the files and the leftover empty directories, I can remove with rm -rf.

But I am unable to say if ionice has any effect on the above command.

From man, ionice class 3:

A program running with idle io priority will only get disk time when no other program has asked for disk io for a defined grace period. The impact of idle io processes on normal system activity should be zero.

From source code, I see that ionice sets ioprio_set.

So, what is ioprio_set?

The ioprio_get() and ioprio_set() system calls respectively get and set the I/O scheduling class and priority of one or more threads.

Does it mean that the process thread carries additional properties for I/O scheduler to use them to schedule the I/O for the process?

It begs me the following questions:

  • Does I/O scheduler in general knows I/O load on a disk or it just schedules I/O to disk?
  • If it's the case i.e. I/O scheduler knows about load on a disk and takes decisions based on that, I think the IO scheduling classes and priorities will not have any effect on IO scheduling to a remote disk. Thus ionice can not have any effect.
  • And if it's not, I think the IO scheduling classes and prioities can have effect on IO scheduling to a remote disk also like NFS. Thus ionice will work if multiple users/processes are using the same NFS disk, where the I/O scheduler schedules IO for a given thread based on if other user/procesess are using the same NFS disk.

Please correct me if I am utterly wrong.

There can be a way to perform the operation from server end also, but I want to first try from the client end.


Note that my answer assumes you're using Linux, as I'm pretty sure the ionice command is Linux specific.

The I/O scheduler operates at the block layer, not the filesystem layer. As a result, it only has an effect on local storage devices and remotely attached block storage (such as NBD, iSCSI, or ATAoE connected storage devices). As a result, there is no special I/O scheduling done for a NFS share on the NFS client (but the server still does it, it just doesn't know about the remote I/O priorities), but might be for iSCSI, NBD, or ATAoE devices (many distros will set these up with the no-op scheduler however, which means that the only I/O scheduling is done on the server side here too). The only possible case in which it would impact NFS is if you're using pNFS with the block layout, but you probably arent and I'm not quite sure how that interacts with the block layer, so I'm just going to ignore that).

As far as what the I/O priority actually does, that depends on the specific I/O scheduler you're using. At a minimum, the noop and deadline (and possibly the new mq-deadline) schedulers don't pay any attention to it at all, while CFQ, BFQ, and I think the new Kyber scheduler do something with it, but they don't do the exact same things with it. As far as I know, for CFQ, classes behave similarly to the equivalent CPU scheduling classes (with the real-time I/O class behaving like the RT FIFO CPU scheduling class). I believe that BFQ just uses them as hints for it's scheduling algorithm (as opposed to the more significant impact they have with CFQ), but I'm not certain about that.

Now, regarding your particular example, ionice should have no impact there at all, but it likely wouldn't have much impact on a local filesystem either unless the disk was already fully utilized by other processes (the 'idle' scheduling class you specified isn't a true idle scheduler, but even if it were, find doesn't use much disk time most of the time, and the rm command uses even less).

Also, a slightly off-topic side note, but the find command you quoted will only remove files (because of the -type f option), so it's not exactly equivalent to rm -rf, and you could improve its (local) performance by replacing the -exec rm {} ; with -delete, which does the same thing without needing to create a new process for each file it's deleting.

| improve this answer | |
  • Thanks, the find command was written in hurry and to avoid chance of removing (. and .. ) directories, I used -type f. – GP92 Jan 17 '18 at 7:14
  • And when you said that find doesn't use much disk time most of the time, do you mean that find and exec rm {} doesn't cause any resource throttling when compared to rm -rf for a Netapp NFS? Actually, I have read some netapp articles saying rm -rf should not run for large recursive trees and should be done on small subset bases. Hence, I was using the find command. I can't find those articles now anywhere. – GP92 Jan 17 '18 at 7:27
  • @JeevanPatnaik find is usually not hugely I/O intensive, since it mostly just calls stat() on everything (which is slow, but not I/O intensive). As far as the NetApp advice, your find command is not likely to be much better (it's probably the storm of unlink() commands that causes issues for NetApp, which will still be present with the find command you used). Also, for future reference, you're usually better off using ! -name . ! -name .. to exclude the . and .. entries in that command than using -type f. – Austin Hemmelgarn Jan 17 '18 at 13:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.