Page History
Introduction
If files are accidentally deleted from a file system, an application may be interrupted and the user data may be permanently lost. The recycle bin is a recommended feature in file systems that acts as a virtual trash can, allowing users to store deleted files temporarily before permanently deleting them. It provides a way to restore or retrieve deleted files if needed.
Once the recycle bin feature is enabled, when a user deletes a file from a file system, it is not actually deleted but moved to the recycle bin, deleted files and directories are temporarily stored in the recycle bin. The recycel bin may be manually emptied or once it is full, it will remove the oldest files first. Additionally, items in the recycle bin may be restored or retrieved if they are still there.
Recycle Bin Functionalities
The recycle bin should including the following functionalities:
List "undeleted" files in the recycle bin;
After a file is deleted and moved into recycle bin, the quota for this file should be accounted and updated (reduced) accordingly;
A file in the recycle bin is not visiable in the namespace of the file system;
Restore a file in the recycle bin. This will restore a file to its original path. The corresponding quota account should be updated also;
Delete a file in the recycle bin. This will finally remove the file from the file system and free the used space. The file is now unrecoverable;
Empty the recycle bin. This will remove all files in the recycle bin;
A user can restore files from recycle bin within the specified retention period. By this way, a file can be kept "undeleted" under a pre-defined configureable grace period.
Enable/disable recycle bin feature on a entire file system;
A administrator can enable/disable recycle bin feature on a specified directory;
Deleted files can no longer be restored from the recycle bin when:
A file (or directory) is deleted again from the recycle bin. In other words it have been deleted twice. The first deletion only moves the file to the recycle bin. The second deletion actually removes the file from the file system.
The recycle bin is emptied of all of its contents.
Design and Implementation
The design for the recycle bin feature in Lustre is simple.
On the server side, It just implements the basic functionalities such as moving the "undeleted" files into the cycle bin and the interface how to traverse them. On the client side, it implements the basic utility tools to interact with the recycle bin (lctl recycle set|clear|list|delete|restore xxx), including:
- Set or clear the recycle flag on a given file or directory;
- list "undeleted" files on a given MDT;
- Permantently delete a file within the recycle bin on a given MDT;
- Empty the recycle bin on a give MDT;
- Restore a file within the recycle bin on a give MDT;
Our mechanism only moves the regular files into the recycle bin upon its last unlink, but ignoring the directories.
It borrows lots of ideas from orphan and volatile files in Lustre (which stores in "ROOT/PENDING"" directory on each MDT). During the format and setup, each MDT creates a "ROOT/RECYCLE" directory as a recycle bin to store "undeleted" files.
The POSIX API is used to traverse the files under the recycle bin on a given MDT. First, a client can get the FID of recycle bin directory "ROOT/RECYCLE" on the MDT. Then the client can get the file handle via FID open: dir_fd=llapi_open_by_fid(); After that, the "undeleted" files within the recycle bin can be traversed via readdir(dir_fd); it can open by openat(dir_fd, ent->d_name) and obtain the "undeleted" XATTR, which contains the necessary information to resotre, via fgetxattr(fd, "trusted.recyclebin"); The client can even read the data or swap layouts of the "undeleted" file on the recycle bin for restore: opendir()/readddir()/openat()/fgetxattr("trusted.recyclebin")/close()/closedir();
The workflow for the recycle bin is as follows:
An administrator can enable/disable recycle bin feature on a specified MDT via: mdd.*.recycle_bin_enabled;
An adminstrator can enable/disable recycle bin feature on a specified directory or a file via the file flag: FS_UNRM_FL; All sub files under a directory flagged with FS_UNRM_FL can inherit this flag;
...
Provide the functionality to restore/delete all files within a given directory. This can be achieved by using the command combination of "lctl recycle list" and "lctl recycle restore" or "lctl recycle delete" to fileter the files with the full path attribute under a given directory.
Provide .lustre/recycle/MDT[N] (where N is the MDT index) filesystem namespace. By this way, users can access the "undeleted" files with readonly mode under the recycle bin directory on a given MDT[N] via POSIX file system API. However, we can not access these files from fileset sub directory mount. We can perform the following commands from a Lustre namespace (mount point of "/mnt/lustre") on a client:
# ls /mnt/lustre/.lustre/recycle/mdt0002MDT0002
0x200034021:0x1:0x0
0x200034021:0x2:0x0
...
# cat /mnt/lustre/.lustre/recycle/MDT0002/0x200034021:0x1:0x0
# lctl recycle info /mnt/lustre/.lustre/recycle/MDT0002/0x200034021:0x1:0x0
0 0 4096 Nov 14 08:11 [0x200034021:0x1:0x0]->/mnt/lustre/f1
# lctl recycle list /mnt/lustre/.lustre/recycle/MDT0002
MDT index: 1
uid gid size delete time FID Fullpath
0 0 4096 Nov 14 08:11 [0x200034021:0x1:0x0]->/mnt/lustre/f1
0 0 32104 Nov 14 08:07 [0x200034021:0x2:0x0]->/mnt/lustre/dir/f2
...
...