Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
f334bcd9
K
Kernel
项目概览
openeuler
/
Kernel
接近 2 年 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
f334bcd9
编写于
10月 08, 2016
作者:
A
Al Viro
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'ovl/misc' into work.misc
上级
73e8fb2d
814184fd
变更
25
隐藏空白更改
内联
并排
Showing
25 changed file
with
170 addition
and
101 deletion
+170
-101
fs/attr.c
fs/attr.c
+15
-0
fs/btrfs/ctree.h
fs/btrfs/ctree.h
+0
-1
fs/btrfs/file.c
fs/btrfs/file.c
+1
-1
fs/btrfs/inode.c
fs/btrfs/inode.c
+0
-15
fs/btrfs/tree-log.c
fs/btrfs/tree-log.c
+2
-2
fs/cifs/cifsfs.h
fs/cifs/cifsfs.h
+10
-0
fs/cifs/dir.c
fs/cifs/dir.c
+3
-3
fs/cifs/inode.c
fs/cifs/inode.c
+1
-1
fs/f2fs/node.c
fs/f2fs/node.c
+2
-5
fs/fat/namei_vfat.c
fs/fat/namei_vfat.c
+15
-4
fs/inode.c
fs/inode.c
+27
-6
fs/internal.h
fs/internal.h
+9
-0
fs/locks.c
fs/locks.c
+30
-23
fs/namei.c
fs/namei.c
+1
-1
fs/namespace.c
fs/namespace.c
+1
-1
fs/open.c
fs/open.c
+14
-3
fs/overlayfs/super.c
fs/overlayfs/super.c
+1
-1
fs/posix_acl.c
fs/posix_acl.c
+6
-5
fs/utimes.c
fs/utimes.c
+1
-16
include/linux/dcache.h
include/linux/dcache.h
+3
-2
include/linux/fs.h
include/linux/fs.h
+15
-3
include/linux/fsnotify.h
include/linux/fsnotify.h
+9
-5
include/uapi/linux/fs.h
include/uapi/linux/fs.h
+1
-0
security/integrity/ima/ima_appraise.c
security/integrity/ima/ima_appraise.c
+2
-2
security/integrity/ima/ima_main.c
security/integrity/ima/ima_main.c
+1
-1
未找到文件。
fs/attr.c
浏览文件 @
f334bcd9
...
@@ -202,6 +202,21 @@ int notify_change(struct dentry * dentry, struct iattr * attr, struct inode **de
...
@@ -202,6 +202,21 @@ int notify_change(struct dentry * dentry, struct iattr * attr, struct inode **de
return
-
EPERM
;
return
-
EPERM
;
}
}
/*
* If utimes(2) and friends are called with times == NULL (or both
* times are UTIME_NOW), then we need to check for write permission
*/
if
(
ia_valid
&
ATTR_TOUCH
)
{
if
(
IS_IMMUTABLE
(
inode
))
return
-
EPERM
;
if
(
!
inode_owner_or_capable
(
inode
))
{
error
=
inode_permission
(
inode
,
MAY_WRITE
);
if
(
error
)
return
error
;
}
}
if
((
ia_valid
&
ATTR_MODE
))
{
if
((
ia_valid
&
ATTR_MODE
))
{
umode_t
amode
=
attr
->
ia_mode
;
umode_t
amode
=
attr
->
ia_mode
;
/* Flag setting protected by i_mutex */
/* Flag setting protected by i_mutex */
...
...
fs/btrfs/ctree.h
浏览文件 @
f334bcd9
...
@@ -3161,7 +3161,6 @@ int btrfs_prealloc_file_range_trans(struct inode *inode,
...
@@ -3161,7 +3161,6 @@ int btrfs_prealloc_file_range_trans(struct inode *inode,
struct
btrfs_trans_handle
*
trans
,
int
mode
,
struct
btrfs_trans_handle
*
trans
,
int
mode
,
u64
start
,
u64
num_bytes
,
u64
min_size
,
u64
start
,
u64
num_bytes
,
u64
min_size
,
loff_t
actual_len
,
u64
*
alloc_hint
);
loff_t
actual_len
,
u64
*
alloc_hint
);
int
btrfs_inode_check_errors
(
struct
inode
*
inode
);
extern
const
struct
dentry_operations
btrfs_dentry_operations
;
extern
const
struct
dentry_operations
btrfs_dentry_operations
;
#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
void
btrfs_test_inode_set_ops
(
struct
inode
*
inode
);
void
btrfs_test_inode_set_ops
(
struct
inode
*
inode
);
...
...
fs/btrfs/file.c
浏览文件 @
f334bcd9
...
@@ -2040,7 +2040,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
...
@@ -2040,7 +2040,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
* flags for any errors that might have happened while doing
* flags for any errors that might have happened while doing
* writeback of file data.
* writeback of file data.
*/
*/
ret
=
btrfs_inode_check_errors
(
inode
);
ret
=
filemap_check_errors
(
inode
->
i_mapping
);
inode_unlock
(
inode
);
inode_unlock
(
inode
);
goto
out
;
goto
out
;
}
}
...
...
fs/btrfs/inode.c
浏览文件 @
f334bcd9
...
@@ -10543,21 +10543,6 @@ static int btrfs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
...
@@ -10543,21 +10543,6 @@ static int btrfs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
}
}
/* Inspired by filemap_check_errors() */
int
btrfs_inode_check_errors
(
struct
inode
*
inode
)
{
int
ret
=
0
;
if
(
test_bit
(
AS_ENOSPC
,
&
inode
->
i_mapping
->
flags
)
&&
test_and_clear_bit
(
AS_ENOSPC
,
&
inode
->
i_mapping
->
flags
))
ret
=
-
ENOSPC
;
if
(
test_bit
(
AS_EIO
,
&
inode
->
i_mapping
->
flags
)
&&
test_and_clear_bit
(
AS_EIO
,
&
inode
->
i_mapping
->
flags
))
ret
=
-
EIO
;
return
ret
;
}
static
const
struct
inode_operations
btrfs_dir_inode_operations
=
{
static
const
struct
inode_operations
btrfs_dir_inode_operations
=
{
.
getattr
=
btrfs_getattr
,
.
getattr
=
btrfs_getattr
,
.
lookup
=
btrfs_lookup
,
.
lookup
=
btrfs_lookup
,
...
...
fs/btrfs/tree-log.c
浏览文件 @
f334bcd9
...
@@ -3961,7 +3961,7 @@ static int wait_ordered_extents(struct btrfs_trans_handle *trans,
...
@@ -3961,7 +3961,7 @@ static int wait_ordered_extents(struct btrfs_trans_handle *trans,
* i_mapping flags, so that the next fsync won't get
* i_mapping flags, so that the next fsync won't get
* an outdated io error too.
* an outdated io error too.
*/
*/
btrfs_inode_check_errors
(
inode
);
filemap_check_errors
(
inode
->
i_mapping
);
*
ordered_io_error
=
true
;
*
ordered_io_error
=
true
;
break
;
break
;
}
}
...
@@ -4198,7 +4198,7 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans,
...
@@ -4198,7 +4198,7 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans,
* without writing to the log tree and the fsync must report the
* without writing to the log tree and the fsync must report the
* file data write error and not commit the current transaction.
* file data write error and not commit the current transaction.
*/
*/
ret
=
btrfs_inode_check_errors
(
inode
);
ret
=
filemap_check_errors
(
inode
->
i_mapping
);
if
(
ret
)
if
(
ret
)
ctx
->
io_err
=
ret
;
ctx
->
io_err
=
ret
;
process:
process:
...
...
fs/cifs/cifsfs.h
浏览文件 @
f334bcd9
...
@@ -41,6 +41,16 @@ cifs_uniqueid_to_ino_t(u64 fileid)
...
@@ -41,6 +41,16 @@ cifs_uniqueid_to_ino_t(u64 fileid)
}
}
static
inline
void
cifs_set_time
(
struct
dentry
*
dentry
,
unsigned
long
time
)
{
dentry
->
d_fsdata
=
(
void
*
)
time
;
}
static
inline
unsigned
long
cifs_get_time
(
struct
dentry
*
dentry
)
{
return
(
unsigned
long
)
dentry
->
d_fsdata
;
}
extern
struct
file_system_type
cifs_fs_type
;
extern
struct
file_system_type
cifs_fs_type
;
extern
const
struct
address_space_operations
cifs_addr_ops
;
extern
const
struct
address_space_operations
cifs_addr_ops
;
extern
const
struct
address_space_operations
cifs_addr_ops_smallbuf
;
extern
const
struct
address_space_operations
cifs_addr_ops_smallbuf
;
...
...
fs/cifs/dir.c
浏览文件 @
f334bcd9
...
@@ -40,7 +40,7 @@ renew_parental_timestamps(struct dentry *direntry)
...
@@ -40,7 +40,7 @@ renew_parental_timestamps(struct dentry *direntry)
/* BB check if there is a way to get the kernel to do this or if we
/* BB check if there is a way to get the kernel to do this or if we
really need this */
really need this */
do
{
do
{
direntry
->
d_time
=
jiffies
;
cifs_set_time
(
direntry
,
jiffies
)
;
direntry
=
direntry
->
d_parent
;
direntry
=
direntry
->
d_parent
;
}
while
(
!
IS_ROOT
(
direntry
));
}
while
(
!
IS_ROOT
(
direntry
));
}
}
...
@@ -802,7 +802,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
...
@@ -802,7 +802,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
}
else
if
(
rc
==
-
ENOENT
)
{
}
else
if
(
rc
==
-
ENOENT
)
{
rc
=
0
;
rc
=
0
;
direntry
->
d_time
=
jiffies
;
cifs_set_time
(
direntry
,
jiffies
)
;
d_add
(
direntry
,
NULL
);
d_add
(
direntry
,
NULL
);
/* if it was once a directory (but how can we tell?) we could do
/* if it was once a directory (but how can we tell?) we could do
shrink_dcache_parent(direntry); */
shrink_dcache_parent(direntry); */
...
@@ -862,7 +862,7 @@ cifs_d_revalidate(struct dentry *direntry, unsigned int flags)
...
@@ -862,7 +862,7 @@ cifs_d_revalidate(struct dentry *direntry, unsigned int flags)
if
(
flags
&
(
LOOKUP_CREATE
|
LOOKUP_RENAME_TARGET
))
if
(
flags
&
(
LOOKUP_CREATE
|
LOOKUP_RENAME_TARGET
))
return
0
;
return
0
;
if
(
time_after
(
jiffies
,
direntry
->
d_time
+
HZ
)
||
!
lookupCacheEnabled
)
if
(
time_after
(
jiffies
,
cifs_get_time
(
direntry
)
+
HZ
)
||
!
lookupCacheEnabled
)
return
0
;
return
0
;
return
1
;
return
1
;
...
...
fs/cifs/inode.c
浏览文件 @
f334bcd9
...
@@ -1951,7 +1951,7 @@ int cifs_revalidate_dentry_attr(struct dentry *dentry)
...
@@ -1951,7 +1951,7 @@ int cifs_revalidate_dentry_attr(struct dentry *dentry)
cifs_dbg
(
FYI
,
"Update attributes: %s inode 0x%p count %d dentry: 0x%p d_time %ld jiffies %ld
\n
"
,
cifs_dbg
(
FYI
,
"Update attributes: %s inode 0x%p count %d dentry: 0x%p d_time %ld jiffies %ld
\n
"
,
full_path
,
inode
,
inode
->
i_count
.
counter
,
full_path
,
inode
,
inode
->
i_count
.
counter
,
dentry
,
dentry
->
d_time
,
jiffies
);
dentry
,
cifs_get_time
(
dentry
)
,
jiffies
);
if
(
cifs_sb_master_tcon
(
CIFS_SB
(
sb
))
->
unix_ext
)
if
(
cifs_sb_master_tcon
(
CIFS_SB
(
sb
))
->
unix_ext
)
rc
=
cifs_get_inode_info_unix
(
&
inode
,
full_path
,
sb
,
xid
);
rc
=
cifs_get_inode_info_unix
(
&
inode
,
full_path
,
sb
,
xid
);
...
...
fs/f2fs/node.c
浏览文件 @
f334bcd9
...
@@ -1513,7 +1513,7 @@ int wait_on_node_pages_writeback(struct f2fs_sb_info *sbi, nid_t ino)
...
@@ -1513,7 +1513,7 @@ int wait_on_node_pages_writeback(struct f2fs_sb_info *sbi, nid_t ino)
{
{
pgoff_t
index
=
0
,
end
=
ULONG_MAX
;
pgoff_t
index
=
0
,
end
=
ULONG_MAX
;
struct
pagevec
pvec
;
struct
pagevec
pvec
;
int
ret2
=
0
,
ret
=
0
;
int
ret2
,
ret
=
0
;
pagevec_init
(
&
pvec
,
0
);
pagevec_init
(
&
pvec
,
0
);
...
@@ -1542,10 +1542,7 @@ int wait_on_node_pages_writeback(struct f2fs_sb_info *sbi, nid_t ino)
...
@@ -1542,10 +1542,7 @@ int wait_on_node_pages_writeback(struct f2fs_sb_info *sbi, nid_t ino)
cond_resched
();
cond_resched
();
}
}
if
(
unlikely
(
test_and_clear_bit
(
AS_ENOSPC
,
&
NODE_MAPPING
(
sbi
)
->
flags
)))
ret2
=
filemap_check_errors
(
NODE_MAPPING
(
sbi
));
ret2
=
-
ENOSPC
;
if
(
unlikely
(
test_and_clear_bit
(
AS_EIO
,
&
NODE_MAPPING
(
sbi
)
->
flags
)))
ret2
=
-
EIO
;
if
(
!
ret
)
if
(
!
ret
)
ret
=
ret2
;
ret
=
ret2
;
return
ret
;
return
ret
;
...
...
fs/fat/namei_vfat.c
浏览文件 @
f334bcd9
...
@@ -21,6 +21,17 @@
...
@@ -21,6 +21,17 @@
#include <linux/namei.h>
#include <linux/namei.h>
#include "fat.h"
#include "fat.h"
static
inline
unsigned
long
vfat_d_version
(
struct
dentry
*
dentry
)
{
return
(
unsigned
long
)
dentry
->
d_fsdata
;
}
static
inline
void
vfat_d_version_set
(
struct
dentry
*
dentry
,
unsigned
long
version
)
{
dentry
->
d_fsdata
=
(
void
*
)
version
;
}
/*
/*
* If new entry was created in the parent, it could create the 8.3
* If new entry was created in the parent, it could create the 8.3
* alias (the shortname of logname). So, the parent may have the
* alias (the shortname of logname). So, the parent may have the
...
@@ -33,7 +44,7 @@ static int vfat_revalidate_shortname(struct dentry *dentry)
...
@@ -33,7 +44,7 @@ static int vfat_revalidate_shortname(struct dentry *dentry)
{
{
int
ret
=
1
;
int
ret
=
1
;
spin_lock
(
&
dentry
->
d_lock
);
spin_lock
(
&
dentry
->
d_lock
);
if
(
dentry
->
d_time
!=
d_inode
(
dentry
->
d_parent
)
->
i_version
)
if
(
vfat_d_version
(
dentry
)
!=
d_inode
(
dentry
->
d_parent
)
->
i_version
)
ret
=
0
;
ret
=
0
;
spin_unlock
(
&
dentry
->
d_lock
);
spin_unlock
(
&
dentry
->
d_lock
);
return
ret
;
return
ret
;
...
@@ -759,7 +770,7 @@ static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry,
...
@@ -759,7 +770,7 @@ static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry,
out:
out:
mutex_unlock
(
&
MSDOS_SB
(
sb
)
->
s_lock
);
mutex_unlock
(
&
MSDOS_SB
(
sb
)
->
s_lock
);
if
(
!
inode
)
if
(
!
inode
)
dentry
->
d_time
=
dir
->
i_version
;
vfat_d_version_set
(
dentry
,
dir
->
i_version
)
;
return
d_splice_alias
(
inode
,
dentry
);
return
d_splice_alias
(
inode
,
dentry
);
error:
error:
mutex_unlock
(
&
MSDOS_SB
(
sb
)
->
s_lock
);
mutex_unlock
(
&
MSDOS_SB
(
sb
)
->
s_lock
);
...
@@ -823,7 +834,7 @@ static int vfat_rmdir(struct inode *dir, struct dentry *dentry)
...
@@ -823,7 +834,7 @@ static int vfat_rmdir(struct inode *dir, struct dentry *dentry)
clear_nlink
(
inode
);
clear_nlink
(
inode
);
inode
->
i_mtime
=
inode
->
i_atime
=
CURRENT_TIME_SEC
;
inode
->
i_mtime
=
inode
->
i_atime
=
CURRENT_TIME_SEC
;
fat_detach
(
inode
);
fat_detach
(
inode
);
dentry
->
d_time
=
dir
->
i_version
;
vfat_d_version_set
(
dentry
,
dir
->
i_version
)
;
out:
out:
mutex_unlock
(
&
MSDOS_SB
(
sb
)
->
s_lock
);
mutex_unlock
(
&
MSDOS_SB
(
sb
)
->
s_lock
);
...
@@ -849,7 +860,7 @@ static int vfat_unlink(struct inode *dir, struct dentry *dentry)
...
@@ -849,7 +860,7 @@ static int vfat_unlink(struct inode *dir, struct dentry *dentry)
clear_nlink
(
inode
);
clear_nlink
(
inode
);
inode
->
i_mtime
=
inode
->
i_atime
=
CURRENT_TIME_SEC
;
inode
->
i_mtime
=
inode
->
i_atime
=
CURRENT_TIME_SEC
;
fat_detach
(
inode
);
fat_detach
(
inode
);
dentry
->
d_time
=
dir
->
i_version
;
vfat_d_version_set
(
dentry
,
dir
->
i_version
)
;
out:
out:
mutex_unlock
(
&
MSDOS_SB
(
sb
)
->
s_lock
);
mutex_unlock
(
&
MSDOS_SB
(
sb
)
->
s_lock
);
...
...
fs/inode.c
浏览文件 @
f334bcd9
...
@@ -1562,17 +1562,37 @@ sector_t bmap(struct inode *inode, sector_t block)
...
@@ -1562,17 +1562,37 @@ sector_t bmap(struct inode *inode, sector_t block)
}
}
EXPORT_SYMBOL
(
bmap
);
EXPORT_SYMBOL
(
bmap
);
/*
* Update times in overlayed inode from underlying real inode
*/
static
void
update_ovl_inode_times
(
struct
dentry
*
dentry
,
struct
inode
*
inode
,
bool
rcu
)
{
if
(
!
rcu
)
{
struct
inode
*
realinode
=
d_real_inode
(
dentry
);
if
(
unlikely
(
inode
!=
realinode
)
&&
(
!
timespec_equal
(
&
inode
->
i_mtime
,
&
realinode
->
i_mtime
)
||
!
timespec_equal
(
&
inode
->
i_ctime
,
&
realinode
->
i_ctime
)))
{
inode
->
i_mtime
=
realinode
->
i_mtime
;
inode
->
i_ctime
=
realinode
->
i_ctime
;
}
}
}
/*
/*
* With relative atime, only update atime if the previous atime is
* With relative atime, only update atime if the previous atime is
* earlier than either the ctime or mtime or if at least a day has
* earlier than either the ctime or mtime or if at least a day has
* passed since the last atime update.
* passed since the last atime update.
*/
*/
static
int
relatime_need_update
(
struct
vfsmount
*
mnt
,
struct
inode
*
inode
,
static
int
relatime_need_update
(
const
struct
path
*
path
,
struct
inode
*
inode
,
struct
timespec
now
)
struct
timespec
now
,
bool
rcu
)
{
{
if
(
!
(
mnt
->
mnt_flags
&
MNT_RELATIME
))
if
(
!
(
path
->
mnt
->
mnt_flags
&
MNT_RELATIME
))
return
1
;
return
1
;
update_ovl_inode_times
(
path
->
dentry
,
inode
,
rcu
);
/*
/*
* Is mtime younger than atime? If yes, update atime:
* Is mtime younger than atime? If yes, update atime:
*/
*/
...
@@ -1639,7 +1659,8 @@ static int update_time(struct inode *inode, struct timespec *time, int flags)
...
@@ -1639,7 +1659,8 @@ static int update_time(struct inode *inode, struct timespec *time, int flags)
* This function automatically handles read only file systems and media,
* This function automatically handles read only file systems and media,
* as well as the "noatime" flag and inode specific "noatime" markers.
* as well as the "noatime" flag and inode specific "noatime" markers.
*/
*/
bool
atime_needs_update
(
const
struct
path
*
path
,
struct
inode
*
inode
)
bool
__atime_needs_update
(
const
struct
path
*
path
,
struct
inode
*
inode
,
bool
rcu
)
{
{
struct
vfsmount
*
mnt
=
path
->
mnt
;
struct
vfsmount
*
mnt
=
path
->
mnt
;
struct
timespec
now
;
struct
timespec
now
;
...
@@ -1665,7 +1686,7 @@ bool atime_needs_update(const struct path *path, struct inode *inode)
...
@@ -1665,7 +1686,7 @@ bool atime_needs_update(const struct path *path, struct inode *inode)
now
=
current_fs_time
(
inode
->
i_sb
);
now
=
current_fs_time
(
inode
->
i_sb
);
if
(
!
relatime_need_update
(
mnt
,
inode
,
now
))
if
(
!
relatime_need_update
(
path
,
inode
,
now
,
rcu
))
return
false
;
return
false
;
if
(
timespec_equal
(
&
inode
->
i_atime
,
&
now
))
if
(
timespec_equal
(
&
inode
->
i_atime
,
&
now
))
...
@@ -1680,7 +1701,7 @@ void touch_atime(const struct path *path)
...
@@ -1680,7 +1701,7 @@ void touch_atime(const struct path *path)
struct
inode
*
inode
=
d_inode
(
path
->
dentry
);
struct
inode
*
inode
=
d_inode
(
path
->
dentry
);
struct
timespec
now
;
struct
timespec
now
;
if
(
!
atime_needs_update
(
path
,
inod
e
))
if
(
!
__atime_needs_update
(
path
,
inode
,
fals
e
))
return
;
return
;
if
(
!
sb_start_write_trylock
(
inode
->
i_sb
))
if
(
!
sb_start_write_trylock
(
inode
->
i_sb
))
...
...
fs/internal.h
浏览文件 @
f334bcd9
...
@@ -120,6 +120,15 @@ extern long prune_icache_sb(struct super_block *sb, struct shrink_control *sc);
...
@@ -120,6 +120,15 @@ extern long prune_icache_sb(struct super_block *sb, struct shrink_control *sc);
extern
void
inode_add_lru
(
struct
inode
*
inode
);
extern
void
inode_add_lru
(
struct
inode
*
inode
);
extern
int
dentry_needs_remove_privs
(
struct
dentry
*
dentry
);
extern
int
dentry_needs_remove_privs
(
struct
dentry
*
dentry
);
extern
bool
__atime_needs_update
(
const
struct
path
*
,
struct
inode
*
,
bool
);
static
inline
bool
atime_needs_update_rcu
(
const
struct
path
*
path
,
struct
inode
*
inode
)
{
return
__atime_needs_update
(
path
,
inode
,
true
);
}
extern
bool
atime_needs_update_rcu
(
const
struct
path
*
,
struct
inode
*
);
/*
/*
* fs-writeback.c
* fs-writeback.c
*/
*/
...
...
fs/locks.c
浏览文件 @
f334bcd9
...
@@ -139,6 +139,11 @@
...
@@ -139,6 +139,11 @@
#define IS_LEASE(fl) (fl->fl_flags & (FL_LEASE|FL_DELEG|FL_LAYOUT))
#define IS_LEASE(fl) (fl->fl_flags & (FL_LEASE|FL_DELEG|FL_LAYOUT))
#define IS_OFDLCK(fl) (fl->fl_flags & FL_OFDLCK)
#define IS_OFDLCK(fl) (fl->fl_flags & FL_OFDLCK)
static
inline
bool
is_remote_lock
(
struct
file
*
filp
)
{
return
likely
(
!
(
filp
->
f_path
.
dentry
->
d_sb
->
s_flags
&
MS_NOREMOTELOCK
));
}
static
bool
lease_breaking
(
struct
file_lock
*
fl
)
static
bool
lease_breaking
(
struct
file_lock
*
fl
)
{
{
return
fl
->
fl_flags
&
(
FL_UNLOCK_PENDING
|
FL_DOWNGRADE_PENDING
);
return
fl
->
fl_flags
&
(
FL_UNLOCK_PENDING
|
FL_DOWNGRADE_PENDING
);
...
@@ -791,7 +796,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl)
...
@@ -791,7 +796,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl)
{
{
struct
file_lock
*
cfl
;
struct
file_lock
*
cfl
;
struct
file_lock_context
*
ctx
;
struct
file_lock_context
*
ctx
;
struct
inode
*
inode
=
file
_inode
(
filp
);
struct
inode
*
inode
=
locks
_inode
(
filp
);
ctx
=
smp_load_acquire
(
&
inode
->
i_flctx
);
ctx
=
smp_load_acquire
(
&
inode
->
i_flctx
);
if
(
!
ctx
||
list_empty_careful
(
&
ctx
->
flc_posix
))
{
if
(
!
ctx
||
list_empty_careful
(
&
ctx
->
flc_posix
))
{
...
@@ -1192,7 +1197,7 @@ static int posix_lock_inode(struct inode *inode, struct file_lock *request,
...
@@ -1192,7 +1197,7 @@ static int posix_lock_inode(struct inode *inode, struct file_lock *request,
int
posix_lock_file
(
struct
file
*
filp
,
struct
file_lock
*
fl
,
int
posix_lock_file
(
struct
file
*
filp
,
struct
file_lock
*
fl
,
struct
file_lock
*
conflock
)
struct
file_lock
*
conflock
)
{
{
return
posix_lock_inode
(
file
_inode
(
filp
),
fl
,
conflock
);
return
posix_lock_inode
(
locks
_inode
(
filp
),
fl
,
conflock
);
}
}
EXPORT_SYMBOL
(
posix_lock_file
);
EXPORT_SYMBOL
(
posix_lock_file
);
...
@@ -1232,7 +1237,7 @@ static int posix_lock_inode_wait(struct inode *inode, struct file_lock *fl)
...
@@ -1232,7 +1237,7 @@ static int posix_lock_inode_wait(struct inode *inode, struct file_lock *fl)
int
locks_mandatory_locked
(
struct
file
*
file
)
int
locks_mandatory_locked
(
struct
file
*
file
)
{
{
int
ret
;
int
ret
;
struct
inode
*
inode
=
file
_inode
(
file
);
struct
inode
*
inode
=
locks
_inode
(
file
);
struct
file_lock_context
*
ctx
;
struct
file_lock_context
*
ctx
;
struct
file_lock
*
fl
;
struct
file_lock
*
fl
;
...
@@ -1572,7 +1577,7 @@ EXPORT_SYMBOL(lease_get_mtime);
...
@@ -1572,7 +1577,7 @@ EXPORT_SYMBOL(lease_get_mtime);
int
fcntl_getlease
(
struct
file
*
filp
)
int
fcntl_getlease
(
struct
file
*
filp
)
{
{
struct
file_lock
*
fl
;
struct
file_lock
*
fl
;
struct
inode
*
inode
=
file
_inode
(
filp
);
struct
inode
*
inode
=
locks
_inode
(
filp
);
struct
file_lock_context
*
ctx
;
struct
file_lock_context
*
ctx
;
int
type
=
F_UNLCK
;
int
type
=
F_UNLCK
;
LIST_HEAD
(
dispose
);
LIST_HEAD
(
dispose
);
...
@@ -1580,7 +1585,7 @@ int fcntl_getlease(struct file *filp)
...
@@ -1580,7 +1585,7 @@ int fcntl_getlease(struct file *filp)
ctx
=
smp_load_acquire
(
&
inode
->
i_flctx
);
ctx
=
smp_load_acquire
(
&
inode
->
i_flctx
);
if
(
ctx
&&
!
list_empty_careful
(
&
ctx
->
flc_lease
))
{
if
(
ctx
&&
!
list_empty_careful
(
&
ctx
->
flc_lease
))
{
spin_lock
(
&
ctx
->
flc_lock
);
spin_lock
(
&
ctx
->
flc_lock
);
time_out_leases
(
file_inode
(
filp
)
,
&
dispose
);
time_out_leases
(
inode
,
&
dispose
);
list_for_each_entry
(
fl
,
&
ctx
->
flc_lease
,
fl_list
)
{
list_for_each_entry
(
fl
,
&
ctx
->
flc_lease
,
fl_list
)
{
if
(
fl
->
fl_file
!=
filp
)
if
(
fl
->
fl_file
!=
filp
)
continue
;
continue
;
...
@@ -1613,7 +1618,8 @@ check_conflicting_open(const struct dentry *dentry, const long arg, int flags)
...
@@ -1613,7 +1618,8 @@ check_conflicting_open(const struct dentry *dentry, const long arg, int flags)
if
(
flags
&
FL_LAYOUT
)
if
(
flags
&
FL_LAYOUT
)
return
0
;
return
0
;
if
((
arg
==
F_RDLCK
)
&&
(
atomic_read
(
&
inode
->
i_writecount
)
>
0
))
if
((
arg
==
F_RDLCK
)
&&
(
atomic_read
(
&
d_real_inode
(
dentry
)
->
i_writecount
)
>
0
))
return
-
EAGAIN
;
return
-
EAGAIN
;
if
((
arg
==
F_WRLCK
)
&&
((
d_count
(
dentry
)
>
1
)
||
if
((
arg
==
F_WRLCK
)
&&
((
d_count
(
dentry
)
>
1
)
||
...
@@ -1628,7 +1634,7 @@ generic_add_lease(struct file *filp, long arg, struct file_lock **flp, void **pr
...
@@ -1628,7 +1634,7 @@ generic_add_lease(struct file *filp, long arg, struct file_lock **flp, void **pr
{
{
struct
file_lock
*
fl
,
*
my_fl
=
NULL
,
*
lease
;
struct
file_lock
*
fl
,
*
my_fl
=
NULL
,
*
lease
;
struct
dentry
*
dentry
=
filp
->
f_path
.
dentry
;
struct
dentry
*
dentry
=
filp
->
f_path
.
dentry
;
struct
inode
*
inode
=
file_inode
(
filp
)
;
struct
inode
*
inode
=
dentry
->
d_inode
;
struct
file_lock_context
*
ctx
;
struct
file_lock_context
*
ctx
;
bool
is_deleg
=
(
*
flp
)
->
fl_flags
&
FL_DELEG
;
bool
is_deleg
=
(
*
flp
)
->
fl_flags
&
FL_DELEG
;
int
error
;
int
error
;
...
@@ -1742,7 +1748,7 @@ static int generic_delete_lease(struct file *filp, void *owner)
...
@@ -1742,7 +1748,7 @@ static int generic_delete_lease(struct file *filp, void *owner)
{
{
int
error
=
-
EAGAIN
;
int
error
=
-
EAGAIN
;
struct
file_lock
*
fl
,
*
victim
=
NULL
;
struct
file_lock
*
fl
,
*
victim
=
NULL
;
struct
inode
*
inode
=
file
_inode
(
filp
);
struct
inode
*
inode
=
locks
_inode
(
filp
);
struct
file_lock_context
*
ctx
;
struct
file_lock_context
*
ctx
;
LIST_HEAD
(
dispose
);
LIST_HEAD
(
dispose
);
...
@@ -1782,7 +1788,7 @@ static int generic_delete_lease(struct file *filp, void *owner)
...
@@ -1782,7 +1788,7 @@ static int generic_delete_lease(struct file *filp, void *owner)
int
generic_setlease
(
struct
file
*
filp
,
long
arg
,
struct
file_lock
**
flp
,
int
generic_setlease
(
struct
file
*
filp
,
long
arg
,
struct
file_lock
**
flp
,
void
**
priv
)
void
**
priv
)
{
{
struct
inode
*
inode
=
file
_inode
(
filp
);
struct
inode
*
inode
=
locks
_inode
(
filp
);
int
error
;
int
error
;
if
((
!
uid_eq
(
current_fsuid
(),
inode
->
i_uid
))
&&
!
capable
(
CAP_LEASE
))
if
((
!
uid_eq
(
current_fsuid
(),
inode
->
i_uid
))
&&
!
capable
(
CAP_LEASE
))
...
@@ -1830,7 +1836,7 @@ EXPORT_SYMBOL(generic_setlease);
...
@@ -1830,7 +1836,7 @@ EXPORT_SYMBOL(generic_setlease);
int
int
vfs_setlease
(
struct
file
*
filp
,
long
arg
,
struct
file_lock
**
lease
,
void
**
priv
)
vfs_setlease
(
struct
file
*
filp
,
long
arg
,
struct
file_lock
**
lease
,
void
**
priv
)
{
{
if
(
filp
->
f_op
->
setlease
)
if
(
filp
->
f_op
->
setlease
&&
is_remote_lock
(
filp
)
)
return
filp
->
f_op
->
setlease
(
filp
,
arg
,
lease
,
priv
);
return
filp
->
f_op
->
setlease
(
filp
,
arg
,
lease
,
priv
);
else
else
return
generic_setlease
(
filp
,
arg
,
lease
,
priv
);
return
generic_setlease
(
filp
,
arg
,
lease
,
priv
);
...
@@ -1979,7 +1985,7 @@ SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd)
...
@@ -1979,7 +1985,7 @@ SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd)
if
(
error
)
if
(
error
)
goto
out_free
;
goto
out_free
;
if
(
f
.
file
->
f_op
->
flock
)
if
(
f
.
file
->
f_op
->
flock
&&
is_remote_lock
(
f
.
file
)
)
error
=
f
.
file
->
f_op
->
flock
(
f
.
file
,
error
=
f
.
file
->
f_op
->
flock
(
f
.
file
,
(
can_sleep
)
?
F_SETLKW
:
F_SETLK
,
(
can_sleep
)
?
F_SETLKW
:
F_SETLK
,
lock
);
lock
);
...
@@ -2005,7 +2011,7 @@ SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd)
...
@@ -2005,7 +2011,7 @@ SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd)
*/
*/
int
vfs_test_lock
(
struct
file
*
filp
,
struct
file_lock
*
fl
)
int
vfs_test_lock
(
struct
file
*
filp
,
struct
file_lock
*
fl
)
{
{
if
(
filp
->
f_op
->
lock
)
if
(
filp
->
f_op
->
lock
&&
is_remote_lock
(
filp
)
)
return
filp
->
f_op
->
lock
(
filp
,
F_GETLK
,
fl
);
return
filp
->
f_op
->
lock
(
filp
,
F_GETLK
,
fl
);
posix_test_lock
(
filp
,
fl
);
posix_test_lock
(
filp
,
fl
);
return
0
;
return
0
;
...
@@ -2129,7 +2135,7 @@ int fcntl_getlk(struct file *filp, unsigned int cmd, struct flock __user *l)
...
@@ -2129,7 +2135,7 @@ int fcntl_getlk(struct file *filp, unsigned int cmd, struct flock __user *l)
*/
*/
int
vfs_lock_file
(
struct
file
*
filp
,
unsigned
int
cmd
,
struct
file_lock
*
fl
,
struct
file_lock
*
conf
)
int
vfs_lock_file
(
struct
file
*
filp
,
unsigned
int
cmd
,
struct
file_lock
*
fl
,
struct
file_lock
*
conf
)
{
{
if
(
filp
->
f_op
->
lock
)
if
(
filp
->
f_op
->
lock
&&
is_remote_lock
(
filp
)
)
return
filp
->
f_op
->
lock
(
filp
,
cmd
,
fl
);
return
filp
->
f_op
->
lock
(
filp
,
cmd
,
fl
);
else
else
return
posix_lock_file
(
filp
,
fl
,
conf
);
return
posix_lock_file
(
filp
,
fl
,
conf
);
...
@@ -2191,7 +2197,7 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd,
...
@@ -2191,7 +2197,7 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd,
if
(
file_lock
==
NULL
)
if
(
file_lock
==
NULL
)
return
-
ENOLCK
;
return
-
ENOLCK
;
inode
=
file
_inode
(
filp
);
inode
=
locks
_inode
(
filp
);
/*
/*
* This might block, so we do it before checking the inode.
* This might block, so we do it before checking the inode.
...
@@ -2343,7 +2349,7 @@ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd,
...
@@ -2343,7 +2349,7 @@ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd,
if
(
copy_from_user
(
&
flock
,
l
,
sizeof
(
flock
)))
if
(
copy_from_user
(
&
flock
,
l
,
sizeof
(
flock
)))
goto
out
;
goto
out
;
inode
=
file
_inode
(
filp
);
inode
=
locks
_inode
(
filp
);
/* Don't allow mandatory locks on files that may be memory mapped
/* Don't allow mandatory locks on files that may be memory mapped
* and shared.
* and shared.
...
@@ -2426,6 +2432,7 @@ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd,
...
@@ -2426,6 +2432,7 @@ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd,
void
locks_remove_posix
(
struct
file
*
filp
,
fl_owner_t
owner
)
void
locks_remove_posix
(
struct
file
*
filp
,
fl_owner_t
owner
)
{
{
int
error
;
int
error
;
struct
inode
*
inode
=
locks_inode
(
filp
);
struct
file_lock
lock
;
struct
file_lock
lock
;
struct
file_lock_context
*
ctx
;
struct
file_lock_context
*
ctx
;
...
@@ -2434,7 +2441,7 @@ void locks_remove_posix(struct file *filp, fl_owner_t owner)
...
@@ -2434,7 +2441,7 @@ void locks_remove_posix(struct file *filp, fl_owner_t owner)
* posix_lock_file(). Another process could be setting a lock on this
* posix_lock_file(). Another process could be setting a lock on this
* file at the same time, but we wouldn't remove that lock anyway.
* file at the same time, but we wouldn't remove that lock anyway.
*/
*/
ctx
=
smp_load_acquire
(
&
file_inode
(
filp
)
->
i_flctx
);
ctx
=
smp_load_acquire
(
&
inode
->
i_flctx
);
if
(
!
ctx
||
list_empty
(
&
ctx
->
flc_posix
))
if
(
!
ctx
||
list_empty
(
&
ctx
->
flc_posix
))
return
;
return
;
...
@@ -2452,7 +2459,7 @@ void locks_remove_posix(struct file *filp, fl_owner_t owner)
...
@@ -2452,7 +2459,7 @@ void locks_remove_posix(struct file *filp, fl_owner_t owner)
if
(
lock
.
fl_ops
&&
lock
.
fl_ops
->
fl_release_private
)
if
(
lock
.
fl_ops
&&
lock
.
fl_ops
->
fl_release_private
)
lock
.
fl_ops
->
fl_release_private
(
&
lock
);
lock
.
fl_ops
->
fl_release_private
(
&
lock
);
trace_locks_remove_posix
(
file_inode
(
filp
)
,
&
lock
,
error
);
trace_locks_remove_posix
(
inode
,
&
lock
,
error
);
}
}
EXPORT_SYMBOL
(
locks_remove_posix
);
EXPORT_SYMBOL
(
locks_remove_posix
);
...
@@ -2469,12 +2476,12 @@ locks_remove_flock(struct file *filp, struct file_lock_context *flctx)
...
@@ -2469,12 +2476,12 @@ locks_remove_flock(struct file *filp, struct file_lock_context *flctx)
.
fl_type
=
F_UNLCK
,
.
fl_type
=
F_UNLCK
,
.
fl_end
=
OFFSET_MAX
,
.
fl_end
=
OFFSET_MAX
,
};
};
struct
inode
*
inode
=
file
_inode
(
filp
);
struct
inode
*
inode
=
locks
_inode
(
filp
);
if
(
list_empty
(
&
flctx
->
flc_flock
))
if
(
list_empty
(
&
flctx
->
flc_flock
))
return
;
return
;
if
(
filp
->
f_op
->
flock
)
if
(
filp
->
f_op
->
flock
&&
is_remote_lock
(
filp
)
)
filp
->
f_op
->
flock
(
filp
,
F_SETLKW
,
&
fl
);
filp
->
f_op
->
flock
(
filp
,
F_SETLKW
,
&
fl
);
else
else
flock_lock_inode
(
inode
,
&
fl
);
flock_lock_inode
(
inode
,
&
fl
);
...
@@ -2508,7 +2515,7 @@ void locks_remove_file(struct file *filp)
...
@@ -2508,7 +2515,7 @@ void locks_remove_file(struct file *filp)
{
{
struct
file_lock_context
*
ctx
;
struct
file_lock_context
*
ctx
;
ctx
=
smp_load_acquire
(
&
file
_inode
(
filp
)
->
i_flctx
);
ctx
=
smp_load_acquire
(
&
locks
_inode
(
filp
)
->
i_flctx
);
if
(
!
ctx
)
if
(
!
ctx
)
return
;
return
;
...
@@ -2552,7 +2559,7 @@ EXPORT_SYMBOL(posix_unblock_lock);
...
@@ -2552,7 +2559,7 @@ EXPORT_SYMBOL(posix_unblock_lock);
*/
*/
int
vfs_cancel_lock
(
struct
file
*
filp
,
struct
file_lock
*
fl
)
int
vfs_cancel_lock
(
struct
file
*
filp
,
struct
file_lock
*
fl
)
{
{
if
(
filp
->
f_op
->
lock
)
if
(
filp
->
f_op
->
lock
&&
is_remote_lock
(
filp
)
)
return
filp
->
f_op
->
lock
(
filp
,
F_CANCELLK
,
fl
);
return
filp
->
f_op
->
lock
(
filp
,
F_CANCELLK
,
fl
);
return
0
;
return
0
;
}
}
...
@@ -2580,7 +2587,7 @@ static void lock_get_status(struct seq_file *f, struct file_lock *fl,
...
@@ -2580,7 +2587,7 @@ static void lock_get_status(struct seq_file *f, struct file_lock *fl,
fl_pid
=
fl
->
fl_pid
;
fl_pid
=
fl
->
fl_pid
;
if
(
fl
->
fl_file
!=
NULL
)
if
(
fl
->
fl_file
!=
NULL
)
inode
=
file
_inode
(
fl
->
fl_file
);
inode
=
locks
_inode
(
fl
->
fl_file
);
seq_printf
(
f
,
"%lld:%s "
,
id
,
pfx
);
seq_printf
(
f
,
"%lld:%s "
,
id
,
pfx
);
if
(
IS_POSIX
(
fl
))
{
if
(
IS_POSIX
(
fl
))
{
...
@@ -2682,7 +2689,7 @@ static void __show_fd_locks(struct seq_file *f,
...
@@ -2682,7 +2689,7 @@ static void __show_fd_locks(struct seq_file *f,
void
show_fd_locks
(
struct
seq_file
*
f
,
void
show_fd_locks
(
struct
seq_file
*
f
,
struct
file
*
filp
,
struct
files_struct
*
files
)
struct
file
*
filp
,
struct
files_struct
*
files
)
{
{
struct
inode
*
inode
=
file
_inode
(
filp
);
struct
inode
*
inode
=
locks
_inode
(
filp
);
struct
file_lock_context
*
ctx
;
struct
file_lock_context
*
ctx
;
int
id
=
0
;
int
id
=
0
;
...
...
fs/namei.c
浏览文件 @
f334bcd9
...
@@ -1015,7 +1015,7 @@ const char *get_link(struct nameidata *nd)
...
@@ -1015,7 +1015,7 @@ const char *get_link(struct nameidata *nd)
if
(
!
(
nd
->
flags
&
LOOKUP_RCU
))
{
if
(
!
(
nd
->
flags
&
LOOKUP_RCU
))
{
touch_atime
(
&
last
->
link
);
touch_atime
(
&
last
->
link
);
cond_resched
();
cond_resched
();
}
else
if
(
atime_needs_update
(
&
last
->
link
,
inode
))
{
}
else
if
(
atime_needs_update
_rcu
(
&
last
->
link
,
inode
))
{
if
(
unlikely
(
unlazy_walk
(
nd
,
NULL
,
0
)))
if
(
unlikely
(
unlazy_walk
(
nd
,
NULL
,
0
)))
return
ERR_PTR
(
-
ECHILD
);
return
ERR_PTR
(
-
ECHILD
);
touch_atime
(
&
last
->
link
);
touch_atime
(
&
last
->
link
);
...
...
fs/namespace.c
浏览文件 @
f334bcd9
...
@@ -2700,7 +2700,7 @@ long do_mount(const char *dev_name, const char __user *dir_name,
...
@@ -2700,7 +2700,7 @@ long do_mount(const char *dev_name, const char __user *dir_name,
flags
&=
~
(
MS_NOSUID
|
MS_NOEXEC
|
MS_NODEV
|
MS_ACTIVE
|
MS_BORN
|
flags
&=
~
(
MS_NOSUID
|
MS_NOEXEC
|
MS_NODEV
|
MS_ACTIVE
|
MS_BORN
|
MS_NOATIME
|
MS_NODIRATIME
|
MS_RELATIME
|
MS_KERNMOUNT
|
MS_NOATIME
|
MS_NODIRATIME
|
MS_RELATIME
|
MS_KERNMOUNT
|
MS_STRICTATIME
);
MS_STRICTATIME
|
MS_NOREMOTELOCK
);
if
(
flags
&
MS_REMOUNT
)
if
(
flags
&
MS_REMOUNT
)
retval
=
do_remount
(
&
path
,
flags
&
~
MS_REMOUNT
,
mnt_flags
,
retval
=
do_remount
(
&
path
,
flags
&
~
MS_REMOUNT
,
mnt_flags
,
...
...
fs/open.c
浏览文件 @
f334bcd9
...
@@ -68,6 +68,7 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
...
@@ -68,6 +68,7 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
long
vfs_truncate
(
const
struct
path
*
path
,
loff_t
length
)
long
vfs_truncate
(
const
struct
path
*
path
,
loff_t
length
)
{
{
struct
inode
*
inode
;
struct
inode
*
inode
;
struct
dentry
*
upperdentry
;
long
error
;
long
error
;
inode
=
path
->
dentry
->
d_inode
;
inode
=
path
->
dentry
->
d_inode
;
...
@@ -90,7 +91,17 @@ long vfs_truncate(const struct path *path, loff_t length)
...
@@ -90,7 +91,17 @@ long vfs_truncate(const struct path *path, loff_t length)
if
(
IS_APPEND
(
inode
))
if
(
IS_APPEND
(
inode
))
goto
mnt_drop_write_and_out
;
goto
mnt_drop_write_and_out
;
error
=
get_write_access
(
inode
);
/*
* If this is an overlayfs then do as if opening the file so we get
* write access on the upper inode, not on the overlay inode. For
* non-overlay filesystems d_real() is an identity function.
*/
upperdentry
=
d_real
(
path
->
dentry
,
NULL
,
O_WRONLY
);
error
=
PTR_ERR
(
upperdentry
);
if
(
IS_ERR
(
upperdentry
))
goto
mnt_drop_write_and_out
;
error
=
get_write_access
(
upperdentry
->
d_inode
);
if
(
error
)
if
(
error
)
goto
mnt_drop_write_and_out
;
goto
mnt_drop_write_and_out
;
...
@@ -109,7 +120,7 @@ long vfs_truncate(const struct path *path, loff_t length)
...
@@ -109,7 +120,7 @@ long vfs_truncate(const struct path *path, loff_t length)
error
=
do_truncate
(
path
->
dentry
,
length
,
0
,
NULL
);
error
=
do_truncate
(
path
->
dentry
,
length
,
0
,
NULL
);
put_write_and_out:
put_write_and_out:
put_write_access
(
inode
);
put_write_access
(
upperdentry
->
d_
inode
);
mnt_drop_write_and_out:
mnt_drop_write_and_out:
mnt_drop_write
(
path
->
mnt
);
mnt_drop_write
(
path
->
mnt
);
out:
out:
...
@@ -726,7 +737,7 @@ static int do_dentry_open(struct file *f,
...
@@ -726,7 +737,7 @@ static int do_dentry_open(struct file *f,
if
(
error
)
if
(
error
)
goto
cleanup_all
;
goto
cleanup_all
;
error
=
break_lease
(
inode
,
f
->
f_flags
);
error
=
break_lease
(
locks_inode
(
f
)
,
f
->
f_flags
);
if
(
error
)
if
(
error
)
goto
cleanup_all
;
goto
cleanup_all
;
...
...
fs/overlayfs/super.c
浏览文件 @
f334bcd9
...
@@ -1320,7 +1320,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
...
@@ -1320,7 +1320,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
sb
->
s_xattr
=
ovl_xattr_handlers
;
sb
->
s_xattr
=
ovl_xattr_handlers
;
sb
->
s_root
=
root_dentry
;
sb
->
s_root
=
root_dentry
;
sb
->
s_fs_info
=
ufs
;
sb
->
s_fs_info
=
ufs
;
sb
->
s_flags
|=
MS_POSIXACL
;
sb
->
s_flags
|=
MS_POSIXACL
|
MS_NOREMOTELOCK
;
return
0
;
return
0
;
...
...
fs/posix_acl.c
浏览文件 @
f334bcd9
...
@@ -598,13 +598,14 @@ posix_acl_create(struct inode *dir, umode_t *mode,
...
@@ -598,13 +598,14 @@ posix_acl_create(struct inode *dir, umode_t *mode,
if
(
IS_ERR
(
p
))
if
(
IS_ERR
(
p
))
return
PTR_ERR
(
p
);
return
PTR_ERR
(
p
);
ret
=
-
ENOMEM
;
clone
=
posix_acl_clone
(
p
,
GFP_NOFS
);
clone
=
posix_acl_clone
(
p
,
GFP_NOFS
);
if
(
!
clone
)
if
(
!
clone
)
goto
no_mem
;
goto
err_release
;
ret
=
posix_acl_create_masq
(
clone
,
mode
);
ret
=
posix_acl_create_masq
(
clone
,
mode
);
if
(
ret
<
0
)
if
(
ret
<
0
)
goto
no_mem
_clone
;
goto
err_release
_clone
;
if
(
ret
==
0
)
if
(
ret
==
0
)
posix_acl_release
(
clone
);
posix_acl_release
(
clone
);
...
@@ -618,11 +619,11 @@ posix_acl_create(struct inode *dir, umode_t *mode,
...
@@ -618,11 +619,11 @@ posix_acl_create(struct inode *dir, umode_t *mode,
return
0
;
return
0
;
no_mem
_clone:
err_release
_clone:
posix_acl_release
(
clone
);
posix_acl_release
(
clone
);
no_mem
:
err_release
:
posix_acl_release
(
p
);
posix_acl_release
(
p
);
return
-
ENOMEM
;
return
ret
;
}
}
EXPORT_SYMBOL_GPL
(
posix_acl_create
);
EXPORT_SYMBOL_GPL
(
posix_acl_create
);
...
...
fs/utimes.c
浏览文件 @
f334bcd9
...
@@ -87,21 +87,7 @@ static int utimes_common(struct path *path, struct timespec *times)
...
@@ -87,21 +87,7 @@ static int utimes_common(struct path *path, struct timespec *times)
*/
*/
newattrs
.
ia_valid
|=
ATTR_TIMES_SET
;
newattrs
.
ia_valid
|=
ATTR_TIMES_SET
;
}
else
{
}
else
{
/*
newattrs
.
ia_valid
|=
ATTR_TOUCH
;
* If times is NULL (or both times are UTIME_NOW),
* then we need to check permissions, because
* inode_change_ok() won't do it.
*/
error
=
-
EPERM
;
if
(
IS_IMMUTABLE
(
inode
))
goto
mnt_drop_write_and_out
;
error
=
-
EACCES
;
if
(
!
inode_owner_or_capable
(
inode
))
{
error
=
inode_permission
(
inode
,
MAY_WRITE
);
if
(
error
)
goto
mnt_drop_write_and_out
;
}
}
}
retry_deleg:
retry_deleg:
inode_lock
(
inode
);
inode_lock
(
inode
);
...
@@ -113,7 +99,6 @@ static int utimes_common(struct path *path, struct timespec *times)
...
@@ -113,7 +99,6 @@ static int utimes_common(struct path *path, struct timespec *times)
goto
retry_deleg
;
goto
retry_deleg
;
}
}
mnt_drop_write_and_out:
mnt_drop_write
(
path
->
mnt
);
mnt_drop_write
(
path
->
mnt
);
out:
out:
return
error
;
return
error
;
...
...
include/linux/dcache.h
浏览文件 @
f334bcd9
...
@@ -584,9 +584,10 @@ static inline struct dentry *d_real(struct dentry *dentry,
...
@@ -584,9 +584,10 @@ static inline struct dentry *d_real(struct dentry *dentry,
* If dentry is on an union/overlay, then return the underlying, real inode.
* If dentry is on an union/overlay, then return the underlying, real inode.
* Otherwise return d_inode().
* Otherwise return d_inode().
*/
*/
static
inline
struct
inode
*
d_real_inode
(
struct
dentry
*
dentry
)
static
inline
struct
inode
*
d_real_inode
(
const
struct
dentry
*
dentry
)
{
{
return
d_backing_inode
(
d_real
(
dentry
,
NULL
,
0
));
/* This usage of d_real() results in const dentry */
return
d_backing_inode
(
d_real
((
struct
dentry
*
)
dentry
,
NULL
,
0
));
}
}
...
...
include/linux/fs.h
浏览文件 @
f334bcd9
...
@@ -224,6 +224,7 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
...
@@ -224,6 +224,7 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
#define ATTR_KILL_PRIV (1 << 14)
#define ATTR_KILL_PRIV (1 << 14)
#define ATTR_OPEN (1 << 15)
/* Truncating from open(O_TRUNC) */
#define ATTR_OPEN (1 << 15)
/* Truncating from open(O_TRUNC) */
#define ATTR_TIMES_SET (1 << 16)
#define ATTR_TIMES_SET (1 << 16)
#define ATTR_TOUCH (1 << 17)
/*
/*
* Whiteout is represented by a char device. The following constants define the
* Whiteout is represented by a char device. The following constants define the
...
@@ -1064,6 +1065,18 @@ struct file_lock_context {
...
@@ -1064,6 +1065,18 @@ struct file_lock_context {
extern
void
send_sigio
(
struct
fown_struct
*
fown
,
int
fd
,
int
band
);
extern
void
send_sigio
(
struct
fown_struct
*
fown
,
int
fd
,
int
band
);
/*
* Return the inode to use for locking
*
* For overlayfs this should be the overlay inode, not the real inode returned
* by file_inode(). For any other fs file_inode(filp) and locks_inode(filp) are
* equal.
*/
static
inline
struct
inode
*
locks_inode
(
const
struct
file
*
f
)
{
return
f
->
f_path
.
dentry
->
d_inode
;
}
#ifdef CONFIG_FILE_LOCKING
#ifdef CONFIG_FILE_LOCKING
extern
int
fcntl_getlk
(
struct
file
*
,
unsigned
int
,
struct
flock
__user
*
);
extern
int
fcntl_getlk
(
struct
file
*
,
unsigned
int
,
struct
flock
__user
*
);
extern
int
fcntl_setlk
(
unsigned
int
,
struct
file
*
,
unsigned
int
,
extern
int
fcntl_setlk
(
unsigned
int
,
struct
file
*
,
unsigned
int
,
...
@@ -1251,7 +1264,7 @@ static inline struct dentry *file_dentry(const struct file *file)
...
@@ -1251,7 +1264,7 @@ static inline struct dentry *file_dentry(const struct file *file)
static
inline
int
locks_lock_file_wait
(
struct
file
*
filp
,
struct
file_lock
*
fl
)
static
inline
int
locks_lock_file_wait
(
struct
file
*
filp
,
struct
file_lock
*
fl
)
{
{
return
locks_lock_inode_wait
(
file
_inode
(
filp
),
fl
);
return
locks_lock_inode_wait
(
locks
_inode
(
filp
),
fl
);
}
}
struct
fasync_struct
{
struct
fasync_struct
{
...
@@ -2006,7 +2019,6 @@ enum file_time_flags {
...
@@ -2006,7 +2019,6 @@ enum file_time_flags {
S_VERSION
=
8
,
S_VERSION
=
8
,
};
};
extern
bool
atime_needs_update
(
const
struct
path
*
,
struct
inode
*
);
extern
void
touch_atime
(
const
struct
path
*
);
extern
void
touch_atime
(
const
struct
path
*
);
static
inline
void
file_accessed
(
struct
file
*
file
)
static
inline
void
file_accessed
(
struct
file
*
file
)
{
{
...
@@ -2155,7 +2167,7 @@ static inline int mandatory_lock(struct inode *ino)
...
@@ -2155,7 +2167,7 @@ static inline int mandatory_lock(struct inode *ino)
static
inline
int
locks_verify_locked
(
struct
file
*
file
)
static
inline
int
locks_verify_locked
(
struct
file
*
file
)
{
{
if
(
mandatory_lock
(
file
_inode
(
file
)))
if
(
mandatory_lock
(
locks
_inode
(
file
)))
return
locks_mandatory_locked
(
file
);
return
locks_mandatory_locked
(
file
);
return
0
;
return
0
;
}
}
...
...
include/linux/fsnotify.h
浏览文件 @
f334bcd9
...
@@ -29,7 +29,11 @@ static inline int fsnotify_parent(struct path *path, struct dentry *dentry, __u3
...
@@ -29,7 +29,11 @@ static inline int fsnotify_parent(struct path *path, struct dentry *dentry, __u3
static
inline
int
fsnotify_perm
(
struct
file
*
file
,
int
mask
)
static
inline
int
fsnotify_perm
(
struct
file
*
file
,
int
mask
)
{
{
struct
path
*
path
=
&
file
->
f_path
;
struct
path
*
path
=
&
file
->
f_path
;
struct
inode
*
inode
=
file_inode
(
file
);
/*
* Do not use file_inode() here or anywhere in this file to get the
* inode. That would break *notity on overlayfs.
*/
struct
inode
*
inode
=
path
->
dentry
->
d_inode
;
__u32
fsnotify_mask
=
0
;
__u32
fsnotify_mask
=
0
;
int
ret
;
int
ret
;
...
@@ -173,7 +177,7 @@ static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry)
...
@@ -173,7 +177,7 @@ static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry)
static
inline
void
fsnotify_access
(
struct
file
*
file
)
static
inline
void
fsnotify_access
(
struct
file
*
file
)
{
{
struct
path
*
path
=
&
file
->
f_path
;
struct
path
*
path
=
&
file
->
f_path
;
struct
inode
*
inode
=
file_inode
(
file
)
;
struct
inode
*
inode
=
path
->
dentry
->
d_inode
;
__u32
mask
=
FS_ACCESS
;
__u32
mask
=
FS_ACCESS
;
if
(
S_ISDIR
(
inode
->
i_mode
))
if
(
S_ISDIR
(
inode
->
i_mode
))
...
@@ -191,7 +195,7 @@ static inline void fsnotify_access(struct file *file)
...
@@ -191,7 +195,7 @@ static inline void fsnotify_access(struct file *file)
static
inline
void
fsnotify_modify
(
struct
file
*
file
)
static
inline
void
fsnotify_modify
(
struct
file
*
file
)
{
{
struct
path
*
path
=
&
file
->
f_path
;
struct
path
*
path
=
&
file
->
f_path
;
struct
inode
*
inode
=
file_inode
(
file
)
;
struct
inode
*
inode
=
path
->
dentry
->
d_inode
;
__u32
mask
=
FS_MODIFY
;
__u32
mask
=
FS_MODIFY
;
if
(
S_ISDIR
(
inode
->
i_mode
))
if
(
S_ISDIR
(
inode
->
i_mode
))
...
@@ -209,7 +213,7 @@ static inline void fsnotify_modify(struct file *file)
...
@@ -209,7 +213,7 @@ static inline void fsnotify_modify(struct file *file)
static
inline
void
fsnotify_open
(
struct
file
*
file
)
static
inline
void
fsnotify_open
(
struct
file
*
file
)
{
{
struct
path
*
path
=
&
file
->
f_path
;
struct
path
*
path
=
&
file
->
f_path
;
struct
inode
*
inode
=
file_inode
(
file
)
;
struct
inode
*
inode
=
path
->
dentry
->
d_inode
;
__u32
mask
=
FS_OPEN
;
__u32
mask
=
FS_OPEN
;
if
(
S_ISDIR
(
inode
->
i_mode
))
if
(
S_ISDIR
(
inode
->
i_mode
))
...
@@ -225,7 +229,7 @@ static inline void fsnotify_open(struct file *file)
...
@@ -225,7 +229,7 @@ static inline void fsnotify_open(struct file *file)
static
inline
void
fsnotify_close
(
struct
file
*
file
)
static
inline
void
fsnotify_close
(
struct
file
*
file
)
{
{
struct
path
*
path
=
&
file
->
f_path
;
struct
path
*
path
=
&
file
->
f_path
;
struct
inode
*
inode
=
file_inode
(
file
)
;
struct
inode
*
inode
=
path
->
dentry
->
d_inode
;
fmode_t
mode
=
file
->
f_mode
;
fmode_t
mode
=
file
->
f_mode
;
__u32
mask
=
(
mode
&
FMODE_WRITE
)
?
FS_CLOSE_WRITE
:
FS_CLOSE_NOWRITE
;
__u32
mask
=
(
mode
&
FMODE_WRITE
)
?
FS_CLOSE_WRITE
:
FS_CLOSE_NOWRITE
;
...
...
include/uapi/linux/fs.h
浏览文件 @
f334bcd9
...
@@ -132,6 +132,7 @@ struct inodes_stat_t {
...
@@ -132,6 +132,7 @@ struct inodes_stat_t {
#define MS_LAZYTIME (1<<25)
/* Update the on-disk [acm]times lazily */
#define MS_LAZYTIME (1<<25)
/* Update the on-disk [acm]times lazily */
/* These sb flags are internal to the kernel */
/* These sb flags are internal to the kernel */
#define MS_NOREMOTELOCK (1<<27)
#define MS_NOSEC (1<<28)
#define MS_NOSEC (1<<28)
#define MS_BORN (1<<29)
#define MS_BORN (1<<29)
#define MS_ACTIVE (1<<30)
#define MS_ACTIVE (1<<30)
...
...
security/integrity/ima/ima_appraise.c
浏览文件 @
f334bcd9
...
@@ -190,7 +190,7 @@ int ima_appraise_measurement(enum ima_hooks func,
...
@@ -190,7 +190,7 @@ int ima_appraise_measurement(enum ima_hooks func,
{
{
static
const
char
op
[]
=
"appraise_data"
;
static
const
char
op
[]
=
"appraise_data"
;
char
*
cause
=
"unknown"
;
char
*
cause
=
"unknown"
;
struct
dentry
*
dentry
=
file
->
f_path
.
dentry
;
struct
dentry
*
dentry
=
file
_dentry
(
file
)
;
struct
inode
*
inode
=
d_backing_inode
(
dentry
);
struct
inode
*
inode
=
d_backing_inode
(
dentry
);
enum
integrity_status
status
=
INTEGRITY_UNKNOWN
;
enum
integrity_status
status
=
INTEGRITY_UNKNOWN
;
int
rc
=
xattr_len
,
hash_start
=
0
;
int
rc
=
xattr_len
,
hash_start
=
0
;
...
@@ -295,7 +295,7 @@ int ima_appraise_measurement(enum ima_hooks func,
...
@@ -295,7 +295,7 @@ int ima_appraise_measurement(enum ima_hooks func,
*/
*/
void
ima_update_xattr
(
struct
integrity_iint_cache
*
iint
,
struct
file
*
file
)
void
ima_update_xattr
(
struct
integrity_iint_cache
*
iint
,
struct
file
*
file
)
{
{
struct
dentry
*
dentry
=
file
->
f_path
.
dentry
;
struct
dentry
*
dentry
=
file
_dentry
(
file
)
;
int
rc
=
0
;
int
rc
=
0
;
/* do not collect and update hash for digital signatures */
/* do not collect and update hash for digital signatures */
...
...
security/integrity/ima/ima_main.c
浏览文件 @
f334bcd9
...
@@ -228,7 +228,7 @@ static int process_measurement(struct file *file, char *buf, loff_t size,
...
@@ -228,7 +228,7 @@ static int process_measurement(struct file *file, char *buf, loff_t size,
if
((
action
&
IMA_APPRAISE_SUBMASK
)
||
if
((
action
&
IMA_APPRAISE_SUBMASK
)
||
strcmp
(
template_desc
->
name
,
IMA_TEMPLATE_IMA_NAME
)
!=
0
)
strcmp
(
template_desc
->
name
,
IMA_TEMPLATE_IMA_NAME
)
!=
0
)
/* read 'security.ima' */
/* read 'security.ima' */
xattr_len
=
ima_read_xattr
(
file
->
f_path
.
dentry
,
&
xattr_value
);
xattr_len
=
ima_read_xattr
(
file
_dentry
(
file
)
,
&
xattr_value
);
hash_algo
=
ima_get_hash_algo
(
xattr_value
,
xattr_len
);
hash_algo
=
ima_get_hash_algo
(
xattr_value
,
xattr_len
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录