Storage Management with btrfs

Introduction


To quote the description on the Btrfs Wiki: “Btrfs is a new copy on write filesystem for Linux aimed at implementing advanced features while focusing on fault tolerance, repair and easy administration. Initially developed by Oracle, Btrfs is licensed under the GPL and open for contribution from anyone.”

The file system offers a vast amount of features and functionality that clearly sets it apart from other file systems available for Linux:




  • Extent based file storage
  • 2^64 byte == 16 EiB maximum file size
  • Space-efficient packing of small files
  • Space-efficient indexed directories
  • Dynamic inode allocation
  • Writable snapshots, read-only snapshots
  • Subvolumes (separate internal filesystem roots)
  • Checksums on data and metadata
  • Compression (gzip and LZO)
  • Integrated multiple device support: RAID-0, RAID-1 and RAID-10 implementations
  • Efficient incremental backups
  • Background scrub process for finding and fixing errors on files with redundant copies
  • Online file system defragmentation
The Btfs file system is included in the Unbreakable Enterprise Kernel Release 2 (2.6.39), as installed on the Oracle Linux 6.3 VirtualBox appliance. In fact, the root filesystem of that virtual machine is using Btrfs already.
If you want to learn more about Btrfs, the Oracle Linux Administrator’s Solutions Guide for Release 6 has a dedicated chapter about the file system.

Lab requirements

  • A virtual machine running Oracle Linux 6 with the Unbreakable Enterprise Kernel Release 2 (2.6.39).
  • Two additional empty virtual disks (these should already exist when you use the provided virtual appliance).
[oracle@oraclelinux6 ~]$ sudo umount /cryptfs
[oracle@oraclelinux6 ~]$ sudo rmdir /cryptfs
[oracle@oraclelinux6 ~]$ sudo rm -f /etc/crypttab
[oracle@oraclelinux6 ~]$ sudo cryptsetup luksClose cryptfs

Also, ensure to remove the /cryptfs mount point from /etc/fstab, to avoid errors during the next reboot.
Most of the following exercises will being performed using the btrfs command line utility, which belongs to the package btrfs-progs on Oracle Linux. It has already been installed on the Oracle Linux VirtualBox appliance:
[oracle@oraclelinux6 ~]$ rpm -q btrfs-progs
btrfs-progs-0.20-0.2.git91d9eec.0.1.el6.x86_64


Exercise: Creating and mounting a file system

A Btrfs file system can be created on a block device or logical volume like any other file system, using the mkfs.btrfs utility.
In its simplest form it can be invoked like as follows. Btrfs assumes safe/reasonable defaults – check the mkfs.btrfs manual page for more info on the available options.

mkfs.btrfs <device>
After the file system has been created, it can be mounted manually:
mount -t btrfs <device> <mountpoint>
To mount the file system at bootup time, edit /etc/fstab file and add an entry similar to this one:
<device> <mountpoint>    btrfs   defaults   0  0
The following example creates a partition on the second disk drive (/dev/sdb), creates a btrfs file system on top of it and mounts it to the /storage mount point:
oracle@oraclelinux6 ~]$ sudo fdisk /dev/sdb
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
Building a new DOS disklabel with disk identifier 0xe6629fd3.
Changes will remain in memory only, until you decide to write them.
After that, of course, the previous content won't be recoverable.

Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)

WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
         switch off the mode (command 'c') and change display units to
         sectors (command 'u').

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-522, default 1): 1
Last cylinder, +cylinders or +size{K,M,G} (1-522, default 522): 522


Command (m for help): p
Disk /dev/sdb: 4294 MB, 4294967296 bytes
255 heads, 63 sectors/track, 522 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0xe6629fd3

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1               1         522     4192933+  83  Linux
Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.
[oracle@oraclelinux6 ~]$ sudo mkfs.btrfs /dev/sdb1
WARNING! - Btrfs Btrfs v0.20-rc1 IS EXPERIMENTAL
WARNING! - see http://btrfs.wiki.kernel.org before using

