diff options
| author | Tino Reichardt <milky-kernel@mcmilk.de> | 2012-09-17 12:58:19 -0400 |
|---|---|---|
| committer | Dave Kleikamp <dave.kleikamp@oracle.com> | 2012-09-17 12:58:19 -0400 |
| commit | b40c2e665cd552eae5fbdbb878bc29a34357668e (patch) | |
| tree | 23714e5773a77abf1daf71ca7958dcd8dfa688ea | |
| parent | fbcbe2b3c92ee1c930dcfcf8bb764074c100fd63 (diff) | |
fs/jfs: TRIM support for JFS Filesystem
This patch adds support for the two linux interfaces of the discard/TRIM
command for SSD devices and sparse/thinly-provisioned LUNs.
JFS will support batched discard via FITRIM ioctl and online discard
with the discard mount option.
Signed-off-by: Tino Reichardt <list-jfs@mcmilk.de>
Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com>
| -rw-r--r-- | Documentation/filesystems/jfs.txt | 19 | ||||
| -rw-r--r-- | fs/jfs/Makefile | 2 | ||||
| -rw-r--r-- | fs/jfs/ioctl.c | 43 | ||||
| -rw-r--r-- | fs/jfs/jfs_discard.c | 117 | ||||
| -rw-r--r-- | fs/jfs/jfs_discard.h | 26 | ||||
| -rw-r--r-- | fs/jfs/jfs_dmap.c | 125 | ||||
| -rw-r--r-- | fs/jfs/jfs_dmap.h | 2 | ||||
| -rw-r--r-- | fs/jfs/jfs_filsys.h | 3 | ||||
| -rw-r--r-- | fs/jfs/jfs_incore.h | 1 | ||||
| -rw-r--r-- | fs/jfs/super.c | 71 |
10 files changed, 385 insertions, 24 deletions
diff --git a/Documentation/filesystems/jfs.txt b/Documentation/filesystems/jfs.txt index 26ebde77e821..2f94f9ca1794 100644 --- a/Documentation/filesystems/jfs.txt +++ b/Documentation/filesystems/jfs.txt | |||
| @@ -3,6 +3,7 @@ IBM's Journaled File System (JFS) for Linux | |||
| 3 | JFS Homepage: http://jfs.sourceforge.net/ | 3 | JFS Homepage: http://jfs.sourceforge.net/ |
| 4 | 4 | ||
| 5 | The following mount options are supported: | 5 | The following mount options are supported: |
| 6 | (*) == default | ||
| 6 | 7 | ||
| 7 | iocharset=name Character set to use for converting from Unicode to | 8 | iocharset=name Character set to use for converting from Unicode to |
| 8 | ASCII. The default is to do no conversion. Use | 9 | ASCII. The default is to do no conversion. Use |
| @@ -21,12 +22,12 @@ nointegrity Do not write to the journal. The primary use of this option | |||
| 21 | from backup media. The integrity of the volume is not | 22 | from backup media. The integrity of the volume is not |
| 22 | guaranteed if the system abnormally abends. | 23 | guaranteed if the system abnormally abends. |
| 23 | 24 | ||
| 24 | integrity Default. Commit metadata changes to the journal. Use this | 25 | integrity(*) Commit metadata changes to the journal. Use this option to |
| 25 | option to remount a volume where the nointegrity option was | 26 | remount a volume where the nointegrity option was |
| 26 | previously specified in order to restore normal behavior. | 27 | previously specified in order to restore normal behavior. |
| 27 | 28 | ||
| 28 | errors=continue Keep going on a filesystem error. | 29 | errors=continue Keep going on a filesystem error. |
| 29 | errors=remount-ro Default. Remount the filesystem read-only on an error. | 30 | errors=remount-ro(*) Remount the filesystem read-only on an error. |
| 30 | errors=panic Panic and halt the machine if an error occurs. | 31 | errors=panic Panic and halt the machine if an error occurs. |
| 31 | 32 | ||
| 32 | uid=value Override on-disk uid with specified value | 33 | uid=value Override on-disk uid with specified value |
| @@ -35,6 +36,18 @@ umask=value Override on-disk umask with specified octal value. For | |||
| 35 | directories, the execute bit will be set if the corresponding | 36 | directories, the execute bit will be set if the corresponding |
| 36 | read bit is set. | 37 | read bit is set. |
| 37 | 38 | ||
| 39 | discard=minlen This enables/disables the use of discard/TRIM commands. | ||
| 40 | discard The discard/TRIM commands are sent to the underlying | ||
| 41 | nodiscard(*) block device when blocks are freed. This is useful for SSD | ||
| 42 | devices and sparse/thinly-provisioned LUNs. The FITRIM ioctl | ||
| 43 | command is also available together with the nodiscard option. | ||
| 44 | The value of minlen specifies the minimum blockcount, when | ||
| 45 | a TRIM command to the block device is considered usefull. | ||
| 46 | When no value is given to the discard option, it defaults to | ||
| 47 | 64 blocks, which means 256KiB in JFS. | ||
| 48 | The minlen value of discard overrides the minlen value given | ||
| 49 | on an FITRIM ioctl(). | ||
| 50 | |||
| 38 | Please send bugs, comments, cards and letters to shaggy@linux.vnet.ibm.com. | 51 | Please send bugs, comments, cards and letters to shaggy@linux.vnet.ibm.com. |
| 39 | 52 | ||
| 40 | The JFS mailing list can be subscribed to by using the link labeled | 53 | The JFS mailing list can be subscribed to by using the link labeled |
diff --git a/fs/jfs/Makefile b/fs/jfs/Makefile index a58fa72d7e59..d20d4737b3ef 100644 --- a/fs/jfs/Makefile +++ b/fs/jfs/Makefile | |||
| @@ -6,7 +6,7 @@ obj-$(CONFIG_JFS_FS) += jfs.o | |||
| 6 | 6 | ||
| 7 | jfs-y := super.o file.o inode.o namei.o jfs_mount.o jfs_umount.o \ | 7 | jfs-y := super.o file.o inode.o namei.o jfs_mount.o jfs_umount.o \ |
| 8 | jfs_xtree.o jfs_imap.o jfs_debug.o jfs_dmap.o \ | 8 | jfs_xtree.o jfs_imap.o jfs_debug.o jfs_dmap.o \ |
| 9 | jfs_unicode.o jfs_dtree.o jfs_inode.o \ | 9 | jfs_unicode.o jfs_dtree.o jfs_inode.o jfs_discard.o \ |
| 10 | jfs_extent.o symlink.o jfs_metapage.o \ | 10 | jfs_extent.o symlink.o jfs_metapage.o \ |
| 11 | jfs_logmgr.o jfs_txnmgr.o jfs_uniupr.o \ | 11 | jfs_logmgr.o jfs_txnmgr.o jfs_uniupr.o \ |
| 12 | resize.o xattr.o ioctl.o | 12 | resize.o xattr.o ioctl.o |
diff --git a/fs/jfs/ioctl.c b/fs/jfs/ioctl.c index f19d1e04a374..bc555ff417e9 100644 --- a/fs/jfs/ioctl.c +++ b/fs/jfs/ioctl.c | |||
| @@ -11,13 +11,17 @@ | |||
| 11 | #include <linux/mount.h> | 11 | #include <linux/mount.h> |
| 12 | #include <linux/time.h> | 12 | #include <linux/time.h> |
| 13 | #include <linux/sched.h> | 13 | #include <linux/sched.h> |
| 14 | #include <linux/blkdev.h> | ||
| 14 | #include <asm/current.h> | 15 | #include <asm/current.h> |
| 15 | #include <asm/uaccess.h> | 16 | #include <asm/uaccess.h> |
| 16 | 17 | ||
| 18 | #include "jfs_filsys.h" | ||
| 19 | #include "jfs_debug.h" | ||
| 17 | #include "jfs_incore.h" | 20 | #include "jfs_incore.h" |
| 18 | #include "jfs_dinode.h" | 21 | #include "jfs_dinode.h" |
| 19 | #include "jfs_inode.h" | 22 | #include "jfs_inode.h" |
| 20 | 23 | #include "jfs_dmap.h" | |
| 24 | #include "jfs_discard.h" | ||
| 21 | 25 | ||
| 22 | static struct { | 26 | static struct { |
| 23 | long jfs_flag; | 27 | long jfs_flag; |
| @@ -123,6 +127,40 @@ setflags_out: | |||
| 123 | mnt_drop_write_file(filp); | 127 | mnt_drop_write_file(filp); |
| 124 | return err; | 128 | return err; |
| 125 | } | 129 | } |
| 130 | |||
| 131 | case FITRIM: | ||
| 132 | { | ||
| 133 | struct super_block *sb = inode->i_sb; | ||
| 134 | struct request_queue *q = bdev_get_queue(sb->s_bdev); | ||
| 135 | struct fstrim_range range; | ||
| 136 | s64 ret = 0; | ||
| 137 | |||
| 138 | if (!capable(CAP_SYS_ADMIN)) | ||
| 139 | return -EPERM; | ||
| 140 | |||
| 141 | if (!blk_queue_discard(q)) { | ||
| 142 | jfs_warn("FITRIM not supported on device"); | ||
| 143 | return -EOPNOTSUPP; | ||
| 144 | } | ||
| 145 | |||
| 146 | if (copy_from_user(&range, (struct fstrim_range __user *)arg, | ||
| 147 | sizeof(range))) | ||
| 148 | return -EFAULT; | ||
| 149 | |||
| 150 | range.minlen = max_t(unsigned int, range.minlen, | ||
| 151 | q->limits.discard_granularity); | ||
| 152 | |||
| 153 | ret = jfs_ioc_trim(inode, &range); | ||
| 154 | if (ret < 0) | ||
| 155 | return ret; | ||
| 156 | |||
| 157 | if (copy_to_user((struct fstrim_range __user *)arg, &range, | ||
| 158 | sizeof(range))) | ||
| 159 | return -EFAULT; | ||
| 160 | |||
| 161 | return 0; | ||
| 162 | } | ||
| 163 | |||
| 126 | default: | 164 | default: |
| 127 | return -ENOTTY; | 165 | return -ENOTTY; |
| 128 | } | 166 | } |
| @@ -142,6 +180,9 @@ long jfs_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
| 142 | case JFS_IOC_SETFLAGS32: | 180 | case JFS_IOC_SETFLAGS32: |
| 143 | cmd = JFS_IOC_SETFLAGS; | 181 | cmd = JFS_IOC_SETFLAGS; |
| 144 | break; | 182 | break; |
| 183 | case FITRIM: | ||
| 184 | cmd = FITRIM; | ||
| 185 | break; | ||
| 145 | } | 186 | } |
| 146 | return jfs_ioctl(filp, cmd, arg); | 187 | return jfs_ioctl(filp, cmd, arg); |
| 147 | } | 188 | } |
diff --git a/fs/jfs/jfs_discard.c b/fs/jfs/jfs_discard.c new file mode 100644 index 000000000000..9947563e4175 --- /dev/null +++ b/fs/jfs/jfs_discard.c | |||
| @@ -0,0 +1,117 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) Tino Reichardt, 2012 | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License as published by | ||
| 6 | * the Free Software Foundation; either version 2 of the License, or | ||
| 7 | * (at your option) any later version. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See | ||
| 12 | * the GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program; if not, write to the Free Software | ||
| 16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <linux/fs.h> | ||
| 20 | #include <linux/slab.h> | ||
| 21 | #include <linux/blkdev.h> | ||
| 22 | |||
| 23 | #include "jfs_incore.h" | ||
| 24 | #include "jfs_superblock.h" | ||
| 25 | #include "jfs_discard.h" | ||
| 26 | #include "jfs_dmap.h" | ||
| 27 | #include "jfs_debug.h" | ||
| 28 | |||
| 29 | |||
| 30 | /* | ||
| 31 | * NAME: jfs_issue_discard() | ||
| 32 | * | ||
| 33 | * FUNCTION: TRIM the specified block range on device, if supported | ||
| 34 | * | ||
