exfat: linux 4.16 kernel build support
Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com>
This commit is contained in:
parent
92d4cd0cde
commit
f53d47cb58
2
Makefile
2
Makefile
@ -6,7 +6,7 @@ ifneq ($(KERNELRELEASE),)
|
|||||||
obj-$(CONFIG_EXFAT_FS) += exfat.o
|
obj-$(CONFIG_EXFAT_FS) += exfat.o
|
||||||
|
|
||||||
exfat-y := inode.o namei.o dir.o super.o fatent.o cache.o nls.o misc.o \
|
exfat-y := inode.o namei.o dir.o super.o fatent.o cache.o nls.o misc.o \
|
||||||
file.o balloc.io
|
file.o balloc.o
|
||||||
else
|
else
|
||||||
# Called from external kernel module build
|
# Called from external kernel module build
|
||||||
|
|
||||||
|
11
dir.c
11
dir.c
@ -3,6 +3,7 @@
|
|||||||
* Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
|
* Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/version.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/bio.h>
|
#include <linux/bio.h>
|
||||||
#include <linux/buffer_head.h>
|
#include <linux/buffer_head.h>
|
||||||
@ -443,7 +444,11 @@ int exfat_init_dir_entry(struct inode *inode, struct exfat_chain *p_dir,
|
|||||||
{
|
{
|
||||||
struct super_block *sb = inode->i_sb;
|
struct super_block *sb = inode->i_sb;
|
||||||
struct exfat_sb_info *sbi = EXFAT_SB(sb);
|
struct exfat_sb_info *sbi = EXFAT_SB(sb);
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
|
||||||
struct timespec64 ts = current_time(inode);
|
struct timespec64 ts = current_time(inode);
|
||||||
|
#else
|
||||||
|
struct timespec64 ts = CURRENT_TIME_SEC;
|
||||||
|
#endif
|
||||||
sector_t sector;
|
sector_t sector;
|
||||||
struct exfat_dentry *ep;
|
struct exfat_dentry *ep;
|
||||||
struct buffer_head *bh;
|
struct buffer_head *bh;
|
||||||
@ -884,7 +889,13 @@ struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb,
|
|||||||
|
|
||||||
num_entries = type == ES_ALL_ENTRIES ?
|
num_entries = type == ES_ALL_ENTRIES ?
|
||||||
ep->dentry.file.num_ext + 1 : type;
|
ep->dentry.file.num_ext + 1 : type;
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
|
||||||
es = kmalloc(struct_size(es, entries, num_entries), GFP_KERNEL);
|
es = kmalloc(struct_size(es, entries, num_entries), GFP_KERNEL);
|
||||||
|
#else
|
||||||
|
es = kmalloc((offsetof(struct exfat_entry_set_cache, entries) +
|
||||||
|
(num_entries) * sizeof(struct exfat_dentry)), GFP_KERNEL);
|
||||||
|
#endif
|
||||||
if (!es)
|
if (!es)
|
||||||
goto release_bh;
|
goto release_bh;
|
||||||
|
|
||||||
|
13
file.c
13
file.c
@ -3,6 +3,7 @@
|
|||||||
* Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
|
* Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/version.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/cred.h>
|
#include <linux/cred.h>
|
||||||
#include <linux/buffer_head.h>
|
#include <linux/buffer_head.h>
|
||||||
@ -20,7 +21,11 @@ static int exfat_cont_expand(struct inode *inode, loff_t size)
|
|||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
|
||||||
inode->i_ctime = inode->i_mtime = current_time(inode);
|
inode->i_ctime = inode->i_mtime = current_time(inode);
|
||||||
|
#else
|
||||||
|
inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
|
||||||
|
#endif
|
||||||
mark_inode_dirty(inode);
|
mark_inode_dirty(inode);
|
||||||
|
|
||||||
if (!IS_SYNC(inode))
|
if (!IS_SYNC(inode))
|
||||||
@ -160,7 +165,11 @@ int __exfat_truncate(struct inode *inode, loff_t new_size)
|
|||||||
return -EIO;
|
return -EIO;
|
||||||
ep2 = ep + 1;
|
ep2 = ep + 1;
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
|
||||||
ts = current_time(inode);
|
ts = current_time(inode);
|
||||||
|
#else
|
||||||
|
ts = CURRENT_TIME_SEC;
|
||||||
|
#endif
|
||||||
exfat_set_entry_time(sbi, &ts,
|
exfat_set_entry_time(sbi, &ts,
|
||||||
&ep->dentry.file.modify_tz,
|
&ep->dentry.file.modify_tz,
|
||||||
&ep->dentry.file.modify_time,
|
&ep->dentry.file.modify_time,
|
||||||
@ -243,7 +252,11 @@ void exfat_truncate(struct inode *inode, loff_t size)
|
|||||||
if (err)
|
if (err)
|
||||||
goto write_size;
|
goto write_size;
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
|
||||||
inode->i_ctime = inode->i_mtime = current_time(inode);
|
inode->i_ctime = inode->i_mtime = current_time(inode);
|
||||||
|
#else
|
||||||
|
inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
|
||||||
|
#endif
|
||||||
if (IS_DIRSYNC(inode))
|
if (IS_DIRSYNC(inode))
|
||||||
exfat_sync_inode(inode);
|
exfat_sync_inode(inode);
|
||||||
else
|
else
|
||||||
|
16
inode.c
16
inode.c
@ -3,6 +3,7 @@
|
|||||||
* Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
|
* Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/version.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/buffer_head.h>
|
#include <linux/buffer_head.h>
|
||||||
#include <linux/mpage.h>
|
#include <linux/mpage.h>
|
||||||
@ -12,8 +13,9 @@
|
|||||||
#include <linux/writeback.h>
|
#include <linux/writeback.h>
|
||||||
#include <linux/uio.h>
|
#include <linux/uio.h>
|
||||||
#include <linux/random.h>
|
#include <linux/random.h>
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
|
||||||
#include <linux/iversion.h>
|
#include <linux/iversion.h>
|
||||||
|
#endif
|
||||||
#include "exfat_raw.h"
|
#include "exfat_raw.h"
|
||||||
#include "exfat_fs.h"
|
#include "exfat_fs.h"
|
||||||
|
|
||||||
@ -437,7 +439,11 @@ static int exfat_write_end(struct file *file, struct address_space *mapping,
|
|||||||
exfat_write_failed(mapping, pos+len);
|
exfat_write_failed(mapping, pos+len);
|
||||||
|
|
||||||
if (!(err < 0) && !(ei->attr & ATTR_ARCHIVE)) {
|
if (!(err < 0) && !(ei->attr & ATTR_ARCHIVE)) {
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
|
||||||
inode->i_mtime = inode->i_ctime = current_time(inode);
|
inode->i_mtime = inode->i_ctime = current_time(inode);
|
||||||
|
#else
|
||||||
|
inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
|
||||||
|
#endif
|
||||||
ei->attr |= ATTR_ARCHIVE;
|
ei->attr |= ATTR_ARCHIVE;
|
||||||
mark_inode_dirty(inode);
|
mark_inode_dirty(inode);
|
||||||
}
|
}
|
||||||
@ -582,7 +588,11 @@ static int exfat_fill_inode(struct inode *inode, struct exfat_dir_entry *info)
|
|||||||
|
|
||||||
inode->i_uid = sbi->options.fs_uid;
|
inode->i_uid = sbi->options.fs_uid;
|
||||||
inode->i_gid = sbi->options.fs_gid;
|
inode->i_gid = sbi->options.fs_gid;
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
|
||||||
inode_inc_iversion(inode);
|
inode_inc_iversion(inode);
|
||||||
|
#else
|
||||||
|
inode->i_version++;
|
||||||
|
#endif
|
||||||
inode->i_generation = prandom_u32();
|
inode->i_generation = prandom_u32();
|
||||||
|
|
||||||
if (info->attr & ATTR_SUBDIR) { /* directory */
|
if (info->attr & ATTR_SUBDIR) { /* directory */
|
||||||
@ -640,7 +650,11 @@ struct inode *exfat_build_inode(struct super_block *sb,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
inode->i_ino = iunique(sb, EXFAT_ROOT_INO);
|
inode->i_ino = iunique(sb, EXFAT_ROOT_INO);
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
|
||||||
inode_set_iversion(inode, 1);
|
inode_set_iversion(inode, 1);
|
||||||
|
#else
|
||||||
|
inode->i_version = 1;
|
||||||
|
#endif
|
||||||
err = exfat_fill_inode(inode, info);
|
err = exfat_fill_inode(inode, info);
|
||||||
if (err) {
|
if (err) {
|
||||||
iput(inode);
|
iput(inode);
|
||||||
|
110
namei.c
110
namei.c
@ -3,7 +3,10 @@
|
|||||||
* Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
|
* Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/version.h>
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
|
||||||
#include <linux/iversion.h>
|
#include <linux/iversion.h>
|
||||||
|
#endif
|
||||||
#include <linux/namei.h>
|
#include <linux/namei.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/buffer_head.h>
|
#include <linux/buffer_head.h>
|
||||||
@ -59,8 +62,13 @@ static int exfat_d_revalidate(struct dentry *dentry, unsigned int flags)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
spin_lock(&dentry->d_lock);
|
spin_lock(&dentry->d_lock);
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
|
||||||
ret = inode_eq_iversion(d_inode(dentry->d_parent),
|
ret = inode_eq_iversion(d_inode(dentry->d_parent),
|
||||||
exfat_d_version(dentry));
|
exfat_d_version(dentry));
|
||||||
|
#else
|
||||||
|
if (dentry->d_parent->d_inode->i_version != exfat_d_version(dentry))
|
||||||
|
ret = 0;
|
||||||
|
#endif
|
||||||
spin_unlock(&dentry->d_lock);
|
spin_unlock(&dentry->d_lock);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -580,8 +588,16 @@ static int exfat_create(struct inode *dir, struct dentry *dentry, umode_t mode,
|
|||||||
if (err)
|
if (err)
|
||||||
goto unlock;
|
goto unlock;
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
|
||||||
inode_inc_iversion(dir);
|
inode_inc_iversion(dir);
|
||||||
|
#else
|
||||||
|
dir->i_version++;
|
||||||
|
#endif
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
|
||||||
dir->i_ctime = dir->i_mtime = current_time(dir);
|
dir->i_ctime = dir->i_mtime = current_time(dir);
|
||||||
|
#else
|
||||||
|
dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
|
||||||
|
#endif
|
||||||
if (IS_DIRSYNC(dir))
|
if (IS_DIRSYNC(dir))
|
||||||
exfat_sync_inode(dir);
|
exfat_sync_inode(dir);
|
||||||
else
|
else
|
||||||
@ -592,9 +608,19 @@ static int exfat_create(struct inode *dir, struct dentry *dentry, umode_t mode,
|
|||||||
if (IS_ERR(inode))
|
if (IS_ERR(inode))
|
||||||
goto unlock;
|
goto unlock;
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
|
||||||
inode_inc_iversion(inode);
|
inode_inc_iversion(inode);
|
||||||
|
#else
|
||||||
|
inode->i_version++;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
|
||||||
inode->i_mtime = inode->i_atime = inode->i_ctime =
|
inode->i_mtime = inode->i_atime = inode->i_ctime =
|
||||||
EXFAT_I(inode)->i_crtime = current_time(inode);
|
EXFAT_I(inode)->i_crtime = current_time(inode);
|
||||||
|
#else
|
||||||
|
inode->i_mtime = inode->i_atime = inode->i_ctime =
|
||||||
|
EXFAT_I(inode)->i_crtime = CURRENT_TIME_SEC;
|
||||||
|
#endif
|
||||||
/* timestamp is already written, so mark_inode_dirty() is unneeded. */
|
/* timestamp is already written, so mark_inode_dirty() is unneeded. */
|
||||||
|
|
||||||
d_instantiate(dentry, inode);
|
d_instantiate(dentry, inode);
|
||||||
@ -629,10 +655,18 @@ static int exfat_find(struct inode *dir, struct qstr *qname,
|
|||||||
return num_entries;
|
return num_entries;
|
||||||
|
|
||||||
/* check the validation of hint_stat and initialize it if required */
|
/* check the validation of hint_stat and initialize it if required */
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
|
||||||
if (ei->version != (inode_peek_iversion_raw(dir) & 0xffffffff)) {
|
if (ei->version != (inode_peek_iversion_raw(dir) & 0xffffffff)) {
|
||||||
|
#else
|
||||||
|
if (ei->version != (dir->i_version & 0xffffffff)) {
|
||||||
|
#endif
|
||||||
ei->hint_stat.clu = cdir.dir;
|
ei->hint_stat.clu = cdir.dir;
|
||||||
ei->hint_stat.eidx = 0;
|
ei->hint_stat.eidx = 0;
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
|
||||||
ei->version = (inode_peek_iversion_raw(dir) & 0xffffffff);
|
ei->version = (inode_peek_iversion_raw(dir) & 0xffffffff);
|
||||||
|
#else
|
||||||
|
ei->version = (dir->i_version & 0xffffffff);
|
||||||
|
#endif
|
||||||
ei->hint_femp.eidx = EXFAT_HINT_NONE;
|
ei->hint_femp.eidx = EXFAT_HINT_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -798,7 +832,11 @@ static struct dentry *exfat_lookup(struct inode *dir, struct dentry *dentry,
|
|||||||
out:
|
out:
|
||||||
mutex_unlock(&EXFAT_SB(sb)->s_lock);
|
mutex_unlock(&EXFAT_SB(sb)->s_lock);
|
||||||
if (!inode)
|
if (!inode)
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
|
||||||
exfat_d_version_set(dentry, inode_query_iversion(dir));
|
exfat_d_version_set(dentry, inode_query_iversion(dir));
|
||||||
|
#else
|
||||||
|
exfat_d_version_set(dentry, dir->i_version);
|
||||||
|
#endif
|
||||||
|
|
||||||
return d_splice_alias(inode, dentry);
|
return d_splice_alias(inode, dentry);
|
||||||
unlock:
|
unlock:
|
||||||
@ -852,17 +890,33 @@ static int exfat_unlink(struct inode *dir, struct dentry *dentry)
|
|||||||
ei->dir.dir = DIR_DELETED;
|
ei->dir.dir = DIR_DELETED;
|
||||||
exfat_set_vol_flags(sb, VOL_CLEAN);
|
exfat_set_vol_flags(sb, VOL_CLEAN);
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
|
||||||
inode_inc_iversion(dir);
|
inode_inc_iversion(dir);
|
||||||
|
#else
|
||||||
|
dir->i_version++;
|
||||||
|
#endif
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
|
||||||
dir->i_mtime = dir->i_atime = current_time(dir);
|
dir->i_mtime = dir->i_atime = current_time(dir);
|
||||||
|
#else
|
||||||
|
dir->i_mtime = dir->i_atime = CURRENT_TIME_SEC;
|
||||||
|
#endif
|
||||||
if (IS_DIRSYNC(dir))
|
if (IS_DIRSYNC(dir))
|
||||||
exfat_sync_inode(dir);
|
exfat_sync_inode(dir);
|
||||||
else
|
else
|
||||||
mark_inode_dirty(dir);
|
mark_inode_dirty(dir);
|
||||||
|
|
||||||
clear_nlink(inode);
|
clear_nlink(inode);
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
|
||||||
inode->i_mtime = inode->i_atime = current_time(inode);
|
inode->i_mtime = inode->i_atime = current_time(inode);
|
||||||
|
#else
|
||||||
|
inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC;
|
||||||
|
#endif
|
||||||
exfat_unhash_inode(inode);
|
exfat_unhash_inode(inode);
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
|
||||||
exfat_d_version_set(dentry, inode_query_iversion(dir));
|
exfat_d_version_set(dentry, inode_query_iversion(dir));
|
||||||
|
#else
|
||||||
|
exfat_d_version_set(dentry, dir->i_version);
|
||||||
|
#endif
|
||||||
unlock:
|
unlock:
|
||||||
mutex_unlock(&EXFAT_SB(sb)->s_lock);
|
mutex_unlock(&EXFAT_SB(sb)->s_lock);
|
||||||
return err;
|
return err;
|
||||||
@ -885,8 +939,17 @@ static int exfat_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
|
|||||||
if (err)
|
if (err)
|
||||||
goto unlock;
|
goto unlock;
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
|
||||||
inode_inc_iversion(dir);
|
inode_inc_iversion(dir);
|
||||||
|
#else
|
||||||
|
dir->i_version++;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
|
||||||
dir->i_ctime = dir->i_mtime = current_time(dir);
|
dir->i_ctime = dir->i_mtime = current_time(dir);
|
||||||
|
#else
|
||||||
|
dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
|
||||||
|
#endif
|
||||||
if (IS_DIRSYNC(dir))
|
if (IS_DIRSYNC(dir))
|
||||||
exfat_sync_inode(dir);
|
exfat_sync_inode(dir);
|
||||||
else
|
else
|
||||||
@ -900,9 +963,18 @@ static int exfat_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
|
|||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
|
||||||
inode_inc_iversion(inode);
|
inode_inc_iversion(inode);
|
||||||
|
#else
|
||||||
|
inode->i_version++;
|
||||||
|
#endif
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
|
||||||
inode->i_mtime = inode->i_atime = inode->i_ctime =
|
inode->i_mtime = inode->i_atime = inode->i_ctime =
|
||||||
EXFAT_I(inode)->i_crtime = current_time(inode);
|
EXFAT_I(inode)->i_crtime = current_time(inode);
|
||||||
|
#else
|
||||||
|
inode->i_mtime = inode->i_atime = inode->i_ctime =
|
||||||
|
EXFAT_I(inode)->i_crtime = CURRENT_TIME_SEC;
|
||||||
|
#endif
|
||||||
/* timestamp is already written, so mark_inode_dirty() is unneeded. */
|
/* timestamp is already written, so mark_inode_dirty() is unneeded. */
|
||||||
|
|
||||||
d_instantiate(dentry, inode);
|
d_instantiate(dentry, inode);
|
||||||
@ -1017,8 +1089,16 @@ static int exfat_rmdir(struct inode *dir, struct dentry *dentry)
|
|||||||
ei->dir.dir = DIR_DELETED;
|
ei->dir.dir = DIR_DELETED;
|
||||||
exfat_set_vol_flags(sb, VOL_CLEAN);
|
exfat_set_vol_flags(sb, VOL_CLEAN);
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
|
||||||
inode_inc_iversion(dir);
|
inode_inc_iversion(dir);
|
||||||
|
#else
|
||||||
|
dir->i_version++;
|
||||||
|
#endif
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
|
||||||
dir->i_mtime = dir->i_atime = current_time(dir);
|
dir->i_mtime = dir->i_atime = current_time(dir);
|
||||||
|
#else
|
||||||
|
dir->i_mtime = dir->i_atime = CURRENT_TIME_SEC;
|
||||||
|
#endif
|
||||||
if (IS_DIRSYNC(dir))
|
if (IS_DIRSYNC(dir))
|
||||||
exfat_sync_inode(dir);
|
exfat_sync_inode(dir);
|
||||||
else
|
else
|
||||||
@ -1026,9 +1106,17 @@ static int exfat_rmdir(struct inode *dir, struct dentry *dentry)
|
|||||||
drop_nlink(dir);
|
drop_nlink(dir);
|
||||||
|
|
||||||
clear_nlink(inode);
|
clear_nlink(inode);
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
|
||||||
inode->i_mtime = inode->i_atime = current_time(inode);
|
inode->i_mtime = inode->i_atime = current_time(inode);
|
||||||
|
#else
|
||||||
|
inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC;
|
||||||
|
#endif
|
||||||
exfat_unhash_inode(inode);
|
exfat_unhash_inode(inode);
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
|
||||||
exfat_d_version_set(dentry, inode_query_iversion(dir));
|
exfat_d_version_set(dentry, inode_query_iversion(dir));
|
||||||
|
#else
|
||||||
|
exfat_d_version_set(dentry, dir->i_version);
|
||||||
|
#endif
|
||||||
unlock:
|
unlock:
|
||||||
mutex_unlock(&EXFAT_SB(inode->i_sb)->s_lock);
|
mutex_unlock(&EXFAT_SB(inode->i_sb)->s_lock);
|
||||||
return err;
|
return err;
|
||||||
@ -1384,9 +1472,18 @@ static int exfat_rename(struct inode *old_dir, struct dentry *old_dentry,
|
|||||||
if (err)
|
if (err)
|
||||||
goto unlock;
|
goto unlock;
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
|
||||||
inode_inc_iversion(new_dir);
|
inode_inc_iversion(new_dir);
|
||||||
|
#else
|
||||||
|
new_dir->i_version++;
|
||||||
|
#endif
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
|
||||||
new_dir->i_ctime = new_dir->i_mtime = new_dir->i_atime =
|
new_dir->i_ctime = new_dir->i_mtime = new_dir->i_atime =
|
||||||
EXFAT_I(new_dir)->i_crtime = current_time(new_dir);
|
EXFAT_I(new_dir)->i_crtime = current_time(new_dir);
|
||||||
|
#else
|
||||||
|
new_dir->i_ctime = new_dir->i_mtime = new_dir->i_atime =
|
||||||
|
EXFAT_I(new_dir)->i_crtime = CURRENT_TIME_SEC;
|
||||||
|
#endif
|
||||||
if (IS_DIRSYNC(new_dir))
|
if (IS_DIRSYNC(new_dir))
|
||||||
exfat_sync_inode(new_dir);
|
exfat_sync_inode(new_dir);
|
||||||
else
|
else
|
||||||
@ -1407,8 +1504,16 @@ static int exfat_rename(struct inode *old_dir, struct dentry *old_dentry,
|
|||||||
inc_nlink(new_dir);
|
inc_nlink(new_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
|
||||||
inode_inc_iversion(old_dir);
|
inode_inc_iversion(old_dir);
|
||||||
|
#else
|
||||||
|
old_dir->i_version++;
|
||||||
|
#endif
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
|
||||||
old_dir->i_ctime = old_dir->i_mtime = current_time(old_dir);
|
old_dir->i_ctime = old_dir->i_mtime = current_time(old_dir);
|
||||||
|
#else
|
||||||
|
old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME_SEC;
|
||||||
|
#endif
|
||||||
if (IS_DIRSYNC(old_dir))
|
if (IS_DIRSYNC(old_dir))
|
||||||
exfat_sync_inode(old_dir);
|
exfat_sync_inode(old_dir);
|
||||||
else
|
else
|
||||||
@ -1427,8 +1532,13 @@ static int exfat_rename(struct inode *old_dir, struct dentry *old_dentry,
|
|||||||
"abnormal access to an inode dropped");
|
"abnormal access to an inode dropped");
|
||||||
WARN_ON(new_inode->i_nlink == 0);
|
WARN_ON(new_inode->i_nlink == 0);
|
||||||
}
|
}
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
|
||||||
new_inode->i_ctime = EXFAT_I(new_inode)->i_crtime =
|
new_inode->i_ctime = EXFAT_I(new_inode)->i_crtime =
|
||||||
current_time(new_inode);
|
current_time(new_inode);
|
||||||
|
#else
|
||||||
|
new_inode->i_ctime = EXFAT_I(new_inode)->i_crtime =
|
||||||
|
CURRENT_TIME_SEC;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
unlock:
|
unlock:
|
||||||
|
229
super.c
229
super.c
@ -3,8 +3,14 @@
|
|||||||
* Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
|
* Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/version.h>
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
|
||||||
#include <linux/fs_context.h>
|
#include <linux/fs_context.h>
|
||||||
#include <linux/fs_parser.h>
|
#include <linux/fs_parser.h>
|
||||||
|
#else
|
||||||
|
#include <linux/cred.h>
|
||||||
|
#include <linux/parser.h>
|
||||||
|
#endif
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/time.h>
|
#include <linux/time.h>
|
||||||
@ -14,13 +20,20 @@
|
|||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
#include <linux/blkdev.h>
|
#include <linux/blkdev.h>
|
||||||
#include <linux/fs_struct.h>
|
#include <linux/fs_struct.h>
|
||||||
#include <linux/iversion.h>
|
|
||||||
#include <linux/nls.h>
|
#include <linux/nls.h>
|
||||||
#include <linux/buffer_head.h>
|
#include <linux/buffer_head.h>
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
|
||||||
|
#include <linux/iversion.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "exfat_raw.h"
|
#include "exfat_raw.h"
|
||||||
#include "exfat_fs.h"
|
#include "exfat_fs.h"
|
||||||
|
|
||||||
|
#ifndef CONFIG_EXFAT_DEFAULT_IOCHARSET /* if Kconfig lacked iocharset */
|
||||||
|
#define CONFIG_EXFAT_DEFAULT_IOCHARSET "utf8"
|
||||||
|
#endif
|
||||||
|
|
||||||
static char exfat_default_iocharset[] = CONFIG_EXFAT_DEFAULT_IOCHARSET;
|
static char exfat_default_iocharset[] = CONFIG_EXFAT_DEFAULT_IOCHARSET;
|
||||||
static struct kmem_cache *exfat_inode_cachep;
|
static struct kmem_cache *exfat_inode_cachep;
|
||||||
|
|
||||||
@ -185,14 +198,31 @@ static struct inode *exfat_alloc_inode(struct super_block *sb)
|
|||||||
return &ei->vfs_inode;
|
return &ei->vfs_inode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
|
||||||
static void exfat_free_inode(struct inode *inode)
|
static void exfat_free_inode(struct inode *inode)
|
||||||
{
|
{
|
||||||
kmem_cache_free(exfat_inode_cachep, EXFAT_I(inode));
|
kmem_cache_free(exfat_inode_cachep, EXFAT_I(inode));
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
static void exfat_i_callback(struct rcu_head *head)
|
||||||
|
{
|
||||||
|
struct inode *inode = container_of(head, struct inode, i_rcu);
|
||||||
|
kmem_cache_free(exfat_inode_cachep, EXFAT_I(inode));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void exfat_destroy_inode(struct inode *inode)
|
||||||
|
{
|
||||||
|
call_rcu(&inode->i_rcu, exfat_i_callback);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static const struct super_operations exfat_sops = {
|
static const struct super_operations exfat_sops = {
|
||||||
.alloc_inode = exfat_alloc_inode,
|
.alloc_inode = exfat_alloc_inode,
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
|
||||||
.free_inode = exfat_free_inode,
|
.free_inode = exfat_free_inode,
|
||||||
|
#else
|
||||||
|
.destroy_inode = exfat_destroy_inode,
|
||||||
|
#endif
|
||||||
.write_inode = exfat_write_inode,
|
.write_inode = exfat_write_inode,
|
||||||
.evict_inode = exfat_evict_inode,
|
.evict_inode = exfat_evict_inode,
|
||||||
.put_super = exfat_put_super,
|
.put_super = exfat_put_super,
|
||||||
@ -201,6 +231,7 @@ static const struct super_operations exfat_sops = {
|
|||||||
.show_options = exfat_show_options,
|
.show_options = exfat_show_options,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
|
||||||
enum {
|
enum {
|
||||||
Opt_uid,
|
Opt_uid,
|
||||||
Opt_gid,
|
Opt_gid,
|
||||||
@ -299,6 +330,137 @@ static int exfat_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
enum {
|
||||||
|
Opt_uid,
|
||||||
|
Opt_gid,
|
||||||
|
Opt_umask,
|
||||||
|
Opt_dmask,
|
||||||
|
Opt_fmask,
|
||||||
|
Opt_allow_utime,
|
||||||
|
Opt_charset,
|
||||||
|
Opt_err_cont,
|
||||||
|
Opt_err_panic,
|
||||||
|
Opt_err_ro,
|
||||||
|
Opt_err,
|
||||||
|
Opt_discard,
|
||||||
|
Opt_fs,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const match_table_t exfat_tokens = {
|
||||||
|
{Opt_uid, "uid=%u"},
|
||||||
|
{Opt_gid, "gid=%u"},
|
||||||
|
{Opt_umask, "umask=%o"},
|
||||||
|
{Opt_dmask, "dmask=%o"},
|
||||||
|
{Opt_fmask, "fmask=%o"},
|
||||||
|
{Opt_allow_utime, "allow_utime=%o"},
|
||||||
|
{Opt_charset, "iocharset=%s"},
|
||||||
|
{Opt_err_cont, "errors=continue"},
|
||||||
|
{Opt_err_panic, "errors=panic"},
|
||||||
|
{Opt_err_ro, "errors=remount-ro"},
|
||||||
|
{Opt_discard, "discard"},
|
||||||
|
{Opt_err, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static int parse_options(struct super_block *sb, char *options, int silent,
|
||||||
|
struct exfat_mount_options *opts)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
substring_t args[MAX_OPT_ARGS];
|
||||||
|
int option;
|
||||||
|
char *tmpstr;
|
||||||
|
|
||||||
|
opts->fs_uid = current_uid();
|
||||||
|
opts->fs_gid = current_gid();
|
||||||
|
opts->fs_fmask = opts->fs_dmask = current->fs->umask;
|
||||||
|
opts->allow_utime = -1;
|
||||||
|
opts->iocharset = exfat_default_iocharset;
|
||||||
|
opts->utf8 = 0;
|
||||||
|
opts->errors = EXFAT_ERRORS_RO;
|
||||||
|
opts->discard = 0;
|
||||||
|
|
||||||
|
if (!options)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
while ((p = strsep(&options, ",")) != NULL) {
|
||||||
|
int token;
|
||||||
|
|
||||||
|
if (!*p)
|
||||||
|
continue;
|
||||||
|
token = match_token(p, exfat_tokens, args);
|
||||||
|
switch (token) {
|
||||||
|
case Opt_uid:
|
||||||
|
if (match_int(&args[0], &option))
|
||||||
|
return 0;
|
||||||
|
opts->fs_uid = make_kuid(current_user_ns(), option);
|
||||||
|
break;
|
||||||
|
case Opt_gid:
|
||||||
|
if (match_int(&args[0], &option))
|
||||||
|
return 0;
|
||||||
|
opts->fs_gid = make_kgid(current_user_ns(), option);
|
||||||
|
break;
|
||||||
|
case Opt_umask:
|
||||||
|
case Opt_dmask:
|
||||||
|
case Opt_fmask:
|
||||||
|
if (match_octal(&args[0], &option))
|
||||||
|
return 0;
|
||||||
|
if (token != Opt_dmask)
|
||||||
|
opts->fs_fmask = option;
|
||||||
|
if (token != Opt_fmask)
|
||||||
|
opts->fs_dmask = option;
|
||||||
|
break;
|
||||||
|
case Opt_allow_utime:
|
||||||
|
if (match_octal(&args[0], &option))
|
||||||
|
return 0;
|
||||||
|
opts->allow_utime = option & (0022);
|
||||||
|
break;
|
||||||
|
case Opt_charset:
|
||||||
|
if (opts->iocharset != exfat_default_iocharset)
|
||||||
|
kfree(opts->iocharset);
|
||||||
|
tmpstr = match_strdup(&args[0]);
|
||||||
|
if (!tmpstr)
|
||||||
|
return -ENOMEM;
|
||||||
|
opts->iocharset = tmpstr;
|
||||||
|
break;
|
||||||
|
case Opt_err_cont:
|
||||||
|
opts->errors = EXFAT_ERRORS_CONT;
|
||||||
|
break;
|
||||||
|
case Opt_err_panic:
|
||||||
|
opts->errors = EXFAT_ERRORS_PANIC;
|
||||||
|
break;
|
||||||
|
case Opt_err_ro:
|
||||||
|
opts->errors = EXFAT_ERRORS_RO;
|
||||||
|
break;
|
||||||
|
case Opt_discard:
|
||||||
|
opts->discard = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (!silent) {
|
||||||
|
exfat_msg(sb, KERN_ERR,
|
||||||
|
"unrecognized mount option \"%s\" or missing value",
|
||||||
|
p);
|
||||||
|
}
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (opts->allow_utime == -1)
|
||||||
|
opts->allow_utime = ~opts->fs_dmask & (0022);
|
||||||
|
|
||||||
|
if (opts->discard) {
|
||||||
|
struct request_queue *q = bdev_get_queue(sb->s_bdev);
|
||||||
|
|
||||||
|
if (!blk_queue_discard(q))
|
||||||
|
exfat_msg(sb, KERN_WARNING,
|
||||||
|
"mounting with \"discard\" option, but the device does not support discard");
|
||||||
|
opts->discard = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static void exfat_hash_init(struct super_block *sb)
|
static void exfat_hash_init(struct super_block *sb)
|
||||||
{
|
{
|
||||||
@ -342,7 +504,12 @@ static int exfat_read_root(struct inode *inode)
|
|||||||
|
|
||||||
inode->i_uid = sbi->options.fs_uid;
|
inode->i_uid = sbi->options.fs_uid;
|
||||||
inode->i_gid = sbi->options.fs_gid;
|
inode->i_gid = sbi->options.fs_gid;
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
|
||||||
inode_inc_iversion(inode);
|
inode_inc_iversion(inode);
|
||||||
|
#else
|
||||||
|
inode->i_version++;
|
||||||
|
#endif
|
||||||
inode->i_generation = 0;
|
inode->i_generation = 0;
|
||||||
inode->i_mode = exfat_make_mode(sbi, ATTR_SUBDIR, 0777);
|
inode->i_mode = exfat_make_mode(sbi, ATTR_SUBDIR, 0777);
|
||||||
inode->i_op = &exfat_dir_inode_operations;
|
inode->i_op = &exfat_dir_inode_operations;
|
||||||
@ -355,8 +522,13 @@ static int exfat_read_root(struct inode *inode)
|
|||||||
EXFAT_I(inode)->i_size_ondisk = i_size_read(inode);
|
EXFAT_I(inode)->i_size_ondisk = i_size_read(inode);
|
||||||
|
|
||||||
exfat_save_attr(inode, ATTR_SUBDIR);
|
exfat_save_attr(inode, ATTR_SUBDIR);
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
|
||||||
inode->i_mtime = inode->i_atime = inode->i_ctime = ei->i_crtime =
|
inode->i_mtime = inode->i_atime = inode->i_ctime = ei->i_crtime =
|
||||||
current_time(inode);
|
current_time(inode);
|
||||||
|
#else
|
||||||
|
inode->i_mtime = inode->i_atime = inode->i_ctime = ei->i_crtime =
|
||||||
|
CURRENT_TIME_SEC;
|
||||||
|
#endif
|
||||||
exfat_cache_init_inode(inode);
|
exfat_cache_init_inode(inode);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -524,12 +696,17 @@ free_bh:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
|
||||||
static int exfat_fill_super(struct super_block *sb, struct fs_context *fc)
|
static int exfat_fill_super(struct super_block *sb, struct fs_context *fc)
|
||||||
|
#else
|
||||||
|
static int exfat_fill_super(struct super_block *sb, void *data, int silent)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
struct exfat_sb_info *sbi = sb->s_fs_info;
|
|
||||||
struct exfat_mount_options *opts = &sbi->options;
|
|
||||||
struct inode *root_inode;
|
struct inode *root_inode;
|
||||||
int err;
|
int err;
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
|
||||||
|
struct exfat_sb_info *sbi = sb->s_fs_info;
|
||||||
|
struct exfat_mount_options *opts = &sbi->options;
|
||||||
|
|
||||||
if (opts->allow_utime == (unsigned short)-1)
|
if (opts->allow_utime == (unsigned short)-1)
|
||||||
opts->allow_utime = ~opts->fs_dmask & 0022;
|
opts->allow_utime = ~opts->fs_dmask & 0022;
|
||||||
@ -542,14 +719,39 @@ static int exfat_fill_super(struct super_block *sb, struct fs_context *fc)
|
|||||||
"mounting with \"discard\" option, but the device does not support discard");
|
"mounting with \"discard\" option, but the device does not support discard");
|
||||||
opts->discard = 0;
|
opts->discard = 0;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
struct exfat_sb_info *sbi;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GFP_KERNEL is ok here, because while we do hold the
|
||||||
|
* supeblock lock, memory pressure can't call back into
|
||||||
|
* the filesystem, since we're only just about to mount
|
||||||
|
* it and have no inodes etc active!
|
||||||
|
*/
|
||||||
|
sbi = kzalloc(sizeof(struct exfat_sb_info), GFP_KERNEL);
|
||||||
|
if (!sbi)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
mutex_init(&sbi->s_lock);
|
||||||
|
sb->s_fs_info = sbi;
|
||||||
|
ratelimit_state_init(&sbi->ratelimit, DEFAULT_RATELIMIT_INTERVAL,
|
||||||
|
DEFAULT_RATELIMIT_BURST);
|
||||||
|
err = parse_options(sb, data, silent, &sbi->options);
|
||||||
|
if (err) {
|
||||||
|
exfat_msg(sb, KERN_ERR, "failed to parse options");
|
||||||
|
goto check_nls_io;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
sb->s_flags |= SB_NODIRATIME;
|
sb->s_flags |= SB_NODIRATIME;
|
||||||
sb->s_magic = EXFAT_SUPER_MAGIC;
|
sb->s_magic = EXFAT_SUPER_MAGIC;
|
||||||
sb->s_op = &exfat_sops;
|
sb->s_op = &exfat_sops;
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
|
||||||
sb->s_time_gran = 1;
|
sb->s_time_gran = 1;
|
||||||
sb->s_time_min = EXFAT_MIN_TIMESTAMP_SECS;
|
sb->s_time_min = EXFAT_MIN_TIMESTAMP_SECS;
|
||||||
sb->s_time_max = EXFAT_MAX_TIMESTAMP_SECS;
|
sb->s_time_max = EXFAT_MAX_TIMESTAMP_SECS;
|
||||||
|
#endif
|
||||||
|
|
||||||
err = __exfat_fill_super(sb);
|
err = __exfat_fill_super(sb);
|
||||||
if (err) {
|
if (err) {
|
||||||
@ -561,7 +763,11 @@ static int exfat_fill_super(struct super_block *sb, struct fs_context *fc)
|
|||||||
exfat_hash_init(sb);
|
exfat_hash_init(sb);
|
||||||
|
|
||||||
if (!strcmp(sbi->options.iocharset, "utf8"))
|
if (!strcmp(sbi->options.iocharset, "utf8"))
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
|
||||||
opts->utf8 = 1;
|
opts->utf8 = 1;
|
||||||
|
#else
|
||||||
|
sbi->options.utf8 = 1;
|
||||||
|
#endif
|
||||||
else {
|
else {
|
||||||
sbi->nls_io = load_nls(sbi->options.iocharset);
|
sbi->nls_io = load_nls(sbi->options.iocharset);
|
||||||
if (!sbi->nls_io) {
|
if (!sbi->nls_io) {
|
||||||
@ -585,7 +791,12 @@ static int exfat_fill_super(struct super_block *sb, struct fs_context *fc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
root_inode->i_ino = EXFAT_ROOT_INO;
|
root_inode->i_ino = EXFAT_ROOT_INO;
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
|
||||||
inode_set_iversion(root_inode, 1);
|
inode_set_iversion(root_inode, 1);
|
||||||
|
#else
|
||||||
|
root_inode->i_version = 1;
|
||||||
|
#endif
|
||||||
err = exfat_read_root(root_inode);
|
err = exfat_read_root(root_inode);
|
||||||
if (err) {
|
if (err) {
|
||||||
exfat_msg(sb, KERN_ERR, "failed to initialize root inode.");
|
exfat_msg(sb, KERN_ERR, "failed to initialize root inode.");
|
||||||
@ -620,6 +831,7 @@ check_nls_io:
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
|
||||||
static int exfat_get_tree(struct fs_context *fc)
|
static int exfat_get_tree(struct fs_context *fc)
|
||||||
{
|
{
|
||||||
return get_tree_bdev(fc, exfat_fill_super);
|
return get_tree_bdev(fc, exfat_fill_super);
|
||||||
@ -660,12 +872,23 @@ static int exfat_init_fs_context(struct fs_context *fc)
|
|||||||
fc->ops = &exfat_context_ops;
|
fc->ops = &exfat_context_ops;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
static struct dentry *exfat_fs_mount(struct file_system_type *fs_type,
|
||||||
|
int flags, const char *dev_name, void *data)
|
||||||
|
{
|
||||||
|
return mount_bdev(fs_type, flags, dev_name, data, exfat_fill_super);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct file_system_type exfat_fs_type = {
|
static struct file_system_type exfat_fs_type = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.name = "exfat",
|
.name = "exfat",
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
|
||||||
.init_fs_context = exfat_init_fs_context,
|
.init_fs_context = exfat_init_fs_context,
|
||||||
.parameters = &exfat_parameters,
|
.parameters = &exfat_parameters,
|
||||||
|
#else
|
||||||
|
.mount = exfat_fs_mount,
|
||||||
|
#endif
|
||||||
.kill_sb = kill_block_super,
|
.kill_sb = kill_block_super,
|
||||||
.fs_flags = FS_REQUIRES_DEV,
|
.fs_flags = FS_REQUIRES_DEV,
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user