fs created label (null) on /dev/sdb1
 nodesize 4096 leafsize 4096 sectorsize 4096 size 4.00GB
Btrfs Btrfs v0.20-rc1
[oracle@oraclelinux6 ~]$ sudo mkdir -v /storage
mkdir: created directory `/storage'
Now edit /etc/fstab using your preferred editor and add the following line to the end of the file:
/dev/sdb1   /storage   btrfs    defaults    0 0
Now we can mount the file system (and it will be mounted automatically on the next reboot):
[oracle@oraclelinux6 ~]$ sudo mount -v /storage
/dev/sdb1 on /storage type btrfs (rw)
[oracle@oraclelinux6 ~]$ ls -l /storage
total 0
[oracle@oraclelinux6 ~]$ df -h /storage

Filesystem            Size  Used Avail Use% Mounted on
/dev/sdb1             4.0G   56K  3.6G   1% /storage

At this point, a Btrfs file system does not behave any different than any other Linux file system. You can create directories and files, change permissions and ownerships and so on. Let’s continue with the more advanced features!

Exercise: Snapshotting a file

Using Btrfs, one can create lightweight copies of a file using the cp --reflink command. With this option, the file system does not create a new link pointing to an existing inode, it rather creates a new inode that shares the same disk blocks as the existing file. The outcome looks very much like a copy of the original file, but the actual data blocks have not been duplicated. Because of this, this operation only works within the boundaries of the same file system/subvolume.
This saves disk space and allows the operation to perform much quicker than actually copying the entire file. Due to the copy-on-write nature, a write to either file will cause some or all of the blocks to be duplicated. A modification of one of the files will not be visible in the other file. Note that this should not be confused with hard links – this web page provides a good explanation of the differences.
File snapshots can be quite useful if you need to create copies of very large files that differ very little from each other, e.g. like virtual machine images. In this case the disk space savings can be quite significant.
In the example below, we first create a 100 MB testfile, filled with random data. Then we first copy it five times, using the regular file system copy command. Observe how the disk space usage increases with each copy of the file. Then we repeat the copying using the --reflink option. And even though the five additional files appear in a similar fashion (just much quicker), no additional disk space is required, until we would start modifying any of the files.
[oracle@oraclelinux6 ~]$ cd /storage ; pwd ; df -h .
/storage
Filesystem         Size  Used Avail Use% Mounted on
/dev/sdb1          4.0G   56K  3.6G   1% /storage
[oracle@oraclelinux6 storage]$ sudo dd if=/dev/urandom of=testfile bs=1k count=100000
100000+0 records in
100000+0 records out
102400000 bytes (102 MB) copied, 15.3187 s, 6.7 MB/s
[oracle@oraclelinux6 storage]$ ls -lh ; df -h .
total 98M
-rw-r--r--. 1 root root 98M Aug 17 15:24 testfile
Filesystem         Size  Used Avail Use% Mounted on
/dev/sdb1           4.0G   99M  3.3G   3% /storage
[oracle@oraclelinux6 storage]$ time for a in 1 2 3 4 5 ; do sudo cp -v testfile testfile.$a ; sync; df -h . ; done
`testfile' -> `testfile.1'
Filesystem            Size  Used Avail Use% Mounted on
/dev/sdb1             4.0G  197M  3.2G   6% /storage
`testfile' -> `testfile.2'
Filesystem            Size  Used Avail Use% Mounted on
/dev/sdb1             4.0G  294M  3.1G   9% /storage
`testfile' -> `testfile.3'
Filesystem            Size  Used Avail Use% Mounted on
/dev/sdb1             4.0G  392M  3.0G  12% /storage
`testfile' -> `testfile.4'
Filesystem            Size  Used Avail Use% Mounted on
/dev/sdb1             4.0G  490M  2.9G  15% /storage
`testfile' -> `testfile.5'
Filesystem            Size  Used Avail Use% Mounted on
/dev/sdb1             4.0G  588M  2.8G  18% /storage

real 0m19.071s
user 0m0.046s
sys 0m0.456s
[oracle@oraclelinux6 ~]$ ls -lh
total 586M
-rw-r--r--. 1 root root 98M Aug 17 15:24 testfile
-rw-r--r--. 1 root root 98M Aug 17 15:34 testfile.1
-rw-r--r--. 1 root root 98M Aug 17 15:34 testfile.2
-rw-r--r--. 1 root root 98M Aug 17 15:34 testfile.3
-rw-r--r--. 1 root root 98M Aug 17 15:35 testfile.4
-rw-r--r--. 1 root root 98M Aug 17 15:35 testfile.5
[oracle@oraclelinux6 storage]$ sudo rm testfile.* ; sync ; df -h .
Filesystem          Size  Used Avail Use% Mounted on
/dev/sdb1           4.0G   99M  3.3G   3% /storage
[oracle@oraclelinux6 storage]$ time for a in 1 2 3 4 5 ; do sudo cp -v --reflink testfile testfile.$a ; sync; df -h . ; done
`testfile' -> `testfile.1'
Filesystem            Size  Used Avail Use% Mounted on
/dev/sdb1             4.0G   99M  3.3G   3% /storage
`testfile' -> `testfile.2'
Filesystem            Size  Used Avail Use% Mounted on
/dev/sdb1             4.0G   99M  3.3G   3% /storage
`testfile' -> `testfile.3'
Filesystem            Size  Used Avail Use% Mounted on
/dev/sdb1             4.0G   99M  3.3G   3% /storage
`testfile' -> `testfile.4'
Filesystem            Size  Used Avail Use% Mounted on
/dev/sdb1             4.0G   99M  3.3G   3% /storage
`testfile' -> `testfile.5'
Filesystem            Size  Used Avail Use% Mounted on
/dev/sdb1             4.0G   99M  3.3G   3% /storage

real 0m0.335s
user 0m0.029s
sys 0m0.068s
[oracle@oraclelinux6 storage]$ ls -lh
total 586M
-rw-r--r--. 1 root root 98M Aug 17 15:24 testfile
-rw-r--r--. 1 root root 98M Aug 17 15:36 testfile.1
-rw-r--r--. 1 root root 98M Aug 17 15:36 testfile.2
-rw-r--r--. 1 root root 98M Aug 17 15:36 testfile.3
-rw-r--r--. 1 root root 98M Aug 17 15:36 testfile.4
-rw-r--r--. 1 root root 98M Aug 17 15:36 testfile.5
[oracle@oraclelinux6 storage]$ sudo rm testfile* ; sync ; df -h .

Filesystem Size Used Avail Use% Mounted on /dev/sdb1 4.0G 99M 3.3G 3% /storage
Exercise: Creating Snapshots and Subvolumes


In addition to being able to create lightweight copies (snapshots) of individual files, Btrfs also supports the creation of subvolumes and writable snapshots of these. In this case, an entire directory structure including the files contained therein are treated as an entity and can be frozen atomically at any point in time. This can be useful to preserve the state of a directory structure at any given point in time, e.g. for backup or archiving purposes.
The following commands are utilized for creating and working with subvolumes and snapshots – please check the btrfs(8) manual page for more Details.
btrfs subvolume create <path to subvolume>
btrfs subvolume delete <path to subvolume>
btrfs subvolume snapshot <volume> <snapshot volume>
btrfs subvolume list <volume>

In the following example, we’re going to create a new subvolume src in our /storage file system, populate it with some data and create a snapshot of it. We then modify the data and compare it with the content of the snapshot volume. Finally, we remove the snapshot volume again.
[oracle@oraclelinux6 ~]$ sudo btrfs filesystem show
Label: none  uuid: 89810a0a-7ed4-4756-a1df-c159ddd14dcd
 Total devices 1 FS bytes used 3.46GB
 devid    1 size 7.53GB used 6.29GB path /dev/dm-0

Label: none  uuid: 49faa23f-d87c-4786-8741-cc25eeaa0592
 Total devices 1 FS bytes used 97.99MB
 devid    1 size 4.00GB used 1.48GB path /dev/sdb1

Btrfs Btrfs v0.20-rc1
[oracle@oraclelinux6 ~]$ cd /storage
[oracle@oraclelinux6 storage]$ sudo btrfs subvolume create src ; ls -l

Create subvolume './src'
total 0
drwx------ 1 root root 0 Jan 10 13:06 src
[oracle@oraclelinux6 storage]$ sudo chmod 755 src
[oracle@oraclelinux6 storage]$ sudo cp -a /usr/src/kernels src/
[oracle@oraclelinux6 storage]$ ls -l src/

total 0
drwxr-xr-x. 1 root root 116 Nov 30 07:27 kernels
[oracle@oraclelinux6 storage]$ df -h .
Filesystem            Size  Used Avail Use% Mounted on
/dev/sdb1             4.0G  114M  3.3G   4% /storage
[oracle@oraclelinux6 storage]$ sudo btrfs subvolume snapshot src src-snap
Create a snapshot of 'src' in './src-snap'
[oracle@oraclelinux6 storage]$ ls -l

total 0
drwxr-xr-x 1 root root 14 Jan 10 13:08 src
drwxr-xr-x 1 root root 14 Jan 10 13:08 src-snap
[oracle@oraclelinux6 storage]$ df -h .
Filesystem            Size  Used Avail Use% Mounted on
/dev/sdb1             4.0G  114M  3.3G   4% /storage
[oracle@oraclelinux6 storage]$ sudo btrfs subvolume list .
ID 260 top level 5 path src
ID 261 top level 5 path src-snap
[oracle@oraclelinux6 storage]$ sudo cp -a /opt/VBoxGuestAdditions-4.2.4 src
[oracle@oraclelinux6 storage]$ ls -l src src-snap

src:
total 0
drwxr-xr-x. 1 root root 116 Nov 30 07:27 kernels
drwxr-xr-x  1 root root 104 Nov 30 07:09 VBoxGuestAdditions-4.2.4

src-snap:
total 0
drwxr-xr-x. 1 root root 116 Nov 30 07:27 kernels
[oracle@oraclelinux6 storage]$ sudo btrfs subvolume delete src-snap
Delete subvolume '/storage/src-snap'
[oracle@oraclelinux6 storage]$ ls
src
[oracle@oraclelinux6 storage]$ sudo btrfs subvolume list .
ID 260 top level 5 path src
[oracle@oraclelinux6 storage]$ sudo btrfs subvolume delete src
Delete subvolume '/storage/src'
[oracle@oraclelinux6 storage]$ cd ~

Exercise: Setting up Mirroring/Striping


Btrfs supports various methods to spread data across multiple devices, either to increase performance or to provide reduncancy.
When creating a file system, you can define how the data and metadata should be distributed across the devices specified.
Currently, Btrfs on Oracle Linux supports the following profiles: raid0, raid1, raid10, and single.
The general command syntax is as follows:
mkfs.btrfs <device1> <device2> <device3>
mkfs.btrfs -m <profile> -d <profile> <device1> <device2> <device3>

For mounting such a RAID array, you only need to specify one of the devices used in file system. Btrfs will discover the other ones and mount them together automatically:
mount -t btrfs <device1> <mountpoint>
This is a very useful feature, especially if you plan to add more block devices to the file system at some point (no need to edit the fstab entry).
In the following exercise, we’ll create a file system that will stripe both data and metadata across two devices using the raid0 profile. We’ll start by unmounting and removing the file system from the previous exercise:
[oracle@oraclelinux6 ~]$ mount | grep btrfs
/dev/mapper/vg_oraclelinux6-lv_root on / type btrfs (rw)
/dev/sdb1 on /storage type btrfs (rw)
[oracle@oraclelinux6 ~]$ sudo umount -v /storage
/dev/sdb1 umounted
[oracle@oraclelinux6 ~]$ sudo fdisk -l /dev/sdb

Disk /dev/sdb: 4294 MB, 4294967296 bytes
255 heads, 63 sectors/track, 522 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0xa4488041

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1               1         522     4191941   83  Linux

Now let’s partition the other hard disk drive (/dev/sdc):
[oracle@oraclelinux6 ~]$ sudo fdisk /dev/sdc
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
Building a new DOS disklabel with disk identifier 0xb80b8a15.
Changes will remain in memory only, until you decide to write them.
After that, of course, the previous content won't be recoverable.

Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)

WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
         switch off the mode (command 'c') and change display units to
         sectors (command 'u').

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-522, default 1): 1
Last cylinder, +cylinders or +size{K,M,G} (1-522, default 522): 522


Command (m for help): p
Disk /dev/sdc: 4294 MB, 4294967296 bytes
255 heads, 63 sectors/track, 522 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0xb80b8a15

   Device Boot      Start         End      Blocks   Id  System
/dev/sdc1               1         522     4192933+  83  Linux
Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.
[oracle@oraclelinux6 ~]$ sudo mkfs.btrfs -m raid0 -d raid0 /dev/sdb1 /dev/sdc1
WARNING! - Btrfs Btrfs v0.20-rc1 IS EXPERIMENTAL
WARNING! - see http://btrfs.wiki.kernel.org before using

adding device /dev/sdc1 id 2
fs created label (null) on /dev/sdb1
 nodesize 4096 leafsize 4096 sectorsize 4096 size 8.00GB
Btrfs Btrfs v0.20-rc1
[oracle@oraclelinux6 ~]$ sudo btrfs filesystem show
Label: none  uuid: 89810a0a-7ed4-4756-a1df-c159ddd14dcd
 Total devices 1 FS bytes used 3.59GB
 devid    1 size 5.54GB used 5.54GB path /dev/dm-1

Label: none  uuid: 8f8e68ba-fb92-4d71-ae1b-5af1291c2c76
 Total devices 2 FS bytes used 28.00KB
 devid    2 size 4.00GB used 826.88MB path /dev/sdc1
 devid    1 size 4.00GB used 846.88MB path /dev/sdb1

Btrfs Btrfs v0.20-rc1
[oracle@oraclelinux6 ~]$ sudo mount -v -t btrfs /dev/sdb1 /storage/
/dev/sdb1 on /storage type btrfs (rw)
[oracle@oraclelinux6 ~]$ df -h /storage/

Filesystem            Size  Used Avail Use% Mounted on
/dev/sdb1             8.0G   28K  7.2G   1% /storage

Exercise: Growing/shrinking Volumes


A filesystem can be resized with the following command:
btrfs filesystem resize <size> <filesystem_name>
You have three options for the size argument: a specific size (such as 1024M or 7G), an increment or decrement value (such as +200M or -2G), or “max,” which will expand the filesystem to fill all of the available space on the underlying device or partition. This is useful if the management of the underlying block devices is being done outside of Btrfs (e.g. when using LVM2):
[oracle@oraclelinux6 ~]$ sudo btrfs filesystem resize -2G /storage
Resize '/storage' of '-2G'
[oracle@oraclelinux6 ~]$ df -h /storage

Filesystem            Size  Used Avail Use% Mounted on
/dev/sdb1             6.0G   28K  3.2G   1% /storage

Exercise: Adding/removing Block Devices

To create more disk space, you can add another disk to an existing file system using the following command:
btrfs device add <newdevice> <mountpoint>
The file system will grow automatically and provide the additional space. This operation must be performed while the filesystem is mounted. After you added a new disk, you can tell Btrfs to redistribute the array’s data across all devices for better I/O utilization
btrfs filesystem balance <mountpoint>
Note that this operation could take some time, if the file system is large.
Currently, it is not possible to watch the progress of balancing directly other than looking at the output of dmesg (which is a tad bit cryptic).
[oracle@oraclelinux6 ~]$ sudo umount /storage
[oracle@oraclelinux6 ~]$ sudo mkfs.btrfs /dev/sdb1

WARNING! - Btrfs Btrfs v0.20-rc1 IS EXPERIMENTAL
WARNING! - see http://btrfs.wiki.kernel.org before using

fs created label (null) on /dev/sdb1
 nodesize 4096 leafsize 4096 sectorsize 4096 size 4.00GB
Btrfs Btrfs v0.20-rc1
[oracle@oraclelinux6 ~]$ sudo mount -v /storage
/dev/sdb1 on /storage type btrfs (rw)
[oracle@oraclelinux6 ~]$ df -h /storage

Filesystem            Size  Used Avail Use% Mounted on
/dev/sdb1             4.0G   56K  3.6G   1% /storage
[oracle@oraclelinux6 ~]$ sudo cp -a /usr/src/kernels /storage/
[oracle@oraclelinux6 ~]$ df -h /storage/

Filesystem            Size  Used Avail Use% Mounted on
/dev/sdb1             4.0G  108M  3.3G   4% /storage
[oracle@oraclelinux6 ~]$ sudo btrfs filesystem show
Label: none  uuid: 89810a0a-7ed4-4756-a1df-c159ddd14dcd
 Total devices 1 FS bytes used 3.46GB
 devid    1 size 7.53GB used 6.29GB path /dev/dm-0

Label: none  uuid: 9f13eb80-396d-4de1-9c12-d62eb86c7609
 Total devices 1 FS bytes used 82.83MB
 devid    1 size 4.00GB used 1.08GB path /dev/sdb1

Btrfs Btrfs v0.20-rc1
[oracle@oraclelinux6 ~]$ sudo btrfs device add /dev/sdc1 /storage
[oracle@oraclelinux6 ~]$ df -h /storage

Filesystem            Size  Used Avail Use% Mounted on
/dev/sdb1             8.0G  114M  7.3G   2% /storage
[oracle@oraclelinux6 ~]$ sudo btrfs filesystem show
Label: none  uuid: 89810a0a-7ed4-4756-a1df-c159ddd14dcd
 Total devices 1 FS bytes used 3.46GB
 devid    1 size 7.53GB used 6.29GB path /dev/dm-0

Label: none  uuid: 9f13eb80-396d-4de1-9c12-d62eb86c7609
 Total devices 2 FS bytes used 82.83MB
 devid    2 size 4.00GB used 0.00 path /dev/sdc1
 devid    1 size 4.00GB used 1.08GB path /dev/sdb1

Btrfs Btrfs v0.20-rc1
[oracle@oraclelinux6 ~]$ sudo btrfs filesystem balance /storage
[oracle@oraclelinux6 ~]$ dmesg | tail

btrfs: found 2722 extents
btrfs: relocating block group 243990528 flags 36
btrfs: found 7827 extents
btrfs: relocating block group 29360128 flags 36
btrfs: relocating block group 20971520 flags 34
btrfs: found 1 extents
btrfs: relocating block group 12582912 flags 1
btrfs: found 387 extents
btrfs: found 387 extents
btrfs: relocating block group 4194304 flags 4
[oracle@oraclelinux6 ~]$ sudo btrfs filesystem show
Label: none  uuid: 89810a0a-7ed4-4756-a1df-c159ddd14dcd
 Total devices 1 FS bytes used 3.46GB
 devid    1 size 7.53GB used 6.29GB path /dev/dm-0

Label: none  uuid: 9f13eb80-396d-4de1-9c12-d62eb86c7609
 Total devices 2 FS bytes used 83.09MB
 devid    2 size 4.00GB used 1.39GB path /dev/sdc1
 devid    1 size 4.00GB used 1.34GB path /dev/sdb1

Btrfs Btrfs v0.20-rc1
[oracle@oraclelinux6 ~]$ sudo btrfs filesystem df /storage
Data, RAID0: total=818.88MB, used=52.28MB
System, RAID1: total=64.00MB, used=4.00KB
System: total=4.00MB, used=0.00
Metadata, RAID1: total=512.00MB, used=31.17MB
- See more at: http://linuxserver-jperez.rhcloud.com/?p=494#sthash.pKteNMXL.dpuf

Comentarios