* Re: panic in do_last()
2014-04-18 2:17 ` Al Viro
@ 2014-04-18 2:22 ` Lin Ming
2014-04-18 2:35 ` Lin Ming
1 sibling, 0 replies; 12+ messages in thread
From: Lin Ming @ 2014-04-18 2:22 UTC (permalink / raw)
To: Al Viro; +Cc: David Howells, linux-fsdevel, Hugh Dickins
[-- Attachment #1: Type: text/plain, Size: 242 bytes --]
On Thu, Apr 17, 2014 at 7:17 PM, Al Viro <viro@zeniv.linux.org.uk> wrote:
> I'd still like the disassembly of your do_last() and the missing hex dump...
disassmebly of do_last() attached.
the missing hex dump should be in previous panic.log
[-- Attachment #2: do_last.S --]
[-- Type: application/octet-stream, Size: 73085 bytes --]
vmlinux: file format elf64-x86-64
Disassembly of section .text:
ffffffff81108dd3 <do_last.isra.44>:
}
/*
* Handle the last step of open()
*/
static int do_last(struct nameidata *nd, struct path *path,
ffffffff81108dd3: e8 68 a7 27 00 callq ffffffff81383540 <__fentry__>
ffffffff81108dd8: 55 push %rbp
ffffffff81108dd9: 48 89 e5 mov %rsp,%rbp
ffffffff81108ddc: 41 57 push %r15
ffffffff81108dde: 41 56 push %r14
ffffffff81108de0: 41 55 push %r13
ffffffff81108de2: 49 89 d5 mov %rdx,%r13
ffffffff81108de5: 41 54 push %r12
ffffffff81108de7: 49 89 f4 mov %rsi,%r12
ffffffff81108dea: 53 push %rbx
ffffffff81108deb: 48 89 fb mov %rdi,%rbx
ffffffff81108dee: 48 83 ec 78 sub $0x78,%rsp
struct file *file, const struct open_flags *op,
int *opened, struct filename *name)
{
struct dentry *dir = nd->path.dentry;
int open_flag = op->open_flag;
ffffffff81108df2: 8b 11 mov (%rcx),%edx
*/
static int do_last(struct nameidata *nd, struct path *path,
struct file *file, const struct open_flags *op,
int *opened, struct filename *name)
{
struct dentry *dir = nd->path.dentry;
ffffffff81108df4: 48 8b 47 08 mov 0x8(%rdi),%rax
}
/*
* Handle the last step of open()
*/
static int do_last(struct nameidata *nd, struct path *path,
ffffffff81108df8: 48 89 4d 98 mov %rcx,-0x68(%rbp)
ffffffff81108dfc: 4c 89 45 a0 mov %r8,-0x60(%rbp)
bool will_truncate = (open_flag & O_TRUNC) != 0;
bool got_write = false;
int acc_mode = op->acc_mode;
struct inode *inode;
bool symlink_ok = false;
struct path save_parent = { .dentry = NULL, .mnt = NULL };
ffffffff81108e00: 48 c7 45 c0 00 00 00 movq $0x0,-0x40(%rbp)
ffffffff81108e07: 00
ffffffff81108e08: 48 c7 45 c8 00 00 00 movq $0x0,-0x38(%rbp)
ffffffff81108e0f: 00
*/
static int do_last(struct nameidata *nd, struct path *path,
struct file *file, const struct open_flags *op,
int *opened, struct filename *name)
{
struct dentry *dir = nd->path.dentry;
ffffffff81108e10: 48 89 45 80 mov %rax,-0x80(%rbp)
int open_flag = op->open_flag;
bool will_truncate = (open_flag & O_TRUNC) != 0;
ffffffff81108e14: 89 d0 mov %edx,%eax
static int do_last(struct nameidata *nd, struct path *path,
struct file *file, const struct open_flags *op,
int *opened, struct filename *name)
{
struct dentry *dir = nd->path.dentry;
int open_flag = op->open_flag;
ffffffff81108e16: 89 55 94 mov %edx,-0x6c(%rbp)
bool will_truncate = (open_flag & O_TRUNC) != 0;
ffffffff81108e19: c1 e8 09 shr $0x9,%eax
int error;
nd->flags &= ~LOOKUP_PARENT;
nd->flags |= op->intent;
if (nd->last_type != LAST_NORM) {
ffffffff81108e1c: 8b 57 44 mov 0x44(%rdi),%edx
struct file *file, const struct open_flags *op,
int *opened, struct filename *name)
{
struct dentry *dir = nd->path.dentry;
int open_flag = op->open_flag;
bool will_truncate = (open_flag & O_TRUNC) != 0;
ffffffff81108e1f: 83 e0 01 and $0x1,%eax
ffffffff81108e22: 88 45 aa mov %al,-0x56(%rbp)
bool got_write = false;
int acc_mode = op->acc_mode;
ffffffff81108e25: 8b 41 08 mov 0x8(%rcx),%eax
ffffffff81108e28: 89 85 7c ff ff ff mov %eax,-0x84(%rbp)
bool symlink_ok = false;
struct path save_parent = { .dentry = NULL, .mnt = NULL };
bool retried = false;
int error;
nd->flags &= ~LOOKUP_PARENT;
ffffffff81108e2e: 8b 47 38 mov 0x38(%rdi),%eax
ffffffff81108e31: 83 e0 ef and $0xffffffef,%eax
ffffffff81108e34: 89 47 38 mov %eax,0x38(%rdi)
nd->flags |= op->intent;
ffffffff81108e37: 0b 41 0c or 0xc(%rcx),%eax
if (nd->last_type != LAST_NORM) {
ffffffff81108e3a: 85 d2 test %edx,%edx
struct path save_parent = { .dentry = NULL, .mnt = NULL };
bool retried = false;
int error;
nd->flags &= ~LOOKUP_PARENT;
nd->flags |= op->intent;
ffffffff81108e3c: 89 47 38 mov %eax,0x38(%rdi)
if (nd->last_type != LAST_NORM) {
ffffffff81108e3f: 74 29 je ffffffff81108e6a <do_last.isra.44+0x97>
return inode_permission(nd->inode, MAY_EXEC);
}
static inline int handle_dots(struct nameidata *nd, int type)
{
if (type == LAST_DOTDOT) {
ffffffff81108e41: 83 fa 03 cmp $0x3,%edx
ffffffff81108e44: 0f 85 0c 09 00 00 jne ffffffff81109756 <do_last.isra.44+0x983>
if (nd->flags & LOOKUP_RCU) {
ffffffff81108e4a: a8 40 test $0x40,%al
ffffffff81108e4c: 74 12 je ffffffff81108e60 <do_last.isra.44+0x8d>
if (follow_dotdot_rcu(nd))
ffffffff81108e4e: e8 d8 c0 ff ff callq ffffffff81104f2b <follow_dotdot_rcu>
ffffffff81108e53: 85 c0 test %eax,%eax
ffffffff81108e55: 0f 85 f3 08 00 00 jne ffffffff8110974e <do_last.isra.44+0x97b>
ffffffff81108e5b: e9 f6 08 00 00 jmpq ffffffff81109756 <do_last.isra.44+0x983>
return -ECHILD;
} else
follow_dotdot(nd);
ffffffff81108e60: e8 16 c5 ff ff callq ffffffff8110537b <follow_dotdot>
ffffffff81108e65: e9 ec 08 00 00 jmpq ffffffff81109756 <do_last.isra.44+0x983>
if (error)
return error;
goto finish_open;
}
if (!(open_flag & O_CREAT)) {
ffffffff81108e6a: f6 45 94 40 testb $0x40,-0x6c(%rbp)
ffffffff81108e6e: 75 64 jne ffffffff81108ed4 <do_last.isra.44+0x101>
if (nd->last.name[nd->last.len])
ffffffff81108e70: 8b 57 14 mov 0x14(%rdi),%edx
ffffffff81108e73: 48 8b 4f 18 mov 0x18(%rdi),%rcx
ffffffff81108e77: 80 3c 11 00 cmpb $0x0,(%rcx,%rdx,1)
ffffffff81108e7b: 74 06 je ffffffff81108e83 <do_last.isra.44+0xb0>
nd->flags |= LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
ffffffff81108e7d: 83 c8 03 or $0x3,%eax
ffffffff81108e80: 89 47 38 mov %eax,0x38(%rdi)
if (open_flag & O_PATH && !(nd->flags & LOOKUP_FOLLOW))
ffffffff81108e83: f7 45 94 00 00 20 00 testl $0x200000,-0x6c(%rbp)
int open_flag = op->open_flag;
bool will_truncate = (open_flag & O_TRUNC) != 0;
bool got_write = false;
int acc_mode = op->acc_mode;
struct inode *inode;
bool symlink_ok = false;
ffffffff81108e8a: c6 45 93 00 movb $0x0,-0x6d(%rbp)
}
if (!(open_flag & O_CREAT)) {
if (nd->last.name[nd->last.len])
nd->flags |= LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
if (open_flag & O_PATH && !(nd->flags & LOOKUP_FOLLOW))
ffffffff81108e8e: 74 0f je ffffffff81108e9f <do_last.isra.44+0xcc>
ffffffff81108e90: 8b 43 38 mov 0x38(%rbx),%eax
ffffffff81108e93: 83 e0 01 and $0x1,%eax
ffffffff81108e96: 83 f0 01 xor $0x1,%eax
ffffffff81108e99: 83 e0 01 and $0x1,%eax
ffffffff81108e9c: 88 45 93 mov %al,-0x6d(%rbp)
symlink_ok = true;
/* we _can_ be in RCU mode here */
error = lookup_fast(nd, path, &inode);
ffffffff81108e9f: 48 8d 55 b8 lea -0x48(%rbp),%rdx
ffffffff81108ea3: 4c 89 e6 mov %r12,%rsi
ffffffff81108ea6: 48 89 df mov %rbx,%rdi
ffffffff81108ea9: e8 eb cc ff ff callq ffffffff81105b99 <lookup_fast>
if (likely(!error))
ffffffff81108eae: 83 f8 00 cmp $0x0,%eax
if (nd->last.name[nd->last.len])
nd->flags |= LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
if (open_flag & O_PATH && !(nd->flags & LOOKUP_FOLLOW))
symlink_ok = true;
/* we _can_ be in RCU mode here */
error = lookup_fast(nd, path, &inode);
ffffffff81108eb1: 41 89 c6 mov %eax,%r14d
bool got_write = false;
int acc_mode = op->acc_mode;
struct inode *inode;
bool symlink_ok = false;
struct path save_parent = { .dentry = NULL, .mnt = NULL };
bool retried = false;
ffffffff81108eb4: c6 45 92 00 movb $0x0,-0x6e(%rbp)
nd->flags |= LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
if (open_flag & O_PATH && !(nd->flags & LOOKUP_FOLLOW))
symlink_ok = true;
/* we _can_ be in RCU mode here */
error = lookup_fast(nd, path, &inode);
if (likely(!error))
ffffffff81108eb8: 0f 84 9d 05 00 00 je ffffffff8110945b <do_last.isra.44+0x688>
goto finish_lookup;
if (error < 0)
ffffffff81108ebe: 0f 8c f5 07 00 00 jl ffffffff811096b9 <do_last.isra.44+0x8e6>
goto out;
BUG_ON(nd->inode != dir->d_inode);
ffffffff81108ec4: 48 8b 45 80 mov -0x80(%rbp),%rax
ffffffff81108ec8: 48 8b 40 30 mov 0x30(%rax),%rax
ffffffff81108ecc: 48 39 43 30 cmp %rax,0x30(%rbx)
ffffffff81108ed0: 74 32 je ffffffff81108f04 <do_last.isra.44+0x131>
ffffffff81108ed2: 0f 0b ud2
/*
* This will *only* deal with leaving RCU mode - LOOKUP_JUMPED
* has been cleared when we got to the last component we are
* about to look up
*/
error = complete_walk(nd);
ffffffff81108ed4: e8 d8 c1 ff ff callq ffffffff811050b1 <complete_walk>
if (error)
ffffffff81108ed9: 85 c0 test %eax,%eax
/*
* This will *only* deal with leaving RCU mode - LOOKUP_JUMPED
* has been cleared when we got to the last component we are
* about to look up
*/
error = complete_walk(nd);
ffffffff81108edb: 41 89 c6 mov %eax,%r14d
if (error)
ffffffff81108ede: 0f 85 c7 08 00 00 jne ffffffff811097ab <do_last.isra.44+0x9d8>
return error;
audit_inode(name, dir, LOOKUP_PARENT);
error = -EISDIR;
/* trailing slashes? */
if (nd->last.name[nd->last.len])
ffffffff81108ee4: 8b 43 14 mov 0x14(%rbx),%eax
ffffffff81108ee7: 48 8b 53 18 mov 0x18(%rbx),%rdx
ffffffff81108eeb: 80 3c 02 00 cmpb $0x0,(%rdx,%rax,1)
ffffffff81108eef: 74 0b je ffffffff81108efc <do_last.isra.44+0x129>
error = complete_walk(nd);
if (error)
return error;
audit_inode(name, dir, LOOKUP_PARENT);
error = -EISDIR;
ffffffff81108ef1: 41 be eb ff ff ff mov $0xffffffeb,%r14d
ffffffff81108ef7: e9 bd 07 00 00 jmpq ffffffff811096b9 <do_last.isra.44+0x8e6>
bool got_write = false;
int acc_mode = op->acc_mode;
struct inode *inode;
bool symlink_ok = false;
struct path save_parent = { .dentry = NULL, .mnt = NULL };
bool retried = false;
ffffffff81108efc: c6 45 92 00 movb $0x0,-0x6e(%rbp)
int open_flag = op->open_flag;
bool will_truncate = (open_flag & O_TRUNC) != 0;
bool got_write = false;
int acc_mode = op->acc_mode;
struct inode *inode;
bool symlink_ok = false;
ffffffff81108f00: c6 45 93 00 movb $0x0,-0x6d(%rbp)
if (nd->last.name[nd->last.len])
goto out;
}
retry_lookup:
if (op->open_flag & (O_CREAT | O_TRUNC | O_WRONLY | O_RDWR)) {
ffffffff81108f04: 48 8b 55 98 mov -0x68(%rbp),%rdx
ffffffff81108f08: c6 45 ab 00 movb $0x0,-0x55(%rbp)
ffffffff81108f0c: f7 02 43 02 00 00 testl $0x243,(%rdx)
ffffffff81108f12: 74 0e je ffffffff81108f22 <do_last.isra.44+0x14f>
error = mnt_want_write(nd->path.mnt);
ffffffff81108f14: 48 8b 3b mov (%rbx),%rdi
ffffffff81108f17: e8 2c d2 00 00 callq ffffffff81116148 <mnt_want_write>
if (!error)
ffffffff81108f1c: 85 c0 test %eax,%eax
ffffffff81108f1e: 0f 94 45 ab sete -0x55(%rbp)
* do _not_ fail yet - we might not need that or fail with
* a different error; let lookup_open() decide; we'll be
* dropping this one anyway.
*/
}
mutex_lock(&dir->d_inode->i_mutex);
ffffffff81108f22: 48 8b 45 80 mov -0x80(%rbp),%rax
ffffffff81108f26: 48 8b 40 30 mov 0x30(%rax),%rax
ffffffff81108f2a: 48 89 c7 mov %rax,%rdi
ffffffff81108f2d: 48 81 c7 a0 00 00 00 add $0xa0,%rdi
ffffffff81108f34: e8 7e 8b 27 00 callq ffffffff81381ab7 <mutex_lock>
static int lookup_open(struct nameidata *nd, struct path *path,
struct file *file,
const struct open_flags *op,
bool got_write, int *opened)
{
struct dentry *dir = nd->path.dentry;
ffffffff81108f39: 4c 8b 73 08 mov 0x8(%rbx),%r14
struct inode *dir_inode = dir->d_inode;
struct dentry *dentry;
int error;
bool need_lookup;
*opened &= ~FILE_CREATED;
ffffffff81108f3d: 48 8b 55 a0 mov -0x60(%rbp),%rdx
dentry = lookup_dcache(&nd->last, dir, nd->flags, &need_lookup);
ffffffff81108f41: 48 8d 7b 10 lea 0x10(%rbx),%rdi
ffffffff81108f45: 48 8d 4d b7 lea -0x49(%rbp),%rcx
struct file *file,
const struct open_flags *op,
bool got_write, int *opened)
{
struct dentry *dir = nd->path.dentry;
struct inode *dir_inode = dir->d_inode;
ffffffff81108f49: 4d 8b 46 30 mov 0x30(%r14),%r8
struct dentry *dentry;
int error;
bool need_lookup;
*opened &= ~FILE_CREATED;
ffffffff81108f4d: 83 22 fe andl $0xfffffffe,(%rdx)
dentry = lookup_dcache(&nd->last, dir, nd->flags, &need_lookup);
ffffffff81108f50: 4c 89 f6 mov %r14,%rsi
ffffffff81108f53: 8b 53 38 mov 0x38(%rbx),%edx
ffffffff81108f56: 4c 89 85 60 ff ff ff mov %r8,-0xa0(%rbp)
ffffffff81108f5d: e8 50 c8 ff ff callq ffffffff811057b2 <lookup_dcache>
if (IS_ERR(dentry))
ffffffff81108f62: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax
struct dentry *dentry;
int error;
bool need_lookup;
*opened &= ~FILE_CREATED;
dentry = lookup_dcache(&nd->last, dir, nd->flags, &need_lookup);
ffffffff81108f68: 49 89 c7 mov %rax,%r15
if (IS_ERR(dentry))
ffffffff81108f6b: 4c 8b 85 60 ff ff ff mov -0xa0(%rbp),%r8
ffffffff81108f72: 76 05 jbe ffffffff81108f79 <do_last.isra.44+0x1a6>
ffffffff81108f74: e9 61 03 00 00 jmpq ffffffff811092da <do_last.isra.44+0x507>
return PTR_ERR(dentry);
/* Cached positive dentry: will open in f_op->open */
if (!need_lookup && dentry->d_inode)
ffffffff81108f79: 8a 45 b7 mov -0x49(%rbp),%al
ffffffff81108f7c: 84 c0 test %al,%al
ffffffff81108f7e: 88 45 a9 mov %al,-0x57(%rbp)
ffffffff81108f81: 75 0b jne ffffffff81108f8e <do_last.isra.44+0x1bb>
ffffffff81108f83: 49 83 7f 30 00 cmpq $0x0,0x30(%r15)
ffffffff81108f88: 0f 85 b7 03 00 00 jne ffffffff81109345 <do_last.isra.44+0x572>
goto out_no_open;
if ((nd->flags & LOOKUP_OPEN) && dir_inode->i_op->atomic_open) {
ffffffff81108f8e: 8b 53 38 mov 0x38(%rbx),%edx
ffffffff81108f91: f6 c6 01 test $0x1,%dh
ffffffff81108f94: 0f 84 1b 03 00 00 je ffffffff811092b5 <do_last.isra.44+0x4e2>
ffffffff81108f9a: 49 8b 40 20 mov 0x20(%r8),%rax
ffffffff81108f9e: 48 83 b8 b8 00 00 00 cmpq $0x0,0xb8(%rax)
ffffffff81108fa5: 00
ffffffff81108fa6: 0f 84 09 03 00 00 je ffffffff811092b5 <do_last.isra.44+0x4e2>
struct path *path, struct file *file,
const struct open_flags *op,
bool got_write, bool need_lookup,
int *opened)
{
struct inode *dir = nd->path.dentry->d_inode;
ffffffff81108fac: 48 8b 43 08 mov 0x8(%rbx),%rax
unsigned open_flag = open_to_namei_flags(op->open_flag);
ffffffff81108fb0: 48 8b 55 98 mov -0x68(%rbp),%rdx
struct path *path, struct file *file,
const struct open_flags *op,
bool got_write, bool need_lookup,
int *opened)
{
struct inode *dir = nd->path.dentry->d_inode;
ffffffff81108fb4: 48 8b 40 30 mov 0x30(%rax),%rax
unsigned open_flag = open_to_namei_flags(op->open_flag);
ffffffff81108fb8: 44 8b 32 mov (%rdx),%r14d
struct path *path, struct file *file,
const struct open_flags *op,
bool got_write, bool need_lookup,
int *opened)
{
struct inode *dir = nd->path.dentry->d_inode;
ffffffff81108fbb: 48 89 45 88 mov %rax,-0x78(%rbp)
return error;
}
static inline int open_to_namei_flags(int flag)
{
if ((flag & O_ACCMODE) == 3)
ffffffff81108fbf: 44 89 f0 mov %r14d,%eax
ffffffff81108fc2: 83 e0 03 and $0x3,%eax
flag--;
ffffffff81108fc5: 83 f8 03 cmp $0x3,%eax
ffffffff81108fc8: 0f 94 c0 sete %al
ffffffff81108fcb: 0f b6 c0 movzbl %al,%eax
ffffffff81108fce: 41 29 c6 sub %eax,%r14d
int acc_mode;
int create_error = 0;
struct dentry *const DENTRY_NOT_SET = (void *) -1UL;
bool excl;
BUG_ON(dentry->d_inode);
ffffffff81108fd1: 49 83 7f 30 00 cmpq $0x0,0x30(%r15)
ffffffff81108fd6: 74 02 je ffffffff81108fda <do_last.isra.44+0x207>
ffffffff81108fd8: 0f 0b ud2
/* Don't create child dentry for a dead directory. */
if (unlikely(IS_DEADDIR(dir))) {
ffffffff81108fda: 48 8b 45 88 mov -0x78(%rbp),%rax
ffffffff81108fde: f6 40 0c 10 testb $0x10,0xc(%rax)
ffffffff81108fe2: 0f 85 3d 02 00 00 jne ffffffff81109225 <do_last.isra.44+0x452>
error = -ENOENT;
goto out;
}
mode = op->mode;
ffffffff81108fe8: 48 8b 55 98 mov -0x68(%rbp),%rdx
if ((open_flag & O_CREAT) && !IS_POSIXACL(dir))
ffffffff81108fec: 41 f6 c6 40 test $0x40,%r14b
if (unlikely(IS_DEADDIR(dir))) {
error = -ENOENT;
goto out;
}
mode = op->mode;
ffffffff81108ff0: 8b 52 04 mov 0x4(%rdx),%edx
ffffffff81108ff3: 66 89 55 90 mov %dx,-0x70(%rbp)
if ((open_flag & O_CREAT) && !IS_POSIXACL(dir))
ffffffff81108ff7: 74 15 je ffffffff8110900e <do_last.isra.44+0x23b>
ffffffff81108ff9: 48 8b 40 28 mov 0x28(%rax),%rax
ffffffff81108ffd: f6 40 52 01 testb $0x1,0x52(%rax)
ffffffff81109001: 75 0b jne ffffffff8110900e <do_last.isra.44+0x23b>
mode &= ~current_umask();
ffffffff81109003: e8 c0 a5 01 00 callq ffffffff811235c8 <current_umask>
ffffffff81109008: f7 d0 not %eax
ffffffff8110900a: 66 21 45 90 and %ax,-0x70(%rbp)
excl = (open_flag & (O_EXCL | O_CREAT)) == (O_EXCL | O_CREAT);
ffffffff8110900e: 44 89 f0 mov %r14d,%eax
ffffffff81109011: 25 c0 00 00 00 and $0xc0,%eax
ffffffff81109016: 3d c0 00 00 00 cmp $0xc0,%eax
if (excl)
open_flag &= ~O_TRUNC;
ffffffff8110901b: 44 89 f0 mov %r14d,%eax
mode = op->mode;
if ((open_flag & O_CREAT) && !IS_POSIXACL(dir))
mode &= ~current_umask();
excl = (open_flag & (O_EXCL | O_CREAT)) == (O_EXCL | O_CREAT);
ffffffff8110901e: 0f 94 45 a8 sete -0x58(%rbp)
if (excl)
open_flag &= ~O_TRUNC;
ffffffff81109022: 80 e4 fd and $0xfd,%ah
ffffffff81109025: 80 7d a8 00 cmpb $0x0,-0x58(%rbp)
ffffffff81109029: 44 0f 45 f0 cmovne %eax,%r14d
ffffffff8110902d: 44 89 75 ac mov %r14d,-0x54(%rbp)
* to check access and if not granted clear O_CREAT from the flags.
*
* Another problem is returing the "right" error value (e.g. for an
* O_EXCL open we want to return EEXIST not EROFS).
*/
if (((open_flag & (O_CREAT | O_TRUNC)) ||
ffffffff81109031: 41 81 e6 43 02 00 00 and $0x243,%r14d
struct inode *dir = nd->path.dentry->d_inode;
unsigned open_flag = open_to_namei_flags(op->open_flag);
umode_t mode;
int error;
int acc_mode;
int create_error = 0;
ffffffff81109038: 41 be 00 00 00 00 mov $0x0,%r14d
* to check access and if not granted clear O_CREAT from the flags.
*
* Another problem is returing the "right" error value (e.g. for an
* O_EXCL open we want to return EEXIST not EROFS).
*/
if (((open_flag & (O_CREAT | O_TRUNC)) ||
ffffffff8110903e: 74 27 je ffffffff81109067 <do_last.isra.44+0x294>
(open_flag & O_ACCMODE) != O_RDONLY) && unlikely(!got_write)) {
ffffffff81109040: 80 7d ab 00 cmpb $0x0,-0x55(%rbp)
ffffffff81109044: 75 21 jne ffffffff81109067 <do_last.isra.44+0x294>
if (!(open_flag & O_CREAT)) {
ffffffff81109046: f6 45 ac 40 testb $0x40,-0x54(%rbp)
ffffffff8110904a: 0f 84 f9 01 00 00 je ffffffff81109249 <do_last.isra.44+0x476>
/*
* No O_CREATE -> atomicity not a requirement -> fall
* back to lookup + open
*/
goto no_open;
} else if (open_flag & (O_EXCL | O_TRUNC)) {
ffffffff81109050: f7 45 ac 80 02 00 00 testl $0x280,-0x54(%rbp)
ffffffff81109057: 0f 85 e6 01 00 00 jne ffffffff81109243 <do_last.isra.44+0x470>
create_error = -EROFS;
goto no_open;
} else {
/* No side effects, safe to clear O_CREAT */
create_error = -EROFS;
open_flag &= ~O_CREAT;
ffffffff8110905d: 83 65 ac bf andl $0xffffffbf,-0x54(%rbp)
/* Fall back and fail with the right error */
create_error = -EROFS;
goto no_open;
} else {
/* No side effects, safe to clear O_CREAT */
create_error = -EROFS;
ffffffff81109061: 41 be e2 ff ff ff mov $0xffffffe2,%r14d
open_flag &= ~O_CREAT;
}
}
if (open_flag & O_CREAT) {
ffffffff81109067: f6 45 ac 40 testb $0x40,-0x54(%rbp)
ffffffff8110906b: 74 3f je ffffffff811090ac <do_last.isra.44+0x2d9>
{
int error = security_path_mknod(dir, dentry, mode, 0);
if (error)
return error;
error = inode_permission(dir->dentry->d_inode, MAY_WRITE | MAY_EXEC);
ffffffff8110906d: 48 8b 43 08 mov 0x8(%rbx),%rax
ffffffff81109071: be 03 00 00 00 mov $0x3,%esi
ffffffff81109076: 48 8b 78 30 mov 0x30(%rax),%rdi
ffffffff8110907a: e8 7c d2 ff ff callq ffffffff811062fb <inode_permission>
if (error)
ffffffff8110907f: 85 c0 test %eax,%eax
ffffffff81109081: 75 18 jne ffffffff8110909b <do_last.isra.44+0x2c8>
return error;
return security_inode_create(dir->dentry->d_inode, dentry, mode);
ffffffff81109083: 48 8b 43 08 mov 0x8(%rbx),%rax
ffffffff81109087: 0f b7 55 90 movzwl -0x70(%rbp),%edx
ffffffff8110908b: 4c 89 fe mov %r15,%rsi
ffffffff8110908e: 48 8b 78 30 mov 0x30(%rax),%rdi
ffffffff81109092: e8 3c d0 0d 00 callq ffffffff811e60d3 <security_inode_create>
}
}
if (open_flag & O_CREAT) {
error = may_o_create(&nd->path, dentry, mode);
if (error) {
ffffffff81109097: 85 c0 test %eax,%eax
ffffffff81109099: 74 11 je ffffffff811090ac <do_last.isra.44+0x2d9>
create_error = error;
if (open_flag & O_EXCL)
ffffffff8110909b: f6 45 ac 80 testb $0x80,-0x54(%rbp)
int error = security_path_mknod(dir, dentry, mode, 0);
if (error)
return error;
error = inode_permission(dir->dentry->d_inode, MAY_WRITE | MAY_EXEC);
if (error)
ffffffff8110909f: 41 89 c6 mov %eax,%r14d
if (open_flag & O_CREAT) {
error = may_o_create(&nd->path, dentry, mode);
if (error) {
create_error = error;
if (open_flag & O_EXCL)
ffffffff811090a2: 0f 85 a1 01 00 00 jne ffffffff81109249 <do_last.isra.44+0x476>
goto no_open;
open_flag &= ~O_CREAT;
ffffffff811090a8: 83 65 ac bf andl $0xffffffbf,-0x54(%rbp)
}
}
if (nd->flags & LOOKUP_DIRECTORY)
open_flag |= O_DIRECTORY;
ffffffff811090ac: 8b 45 ac mov -0x54(%rbp),%eax
file->f_path.dentry = DENTRY_NOT_SET;
file->f_path.mnt = nd->path.mnt;
error = dir->i_op->atomic_open(dir, dentry, file, open_flag, mode,
ffffffff811090af: 48 8b 55 88 mov -0x78(%rbp),%rdx
ffffffff811090b3: 4c 89 fe mov %r15,%rsi
ffffffff811090b6: 44 0f b7 45 90 movzwl -0x70(%rbp),%r8d
ffffffff811090bb: 4c 8b 4d a0 mov -0x60(%rbp),%r9
ffffffff811090bf: 48 8b 7d 88 mov -0x78(%rbp),%rdi
open_flag &= ~O_CREAT;
}
}
if (nd->flags & LOOKUP_DIRECTORY)
open_flag |= O_DIRECTORY;
ffffffff811090c3: 0d 00 00 01 00 or $0x10000,%eax
ffffffff811090c8: f6 43 38 02 testb $0x2,0x38(%rbx)
file->f_path.dentry = DENTRY_NOT_SET;
ffffffff811090cc: 49 c7 45 18 ff ff ff movq $0xffffffffffffffff,0x18(%r13)
ffffffff811090d3: ff
open_flag &= ~O_CREAT;
}
}
if (nd->flags & LOOKUP_DIRECTORY)
open_flag |= O_DIRECTORY;
ffffffff811090d4: 0f 44 45 ac cmove -0x54(%rbp),%eax
ffffffff811090d8: 89 45 ac mov %eax,-0x54(%rbp)
file->f_path.dentry = DENTRY_NOT_SET;
file->f_path.mnt = nd->path.mnt;
ffffffff811090db: 48 8b 03 mov (%rbx),%rax
error = dir->i_op->atomic_open(dir, dentry, file, open_flag, mode,
ffffffff811090de: 8b 4d ac mov -0x54(%rbp),%ecx
if (nd->flags & LOOKUP_DIRECTORY)
open_flag |= O_DIRECTORY;
file->f_path.dentry = DENTRY_NOT_SET;
file->f_path.mnt = nd->path.mnt;
ffffffff811090e1: 49 89 45 10 mov %rax,0x10(%r13)
error = dir->i_op->atomic_open(dir, dentry, file, open_flag, mode,
ffffffff811090e5: 48 8b 42 20 mov 0x20(%rdx),%rax
ffffffff811090e9: 4c 89 ea mov %r13,%rdx
ffffffff811090ec: ff 90 b8 00 00 00 callq *0xb8(%rax)
opened);
if (error < 0) {
ffffffff811090f2: 83 f8 00 cmp $0x0,%eax
ffffffff811090f5: 7d 17 jge ffffffff8110910e <do_last.isra.44+0x33b>
if (create_error && error == -ENOENT)
ffffffff811090f7: 83 f8 fe cmp $0xfffffffe,%eax
ffffffff811090fa: 0f 85 30 01 00 00 jne ffffffff81109230 <do_last.isra.44+0x45d>
ffffffff81109100: 45 85 f6 test %r14d,%r14d
ffffffff81109103: 0f 85 56 02 00 00 jne ffffffff8110935f <do_last.isra.44+0x58c>
ffffffff81109109: e9 22 01 00 00 jmpq ffffffff81109230 <do_last.isra.44+0x45d>
error = create_error;
goto out;
}
if (error) { /* returned 1, that is */
ffffffff8110910e: 0f 84 a3 00 00 00 je ffffffff811091b7 <do_last.isra.44+0x3e4>
if (WARN_ON(file->f_path.dentry == DENTRY_NOT_SET)) {
ffffffff81109114: 49 8b 45 18 mov 0x18(%r13),%rax
ffffffff81109118: 48 83 f8 ff cmp $0xffffffffffffffff,%rax
ffffffff8110911c: 0f 85 41 06 00 00 jne ffffffff81109763 <do_last.isra.44+0x990>
ffffffff81109122: be 98 0a 00 00 mov $0xa98,%esi
ffffffff81109127: 48 c7 c7 91 a0 4e 81 mov $0xffffffff814ea091,%rdi
error = -EIO;
ffffffff8110912e: 41 be fb ff ff ff mov $0xfffffffb,%r14d
error = create_error;
goto out;
}
if (error) { /* returned 1, that is */
if (WARN_ON(file->f_path.dentry == DENTRY_NOT_SET)) {
ffffffff81109134: e8 9a 05 f3 ff callq ffffffff810396d3 <warn_slowpath_null>
ffffffff81109139: e9 21 02 00 00 jmpq ffffffff8110935f <do_last.isra.44+0x58c>
error = -EIO;
goto out;
}
if (file->f_path.dentry) {
dput(dentry);
ffffffff8110913e: 4c 89 ff mov %r15,%rdi
ffffffff81109141: e8 83 65 00 00 callq ffffffff8110f6c9 <dput>
dentry = file->f_path.dentry;
ffffffff81109146: 4d 8b 7d 18 mov 0x18(%r13),%r15
}
if (*opened & FILE_CREATED)
ffffffff8110914a: 48 8b 45 a0 mov -0x60(%rbp),%rax
ffffffff8110914e: f6 00 01 testb $0x1,(%rax)
ffffffff81109151: 74 1e je ffffffff81109171 <do_last.isra.44+0x39e>
*/
static inline void fsnotify_create(struct inode *inode, struct dentry *dentry)
{
audit_inode_child(inode, dentry, AUDIT_TYPE_CHILD_CREATE);
fsnotify(inode, FS_CREATE, dentry->d_inode, FSNOTIFY_EVENT_INODE, dentry->d_name.name, 0);
ffffffff81109153: 49 8b 57 30 mov 0x30(%r15),%rdx
ffffffff81109157: 4d 8b 47 28 mov 0x28(%r15),%r8
ffffffff8110915b: 45 31 c9 xor %r9d,%r9d
ffffffff8110915e: 48 8b 7d 88 mov -0x78(%rbp),%rdi
ffffffff81109162: b9 02 00 00 00 mov $0x2,%ecx
ffffffff81109167: be 00 01 00 00 mov $0x100,%esi
ffffffff8110916c: e8 d4 73 02 00 callq ffffffff81130545 <fsnotify>
fsnotify_create(dir, dentry);
if (!dentry->d_inode) {
ffffffff81109171: 49 83 7f 30 00 cmpq $0x0,0x30(%r15)
ffffffff81109176: 75 23 jne ffffffff8110919b <do_last.isra.44+0x3c8>
WARN_ON(*opened & FILE_CREATED);
ffffffff81109178: 48 8b 55 a0 mov -0x60(%rbp),%rdx
ffffffff8110917c: f6 02 01 testb $0x1,(%rdx)
ffffffff8110917f: 0f 84 bb 01 00 00 je ffffffff81109340 <do_last.isra.44+0x56d>
ffffffff81109185: be a3 0a 00 00 mov $0xaa3,%esi
ffffffff8110918a: 48 c7 c7 91 a0 4e 81 mov $0xffffffff814ea091,%rdi
ffffffff81109191: e8 3d 05 f3 ff callq ffffffff810396d3 <warn_slowpath_null>
ffffffff81109196: e9 a5 01 00 00 jmpq ffffffff81109340 <do_last.isra.44+0x56d>
if (create_error) {
error = create_error;
goto out;
}
} else {
if (excl && !(*opened & FILE_CREATED)) {
ffffffff8110919b: 80 7d a8 00 cmpb $0x0,-0x58(%rbp)
ffffffff8110919f: 0f 84 a0 01 00 00 je ffffffff81109345 <do_last.isra.44+0x572>
ffffffff811091a5: 48 8b 45 a0 mov -0x60(%rbp),%rax
ffffffff811091a9: f6 00 01 testb $0x1,(%rax)
ffffffff811091ac: 0f 85 93 01 00 00 jne ffffffff81109345 <do_last.isra.44+0x572>
ffffffff811091b2: e9 81 00 00 00 jmpq ffffffff81109238 <do_last.isra.44+0x465>
/*
* We didn't have the inode before the open, so check open permission
* here.
*/
acc_mode = op->acc_mode;
if (*opened & FILE_CREATED) {
ffffffff811091b7: 48 8b 45 a0 mov -0x60(%rbp),%rax
/*
* We didn't have the inode before the open, so check open permission
* here.
*/
acc_mode = op->acc_mode;
ffffffff811091bb: 48 8b 55 98 mov -0x68(%rbp),%rdx
if (*opened & FILE_CREATED) {
ffffffff811091bf: f6 00 01 testb $0x1,(%rax)
/*
* We didn't have the inode before the open, so check open permission
* here.
*/
acc_mode = op->acc_mode;
ffffffff811091c2: 8b 72 08 mov 0x8(%rdx),%esi
if (*opened & FILE_CREATED) {
ffffffff811091c5: 74 3a je ffffffff81109201 <do_last.isra.44+0x42e>
WARN_ON(!(open_flag & O_CREAT));
ffffffff811091c7: f6 45 ac 40 testb $0x40,-0x54(%rbp)
ffffffff811091cb: 75 11 jne ffffffff811091de <do_last.isra.44+0x40b>
ffffffff811091cd: be b7 0a 00 00 mov $0xab7,%esi
ffffffff811091d2: 48 c7 c7 91 a0 4e 81 mov $0xffffffff814ea091,%rdi
ffffffff811091d9: e8 f5 04 f3 ff callq ffffffff810396d3 <warn_slowpath_null>
ffffffff811091de: 49 8b 57 30 mov 0x30(%r15),%rdx
ffffffff811091e2: 4d 8b 47 28 mov 0x28(%r15),%r8
ffffffff811091e6: be 00 01 00 00 mov $0x100,%esi
ffffffff811091eb: 48 8b 7d 88 mov -0x78(%rbp),%rdi
ffffffff811091ef: 45 31 c9 xor %r9d,%r9d
ffffffff811091f2: b9 02 00 00 00 mov $0x2,%ecx
ffffffff811091f7: e8 49 73 02 00 callq ffffffff81130545 <fsnotify>
fsnotify_create(dir, dentry);
acc_mode = MAY_OPEN;
ffffffff811091fc: be 20 00 00 00 mov $0x20,%esi
}
error = may_open(&file->f_path, acc_mode, open_flag);
ffffffff81109201: 8b 55 ac mov -0x54(%rbp),%edx
ffffffff81109204: 49 8d 7d 10 lea 0x10(%r13),%rdi
ffffffff81109208: e8 dc fa ff ff callq ffffffff81108ce9 <may_open>
if (error)
ffffffff8110920d: 85 c0 test %eax,%eax
if (*opened & FILE_CREATED) {
WARN_ON(!(open_flag & O_CREAT));
fsnotify_create(dir, dentry);
acc_mode = MAY_OPEN;
}
error = may_open(&file->f_path, acc_mode, open_flag);
ffffffff8110920f: 41 89 c6 mov %eax,%r14d
if (error)
ffffffff81109212: 0f 84 47 01 00 00 je ffffffff8110935f <do_last.isra.44+0x58c>
fput(file);
ffffffff81109218: 4c 89 ef mov %r13,%rdi
ffffffff8110921b: e8 d6 56 ff ff callq ffffffff810fe8f6 <fput>
ffffffff81109220: e9 3a 01 00 00 jmpq ffffffff8110935f <do_last.isra.44+0x58c>
BUG_ON(dentry->d_inode);
/* Don't create child dentry for a dead directory. */
if (unlikely(IS_DEADDIR(dir))) {
error = -ENOENT;
ffffffff81109225: 41 be fe ff ff ff mov $0xfffffffe,%r14d
ffffffff8110922b: e9 2f 01 00 00 jmpq ffffffff8110935f <do_last.isra.44+0x58c>
file->f_path.dentry = DENTRY_NOT_SET;
file->f_path.mnt = nd->path.mnt;
error = dir->i_op->atomic_open(dir, dentry, file, open_flag, mode,
opened);
if (error < 0) {
if (create_error && error == -ENOENT)
ffffffff81109230: 41 89 c6 mov %eax,%r14d
ffffffff81109233: e9 27 01 00 00 jmpq ffffffff8110935f <do_last.isra.44+0x58c>
error = create_error;
goto out;
}
} else {
if (excl && !(*opened & FILE_CREATED)) {
error = -EEXIST;
ffffffff81109238: 41 be ef ff ff ff mov $0xffffffef,%r14d
ffffffff8110923e: e9 1c 01 00 00 jmpq ffffffff8110935f <do_last.isra.44+0x58c>
* back to lookup + open
*/
goto no_open;
} else if (open_flag & (O_EXCL | O_TRUNC)) {
/* Fall back and fail with the right error */
create_error = -EROFS;
ffffffff81109243: 41 be e2 ff ff ff mov $0xffffffe2,%r14d
out:
dput(dentry);
return error;
no_open:
if (need_lookup) {
ffffffff81109249: 80 7d a9 00 cmpb $0x0,-0x57(%rbp)
ffffffff8110924d: 0f 84 f2 00 00 00 je ffffffff81109345 <do_last.isra.44+0x572>
dentry = lookup_real(dir, dentry, nd->flags);
ffffffff81109253: 8b 53 38 mov 0x38(%rbx),%edx
ffffffff81109256: 48 8b 7d 88 mov -0x78(%rbp),%rdi
ffffffff8110925a: 4c 89 fe mov %r15,%rsi
ffffffff8110925d: e8 82 bc ff ff callq ffffffff81104ee4 <lookup_real>
if (IS_ERR(dentry))
ffffffff81109262: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax
dput(dentry);
return error;
no_open:
if (need_lookup) {
dentry = lookup_real(dir, dentry, nd->flags);
ffffffff81109268: 49 89 c7 mov %rax,%r15
if (IS_ERR(dentry))
ffffffff8110926b: 76 02 jbe ffffffff8110926f <do_last.isra.44+0x49c>
ffffffff8110926d: eb 6b jmp ffffffff811092da <do_last.isra.44+0x507>
return PTR_ERR(dentry);
if (create_error) {
ffffffff8110926f: 45 85 f6 test %r14d,%r14d
ffffffff81109272: 0f 84 cd 00 00 00 je ffffffff81109345 <do_last.isra.44+0x572>
int open_flag = op->open_flag;
ffffffff81109278: 48 8b 45 98 mov -0x68(%rbp),%rax
ffffffff8110927c: 8b 10 mov (%rax),%edx
error = create_error;
if ((open_flag & O_EXCL)) {
ffffffff8110927e: f6 c2 80 test $0x80,%dl
ffffffff81109281: 74 07 je ffffffff8110928a <do_last.isra.44+0x4b7>
if (!dentry->d_inode)
ffffffff81109283: 49 83 7f 30 00 cmpq $0x0,0x30(%r15)
ffffffff81109288: eb 20 jmp ffffffff811092aa <do_last.isra.44+0x4d7>
goto out;
} else if (!dentry->d_inode) {
ffffffff8110928a: 49 8b 47 30 mov 0x30(%r15),%rax
ffffffff8110928e: 48 85 c0 test %rax,%rax
ffffffff81109291: 0f 84 c8 00 00 00 je ffffffff8110935f <do_last.isra.44+0x58c>
goto out;
} else if ((open_flag & O_TRUNC) &&
ffffffff81109297: 80 e6 02 and $0x2,%dh
ffffffff8110929a: 0f 84 a5 00 00 00 je ffffffff81109345 <do_last.isra.44+0x572>
S_ISREG(dentry->d_inode->i_mode)) {
ffffffff811092a0: 8b 00 mov (%rax),%eax
ffffffff811092a2: 66 25 00 f0 and $0xf000,%ax
if ((open_flag & O_EXCL)) {
if (!dentry->d_inode)
goto out;
} else if (!dentry->d_inode) {
goto out;
} else if ((open_flag & O_TRUNC) &&
ffffffff811092a6: 66 3d 00 80 cmp $0x8000,%ax
ffffffff811092aa: 0f 84 af 00 00 00 je ffffffff8110935f <do_last.isra.44+0x58c>
ffffffff811092b0: e9 90 00 00 00 jmpq ffffffff81109345 <do_last.isra.44+0x572>
if ((nd->flags & LOOKUP_OPEN) && dir_inode->i_op->atomic_open) {
return atomic_open(nd, dentry, path, file, op, got_write,
need_lookup, opened);
}
if (need_lookup) {
ffffffff811092b5: 80 7d a9 00 cmpb $0x0,-0x57(%rbp)
ffffffff811092b9: 74 27 je ffffffff811092e2 <do_last.isra.44+0x50f>
BUG_ON(dentry->d_inode);
ffffffff811092bb: 49 83 7f 30 00 cmpq $0x0,0x30(%r15)
ffffffff811092c0: 74 02 je ffffffff811092c4 <do_last.isra.44+0x4f1>
ffffffff811092c2: 0f 0b ud2
dentry = lookup_real(dir_inode, dentry, nd->flags);
ffffffff811092c4: 4c 89 fe mov %r15,%rsi
ffffffff811092c7: 4c 89 c7 mov %r8,%rdi
ffffffff811092ca: e8 15 bc ff ff callq ffffffff81104ee4 <lookup_real>
if (IS_ERR(dentry))
ffffffff811092cf: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax
}
if (need_lookup) {
BUG_ON(dentry->d_inode);
dentry = lookup_real(dir_inode, dentry, nd->flags);
ffffffff811092d5: 49 89 c7 mov %rax,%r15
if (IS_ERR(dentry))
ffffffff811092d8: 76 08 jbe ffffffff811092e2 <do_last.isra.44+0x50f>
return PTR_ERR(dentry);
ffffffff811092da: 45 89 fe mov %r15d,%r14d
ffffffff811092dd: e9 85 00 00 00 jmpq ffffffff81109367 <do_last.isra.44+0x594>
}
/* Negative dentry, just create the file */
if (!dentry->d_inode && (op->open_flag & O_CREAT)) {
ffffffff811092e2: 49 83 7f 30 00 cmpq $0x0,0x30(%r15)
ffffffff811092e7: 75 5c jne ffffffff81109345 <do_last.isra.44+0x572>
ffffffff811092e9: 48 8b 55 98 mov -0x68(%rbp),%rdx
ffffffff811092ed: f6 02 40 testb $0x40,(%rdx)
ffffffff811092f0: 74 53 je ffffffff81109345 <do_last.isra.44+0x572>
umode_t mode = op->mode;
if (!IS_POSIXACL(dir->d_inode))
ffffffff811092f2: 49 8b 46 30 mov 0x30(%r14),%rax
return PTR_ERR(dentry);
}
/* Negative dentry, just create the file */
if (!dentry->d_inode && (op->open_flag & O_CREAT)) {
umode_t mode = op->mode;
ffffffff811092f6: 8b 52 04 mov 0x4(%rdx),%edx
if (!IS_POSIXACL(dir->d_inode))
ffffffff811092f9: 48 8b 40 28 mov 0x28(%rax),%rax
ffffffff811092fd: f6 40 52 01 testb $0x1,0x52(%rax)
ffffffff81109301: 75 15 jne ffffffff81109318 <do_last.isra.44+0x545>
mode &= ~current_umask();
ffffffff81109303: 89 95 60 ff ff ff mov %edx,-0xa0(%rbp)
ffffffff81109309: e8 ba a2 01 00 callq ffffffff811235c8 <current_umask>
ffffffff8110930e: 8b 95 60 ff ff ff mov -0xa0(%rbp),%edx
ffffffff81109314: f7 d0 not %eax
ffffffff81109316: 21 c2 and %eax,%edx
* rw->ro transition does not occur between
* the time when the file is created and when
* a permanent write count is taken through
* the 'struct file' in finish_open().
*/
if (!got_write) {
ffffffff81109318: 80 7d ab 00 cmpb $0x0,-0x55(%rbp)
ffffffff8110931c: 74 3b je ffffffff81109359 <do_last.isra.44+0x586>
error = -EROFS;
goto out_dput;
}
*opened |= FILE_CREATED;
ffffffff8110931e: 48 8b 45 a0 mov -0x60(%rbp),%rax
error = security_path_mknod(&nd->path, dentry, mode, 0);
if (error)
goto out_dput;
error = vfs_create(dir->d_inode, dentry, mode,
ffffffff81109322: 0f b7 d2 movzwl %dx,%edx
ffffffff81109325: 4c 89 fe mov %r15,%rsi
*/
if (!got_write) {
error = -EROFS;
goto out_dput;
}
*opened |= FILE_CREATED;
ffffffff81109328: 83 08 01 orl $0x1,(%rax)
error = security_path_mknod(&nd->path, dentry, mode, 0);
if (error)
goto out_dput;
error = vfs_create(dir->d_inode, dentry, mode,
ffffffff8110932b: 8b 4b 38 mov 0x38(%rbx),%ecx
ffffffff8110932e: 49 8b 7e 30 mov 0x30(%r14),%rdi
ffffffff81109332: c1 e9 0a shr $0xa,%ecx
ffffffff81109335: 83 e1 01 and $0x1,%ecx
ffffffff81109338: e8 94 db ff ff callq ffffffff81106ed1 <vfs_create>
ffffffff8110933d: 41 89 c6 mov %eax,%r14d
nd->flags & LOOKUP_EXCL);
if (error)
ffffffff81109340: 45 85 f6 test %r14d,%r14d
ffffffff81109343: 75 1a jne ffffffff8110935f <do_last.isra.44+0x58c>
goto out_dput;
}
out_no_open:
path->dentry = dentry;
ffffffff81109345: 4d 89 7c 24 08 mov %r15,0x8(%r12)
path->mnt = nd->path.mnt;
ffffffff8110934a: 48 8b 03 mov (%rbx),%rax
return 1;
ffffffff8110934d: 41 be 01 00 00 00 mov $0x1,%r14d
if (error)
goto out_dput;
}
out_no_open:
path->dentry = dentry;
path->mnt = nd->path.mnt;
ffffffff81109353: 49 89 04 24 mov %rax,(%r12)
ffffffff81109357: eb 0e jmp ffffffff81109367 <do_last.isra.44+0x594>
* the time when the file is created and when
* a permanent write count is taken through
* the 'struct file' in finish_open().
*/
if (!got_write) {
error = -EROFS;
ffffffff81109359: 41 be e2 ff ff ff mov $0xffffffe2,%r14d
path->dentry = dentry;
path->mnt = nd->path.mnt;
return 1;
out_dput:
dput(dentry);
ffffffff8110935f: 4c 89 ff mov %r15,%rdi
ffffffff81109362: e8 62 63 00 00 callq ffffffff8110f6c9 <dput>
* dropping this one anyway.
*/
}
mutex_lock(&dir->d_inode->i_mutex);
error = lookup_open(nd, path, file, op, got_write, opened);
mutex_unlock(&dir->d_inode->i_mutex);
ffffffff81109367: 48 8b 55 80 mov -0x80(%rbp),%rdx
ffffffff8110936b: 48 8b 52 30 mov 0x30(%rdx),%rdx
ffffffff8110936f: 48 89 d7 mov %rdx,%rdi
ffffffff81109372: 48 81 c7 a0 00 00 00 add $0xa0,%rdi
ffffffff81109379: e8 4a 85 27 00 callq ffffffff813818c8 <mutex_unlock>
if (error <= 0) {
ffffffff8110937e: 41 83 fe 00 cmp $0x0,%r14d
ffffffff81109382: 7f 31 jg ffffffff811093b5 <do_last.isra.44+0x5e2>
if (error)
ffffffff81109384: 0f 85 21 03 00 00 jne ffffffff811096ab <do_last.isra.44+0x8d8>
goto out;
if ((*opened & FILE_CREATED) ||
ffffffff8110938a: 48 8b 45 a0 mov -0x60(%rbp),%rax
ffffffff8110938e: f6 00 01 testb $0x1,(%rax)
ffffffff81109391: 0f 85 93 02 00 00 jne ffffffff8110962a <do_last.isra.44+0x857>
!S_ISREG(file_inode(file)->i_mode))
ffffffff81109397: 49 8b 45 20 mov 0x20(%r13),%rax
will_truncate = false;
ffffffff8110939b: 8a 55 aa mov -0x56(%rbp),%dl
if (error <= 0) {
if (error)
goto out;
if ((*opened & FILE_CREATED) ||
!S_ISREG(file_inode(file)->i_mode))
ffffffff8110939e: 8b 00 mov (%rax),%eax
ffffffff811093a0: 66 25 00 f0 and $0xf000,%ax
will_truncate = false;
ffffffff811093a4: 66 3d 00 80 cmp $0x8000,%ax
ffffffff811093a8: b0 00 mov $0x0,%al
ffffffff811093aa: 0f 45 d0 cmovne %eax,%edx
ffffffff811093ad: 88 55 aa mov %dl,-0x56(%rbp)
ffffffff811093b0: e9 79 02 00 00 jmpq ffffffff8110962e <do_last.isra.44+0x85b>
audit_inode(name, file->f_path.dentry, 0);
goto opened;
}
if (*opened & FILE_CREATED) {
ffffffff811093b5: 48 8b 45 a0 mov -0x60(%rbp),%rax
ffffffff811093b9: f6 00 01 testb $0x1,(%rax)
ffffffff811093bc: 74 47 je ffffffff81109405 <do_last.isra.44+0x632>
/* Don't check for write permission, don't truncate */
open_flag &= ~O_TRUNC;
ffffffff811093be: 81 65 94 ff fd ff ff andl $0xfffffdff,-0x6c(%rbp)
}
static inline void path_to_nameidata(const struct path *path,
struct nameidata *nd)
{
if (!(nd->flags & LOOKUP_RCU)) {
ffffffff811093c5: f6 43 38 40 testb $0x40,0x38(%rbx)
ffffffff811093c9: 75 17 jne ffffffff811093e2 <do_last.isra.44+0x60f>
dput(nd->path.dentry);
ffffffff811093cb: 48 8b 7b 08 mov 0x8(%rbx),%rdi
ffffffff811093cf: e8 f5 62 00 00 callq ffffffff8110f6c9 <dput>
if (nd->path.mnt != path->mnt)
ffffffff811093d4: 48 8b 3b mov (%rbx),%rdi
ffffffff811093d7: 49 3b 3c 24 cmp (%r12),%rdi
ffffffff811093db: 74 05 je ffffffff811093e2 <do_last.isra.44+0x60f>
mntput(nd->path.mnt);
ffffffff811093dd: e8 b1 ca 00 00 callq ffffffff81115e93 <mntput>
}
nd->path.mnt = path->mnt;
ffffffff811093e2: 49 8b 04 24 mov (%r12),%rax
}
if (*opened & FILE_CREATED) {
/* Don't check for write permission, don't truncate */
open_flag &= ~O_TRUNC;
will_truncate = false;
ffffffff811093e6: c6 45 aa 00 movb $0x0,-0x56(%rbp)
acc_mode = MAY_OPEN;
ffffffff811093ea: c7 85 7c ff ff ff 20 movl $0x20,-0x84(%rbp)
ffffffff811093f1: 00 00 00
if (!(nd->flags & LOOKUP_RCU)) {
dput(nd->path.dentry);
if (nd->path.mnt != path->mnt)
mntput(nd->path.mnt);
}
nd->path.mnt = path->mnt;
ffffffff811093f4: 48 89 03 mov %rax,(%rbx)
nd->path.dentry = path->dentry;
ffffffff811093f7: 49 8b 44 24 08 mov 0x8(%r12),%rax
ffffffff811093fc: 48 89 43 08 mov %rax,0x8(%rbx)
ffffffff81109400: e9 d9 01 00 00 jmpq ffffffff811095de <do_last.isra.44+0x80b>
/*
* If atomic_open() acquired write access it is dropped now due to
* possible mount and symlink following (this might be optimized away if
* necessary...)
*/
if (got_write) {
ffffffff81109405: 80 7d ab 00 cmpb $0x0,-0x55(%rbp)
ffffffff81109409: 74 08 je ffffffff81109413 <do_last.isra.44+0x640>
mnt_drop_write(nd->path.mnt);
ffffffff8110940b: 48 8b 3b mov (%rbx),%rdi
ffffffff8110940e: e8 75 bf 00 00 callq ffffffff81115388 <mnt_drop_write>
got_write = false;
}
error = -EEXIST;
if ((open_flag & (O_EXCL | O_CREAT)) == (O_EXCL | O_CREAT))
ffffffff81109413: 8b 45 94 mov -0x6c(%rbp),%eax
ffffffff81109416: 25 c0 00 00 00 and $0xc0,%eax
ffffffff8110941b: 3d c0 00 00 00 cmp $0xc0,%eax
ffffffff81109420: 0f 84 a9 02 00 00 je ffffffff811096cf <do_last.isra.44+0x8fc>
goto exit_dput;
error = follow_managed(path, nd->flags);
ffffffff81109426: 8b 73 38 mov 0x38(%rbx),%esi
ffffffff81109429: 4c 89 e7 mov %r12,%rdi
ffffffff8110942c: e8 f2 c0 ff ff callq ffffffff81105523 <follow_managed>
if (error < 0)
ffffffff81109431: 83 f8 00 cmp $0x0,%eax
error = -EEXIST;
if ((open_flag & (O_EXCL | O_CREAT)) == (O_EXCL | O_CREAT))
goto exit_dput;
error = follow_managed(path, nd->flags);
ffffffff81109434: 41 89 c6 mov %eax,%r14d
if (error < 0)
ffffffff81109437: 0f 8c 98 02 00 00 jl ffffffff811096d5 <do_last.isra.44+0x902>
goto exit_dput;
if (error)
ffffffff8110943d: 74 07 je ffffffff81109446 <do_last.isra.44+0x673>
nd->flags |= LOOKUP_JUMPED;
ffffffff8110943f: 81 4b 38 00 10 00 00 orl $0x1000,0x38(%rbx)
BUG_ON(nd->flags & LOOKUP_RCU);
ffffffff81109446: f6 43 38 40 testb $0x40,0x38(%rbx)
ffffffff8110944a: 74 02 je ffffffff8110944e <do_last.isra.44+0x67b>
ffffffff8110944c: 0f 0b ud2
inode = path->dentry->d_inode;
ffffffff8110944e: 49 8b 44 24 08 mov 0x8(%r12),%rax
ffffffff81109453: 48 8b 40 30 mov 0x30(%rax),%rax
ffffffff81109457: 48 89 45 b8 mov %rax,-0x48(%rbp)
finish_lookup:
/* we _can_ be in RCU mode here */
error = -ENOENT;
if (d_is_negative(path->dentry)) {
ffffffff8110945b: 49 8b 74 24 08 mov 0x8(%r12),%rsi
ffffffff81109460: 8b 43 38 mov 0x38(%rbx),%eax
ffffffff81109463: 8b 16 mov (%rsi),%edx
ffffffff81109465: 81 e2 00 00 70 00 and $0x700000,%edx
ffffffff8110946b: 75 36 jne ffffffff811094a3 <do_last.isra.44+0x6d0>
}
static inline void path_to_nameidata(const struct path *path,
struct nameidata *nd)
{
if (!(nd->flags & LOOKUP_RCU)) {
ffffffff8110946d: a8 40 test $0x40,%al
ffffffff8110946f: 75 17 jne ffffffff81109488 <do_last.isra.44+0x6b5>
dput(nd->path.dentry);
ffffffff81109471: 48 8b 7b 08 mov 0x8(%rbx),%rdi
ffffffff81109475: e8 4f 62 00 00 callq ffffffff8110f6c9 <dput>
if (nd->path.mnt != path->mnt)
ffffffff8110947a: 48 8b 3b mov (%rbx),%rdi
ffffffff8110947d: 49 3b 3c 24 cmp (%r12),%rdi
ffffffff81109481: 74 05 je ffffffff81109488 <do_last.isra.44+0x6b5>
mntput(nd->path.mnt);
ffffffff81109483: e8 0b ca 00 00 callq ffffffff81115e93 <mntput>
}
nd->path.mnt = path->mnt;
ffffffff81109488: 49 8b 04 24 mov (%r12),%rax
BUG_ON(nd->flags & LOOKUP_RCU);
inode = path->dentry->d_inode;
finish_lookup:
/* we _can_ be in RCU mode here */
error = -ENOENT;
ffffffff8110948c: 41 be fe ff ff ff mov $0xfffffffe,%r14d
if (!(nd->flags & LOOKUP_RCU)) {
dput(nd->path.dentry);
if (nd->path.mnt != path->mnt)
mntput(nd->path.mnt);
}
nd->path.mnt = path->mnt;
ffffffff81109492: 48 89 03 mov %rax,(%rbx)
nd->path.dentry = path->dentry;
ffffffff81109495: 49 8b 44 24 08 mov 0x8(%r12),%rax
ffffffff8110949a: 48 89 43 08 mov %rax,0x8(%rbx)
ffffffff8110949e: e9 16 02 00 00 jmpq ffffffff811096b9 <do_last.isra.44+0x8e6>
* so we keep a cache of "no, this doesn't need follow_link"
* for the common case.
*/
static inline int should_follow_link(struct dentry *dentry, int follow)
{
return unlikely(d_is_symlink(dentry)) ? follow : 0;
ffffffff811094a3: 81 fa 00 00 30 00 cmp $0x300000,%edx
ffffffff811094a9: 75 37 jne ffffffff811094e2 <do_last.isra.44+0x70f>
if (d_is_negative(path->dentry)) {
path_to_nameidata(path, nd);
goto out;
}
if (should_follow_link(path->dentry, !symlink_ok)) {
ffffffff811094ab: 80 7d 93 00 cmpb $0x0,-0x6d(%rbp)
ffffffff811094af: 75 31 jne ffffffff811094e2 <do_last.isra.44+0x70f>
if (nd->flags & LOOKUP_RCU) {
ffffffff811094b1: a8 40 test $0x40,%al
ffffffff811094b3: 75 1a jne ffffffff811094cf <do_last.isra.44+0x6fc>
if (unlikely(unlazy_walk(nd, path->dentry))) {
error = -ECHILD;
goto out;
}
}
BUG_ON(inode != path->dentry->d_inode);
ffffffff811094b5: 49 8b 44 24 08 mov 0x8(%r12),%rax
ffffffff811094ba: 48 8b 50 30 mov 0x30(%rax),%rdx
ffffffff811094be: 48 39 55 b8 cmp %rdx,-0x48(%rbp)
ffffffff811094c2: 75 1c jne ffffffff811094e0 <do_last.isra.44+0x70d>
return 1;
ffffffff811094c4: 41 be 01 00 00 00 mov $0x1,%r14d
ffffffff811094ca: e9 dc 02 00 00 jmpq ffffffff811097ab <do_last.isra.44+0x9d8>
goto out;
}
if (should_follow_link(path->dentry, !symlink_ok)) {
if (nd->flags & LOOKUP_RCU) {
if (unlikely(unlazy_walk(nd, path->dentry))) {
ffffffff811094cf: 48 89 df mov %rbx,%rdi
ffffffff811094d2: e8 48 bf ff ff callq ffffffff8110541f <unlazy_walk>
ffffffff811094d7: 85 c0 test %eax,%eax
ffffffff811094d9: 74 da je ffffffff811094b5 <do_last.isra.44+0x6e2>
ffffffff811094db: e9 c0 02 00 00 jmpq ffffffff811097a0 <do_last.isra.44+0x9cd>
error = -ECHILD;
goto out;
}
}
BUG_ON(inode != path->dentry->d_inode);
ffffffff811094e0: 0f 0b ud2
return 1;
}
if ((nd->flags & LOOKUP_RCU) || nd->path.mnt != path->mnt) {
ffffffff811094e2: a8 40 test $0x40,%al
ffffffff811094e4: 75 20 jne ffffffff81109506 <do_last.isra.44+0x733>
ffffffff811094e6: 48 8b 03 mov (%rbx),%rax
ffffffff811094e9: 49 3b 04 24 cmp (%r12),%rax
ffffffff811094ed: 48 8b 7b 08 mov 0x8(%rbx),%rdi
ffffffff811094f1: 74 1c je ffffffff8110950f <do_last.isra.44+0x73c>
static inline void path_to_nameidata(const struct path *path,
struct nameidata *nd)
{
if (!(nd->flags & LOOKUP_RCU)) {
dput(nd->path.dentry);
ffffffff811094f3: e8 d1 61 00 00 callq ffffffff8110f6c9 <dput>
if (nd->path.mnt != path->mnt)
ffffffff811094f8: 48 8b 3b mov (%rbx),%rdi
ffffffff811094fb: 49 3b 3c 24 cmp (%r12),%rdi
ffffffff811094ff: 74 05 je ffffffff81109506 <do_last.isra.44+0x733>
mntput(nd->path.mnt);
ffffffff81109501: e8 8d c9 00 00 callq ffffffff81115e93 <mntput>
}
nd->path.mnt = path->mnt;
ffffffff81109506: 49 8b 04 24 mov (%r12),%rax
ffffffff8110950a: 48 89 03 mov %rax,(%rbx)
ffffffff8110950d: eb 10 jmp ffffffff8110951f <do_last.isra.44+0x74c>
}
if ((nd->flags & LOOKUP_RCU) || nd->path.mnt != path->mnt) {
path_to_nameidata(path, nd);
} else {
save_parent.dentry = nd->path.dentry;
ffffffff8110950f: 48 89 7d c8 mov %rdi,-0x38(%rbp)
save_parent.mnt = mntget(path->mnt);
ffffffff81109513: 48 89 c7 mov %rax,%rdi
ffffffff81109516: e8 d0 b9 00 00 callq ffffffff81114eeb <mntget>
ffffffff8110951b: 48 89 45 c0 mov %rax,-0x40(%rbp)
nd->path.dentry = path->dentry;
ffffffff8110951f: 49 8b 44 24 08 mov 0x8(%r12),%rax
ffffffff81109524: 48 89 43 08 mov %rax,0x8(%rbx)
}
nd->inode = inode;
ffffffff81109528: 48 8b 45 b8 mov -0x48(%rbp),%rax
ffffffff8110952c: 48 89 43 30 mov %rax,0x30(%rbx)
/* Why this, you ask? _Now_ we might have grown LOOKUP_JUMPED... */
finish_open:
error = complete_walk(nd);
ffffffff81109530: 48 89 df mov %rbx,%rdi
ffffffff81109533: e8 79 bb ff ff callq ffffffff811050b1 <complete_walk>
if (error) {
ffffffff81109538: 85 c0 test %eax,%eax
}
nd->inode = inode;
/* Why this, you ask? _Now_ we might have grown LOOKUP_JUMPED... */
finish_open:
error = complete_walk(nd);
ffffffff8110953a: 41 89 c6 mov %eax,%r14d
if (error) {
ffffffff8110953d: 74 0e je ffffffff8110954d <do_last.isra.44+0x77a>
path_put(&save_parent);
ffffffff8110953f: 48 8d 7d c0 lea -0x40(%rbp),%rdi
ffffffff81109543: e8 15 bb ff ff callq ffffffff8110505d <path_put>
ffffffff81109548: e9 5e 02 00 00 jmpq ffffffff811097ab <do_last.isra.44+0x9d8>
return error;
}
audit_inode(name, nd->path.dentry, 0);
error = -EISDIR;
if ((open_flag & O_CREAT) && d_is_dir(nd->path.dentry))
ffffffff8110954d: f6 45 94 40 testb $0x40,-0x6c(%rbp)
ffffffff81109551: 74 2c je ffffffff8110957f <do_last.isra.44+0x7ac>
const struct inode_operations page_symlink_inode_operations = {
.readlink = generic_readlink,
.follow_link = page_follow_link_light,
.put_link = page_put_link,
};
EXPORT_SYMBOL(page_symlink_inode_operations);
ffffffff81109553: 48 8b 43 08 mov 0x8(%rbx),%rax
spin_unlock(&dentry->d_lock);
}
static inline unsigned __d_entry_type(const struct dentry *dentry)
{
return dentry->d_flags & DCACHE_ENTRY_TYPE;
ffffffff81109557: 8b 00 mov (%rax),%eax
ffffffff81109559: 25 00 00 70 00 and $0x700000,%eax
return __d_entry_type(dentry) == DCACHE_AUTODIR_TYPE;
}
static inline bool d_is_dir(const struct dentry *dentry)
{
return d_can_lookup(dentry) || d_is_autodir(dentry);
ffffffff8110955e: 3d 00 00 10 00 cmp $0x100000,%eax
ffffffff81109563: 74 0d je ffffffff81109572 <do_last.isra.44+0x79f>
ffffffff81109565: 3d 00 00 20 00 cmp $0x200000,%eax
ffffffff8110956a: 0f 94 c0 sete %al
ffffffff8110956d: 0f b6 c0 movzbl %al,%eax
ffffffff81109570: eb 05 jmp ffffffff81109577 <do_last.isra.44+0x7a4>
ffffffff81109572: b8 01 00 00 00 mov $0x1,%eax
path_put(&save_parent);
return error;
}
audit_inode(name, nd->path.dentry, 0);
error = -EISDIR;
if ((open_flag & O_CREAT) && d_is_dir(nd->path.dentry))
ffffffff81109577: 85 c0 test %eax,%eax
ffffffff81109579: 0f 85 72 f9 ff ff jne ffffffff81108ef1 <do_last.isra.44+0x11e>
goto out;
error = -ENOTDIR;
if ((nd->flags & LOOKUP_DIRECTORY) && !d_can_lookup(nd->path.dentry))
ffffffff8110957f: f6 43 38 02 testb $0x2,0x38(%rbx)
ffffffff81109583: 74 1c je ffffffff811095a1 <do_last.isra.44+0x7ce>
const struct inode_operations page_symlink_inode_operations = {
.readlink = generic_readlink,
.follow_link = page_follow_link_light,
.put_link = page_put_link,
};
EXPORT_SYMBOL(page_symlink_inode_operations);
ffffffff81109585: 48 8b 43 08 mov 0x8(%rbx),%rax
}
audit_inode(name, nd->path.dentry, 0);
error = -EISDIR;
if ((open_flag & O_CREAT) && d_is_dir(nd->path.dentry))
goto out;
error = -ENOTDIR;
ffffffff81109589: 41 be ec ff ff ff mov $0xffffffec,%r14d
spin_unlock(&dentry->d_lock);
}
static inline unsigned __d_entry_type(const struct dentry *dentry)
{
return dentry->d_flags & DCACHE_ENTRY_TYPE;
ffffffff8110958f: 8b 00 mov (%rax),%eax
ffffffff81109591: 25 00 00 70 00 and $0x700000,%eax
if ((nd->flags & LOOKUP_DIRECTORY) && !d_can_lookup(nd->path.dentry))
ffffffff81109596: 3d 00 00 10 00 cmp $0x100000,%eax
ffffffff8110959b: 0f 85 18 01 00 00 jne ffffffff811096b9 <do_last.isra.44+0x8e6>
goto out;
if (!S_ISREG(nd->inode->i_mode))
ffffffff811095a1: 48 8b 43 30 mov 0x30(%rbx),%rax
ffffffff811095a5: 8b 00 mov (%rax),%eax
ffffffff811095a7: 66 25 00 f0 and $0xf000,%ax
ffffffff811095ab: 66 3d 00 80 cmp $0x8000,%ax
ffffffff811095af: 75 1f jne ffffffff811095d0 <do_last.isra.44+0x7fd>
will_truncate = false;
if (will_truncate) {
ffffffff811095b1: 80 7d aa 00 cmpb $0x0,-0x56(%rbp)
ffffffff811095b5: 74 23 je ffffffff811095da <do_last.isra.44+0x807>
error = mnt_want_write(nd->path.mnt);
ffffffff811095b7: 48 8b 3b mov (%rbx),%rdi
ffffffff811095ba: e8 89 cb 00 00 callq ffffffff81116148 <mnt_want_write>
if (error)
ffffffff811095bf: 85 c0 test %eax,%eax
goto out;
if (!S_ISREG(nd->inode->i_mode))
will_truncate = false;
if (will_truncate) {
error = mnt_want_write(nd->path.mnt);
ffffffff811095c1: 41 89 c6 mov %eax,%r14d
if (error)
ffffffff811095c4: 0f 85 ef 00 00 00 jne ffffffff811096b9 <do_last.isra.44+0x8e6>
goto out;
got_write = true;
ffffffff811095ca: c6 45 ab 01 movb $0x1,-0x55(%rbp)
ffffffff811095ce: eb 0e jmp ffffffff811095de <do_last.isra.44+0x80b>
if ((open_flag & O_CREAT) && d_is_dir(nd->path.dentry))
goto out;
error = -ENOTDIR;
if ((nd->flags & LOOKUP_DIRECTORY) && !d_can_lookup(nd->path.dentry))
goto out;
if (!S_ISREG(nd->inode->i_mode))
ffffffff811095d0: c6 45 ab 00 movb $0x0,-0x55(%rbp)
ffffffff811095d4: c6 45 aa 00 movb $0x0,-0x56(%rbp)
ffffffff811095d8: eb 04 jmp ffffffff811095de <do_last.isra.44+0x80b>
will_truncate = false;
if (will_truncate) {
ffffffff811095da: c6 45 ab 00 movb $0x0,-0x55(%rbp)
if (error)
goto out;
got_write = true;
}
finish_open_created:
error = may_open(&nd->path, acc_mode, open_flag);
ffffffff811095de: 8b 55 94 mov -0x6c(%rbp),%edx
ffffffff811095e1: 8b b5 7c ff ff ff mov -0x84(%rbp),%esi
ffffffff811095e7: 48 89 df mov %rbx,%rdi
ffffffff811095ea: e8 fa f6 ff ff callq ffffffff81108ce9 <may_open>
if (error)
ffffffff811095ef: 85 c0 test %eax,%eax
if (error)
goto out;
got_write = true;
}
finish_open_created:
error = may_open(&nd->path, acc_mode, open_flag);
ffffffff811095f1: 41 89 c6 mov %eax,%r14d
if (error)
ffffffff811095f4: 0f 85 b1 00 00 00 jne ffffffff811096ab <do_last.isra.44+0x8d8>
goto out;
file->f_path.mnt = nd->path.mnt;
ffffffff811095fa: 48 8b 03 mov (%rbx),%rax
error = finish_open(file, nd->path.dentry, NULL, opened);
ffffffff811095fd: 48 8b 4d a0 mov -0x60(%rbp),%rcx
ffffffff81109601: 31 d2 xor %edx,%edx
ffffffff81109603: 4c 89 ef mov %r13,%rdi
}
finish_open_created:
error = may_open(&nd->path, acc_mode, open_flag);
if (error)
goto out;
file->f_path.mnt = nd->path.mnt;
ffffffff81109606: 49 89 45 10 mov %rax,0x10(%r13)
error = finish_open(file, nd->path.dentry, NULL, opened);
ffffffff8110960a: 48 8b 73 08 mov 0x8(%rbx),%rsi
ffffffff8110960e: e8 91 29 ff ff callq ffffffff810fbfa4 <finish_open>
if (error) {
ffffffff81109613: 85 c0 test %eax,%eax
finish_open_created:
error = may_open(&nd->path, acc_mode, open_flag);
if (error)
goto out;
file->f_path.mnt = nd->path.mnt;
error = finish_open(file, nd->path.dentry, NULL, opened);
ffffffff81109615: 41 89 c6 mov %eax,%r14d
if (error) {
ffffffff81109618: 74 14 je ffffffff8110962e <do_last.isra.44+0x85b>
if (error == -EOPENSTALE)
ffffffff8110961a: 3d fa fd ff ff cmp $0xfffffdfa,%eax
ffffffff8110961f: 0f 85 86 00 00 00 jne ffffffff811096ab <do_last.isra.44+0x8d8>
ffffffff81109625: e9 c2 00 00 00 jmpq ffffffff811096ec <do_last.isra.44+0x919>
if (error)
goto out;
if ((*opened & FILE_CREATED) ||
!S_ISREG(file_inode(file)->i_mode))
will_truncate = false;
ffffffff8110962a: c6 45 aa 00 movb $0x0,-0x56(%rbp)
if (error == -EOPENSTALE)
goto stale_open;
goto out;
}
opened:
error = open_check_o_direct(file);
ffffffff8110962e: 4c 89 ef mov %r13,%rdi
ffffffff81109631: e8 e6 35 ff ff callq ffffffff810fcc1c <open_check_o_direct>
if (error)
ffffffff81109636: 85 c0 test %eax,%eax
if (error == -EOPENSTALE)
goto stale_open;
goto out;
}
opened:
error = open_check_o_direct(file);
ffffffff81109638: 41 89 c6 mov %eax,%r14d
if (error)
ffffffff8110963b: 0f 85 a1 00 00 00 jne ffffffff811096e2 <do_last.isra.44+0x90f>
goto exit_fput;
error = ima_file_check(file, op->acc_mode);
if (error)
goto exit_fput;
if (will_truncate) {
ffffffff81109641: 80 7d aa 00 cmpb $0x0,-0x56(%rbp)
ffffffff81109645: 74 64 je ffffffff811096ab <do_last.isra.44+0x8d8>
}
static int handle_truncate(struct file *filp)
{
struct path *path = &filp->f_path;
struct inode *inode = path->dentry->d_inode;
ffffffff81109647: 49 8b 45 18 mov 0x18(%r13),%rax
#ifndef atomic_inc_unless_negative
static inline int atomic_inc_unless_negative(atomic_t *p)
{
int v, v1;
for (v = 0; v >= 0; v = v1) {
ffffffff8110964b: 31 d2 xor %edx,%edx
ffffffff8110964d: 4c 8b 60 30 mov 0x30(%rax),%r12
v1 = atomic_cmpxchg(p, v, v + 1);
ffffffff81109651: 8d 4a 01 lea 0x1(%rdx),%ecx
#define atomic_inc_return(v) (atomic_add_return(1, v))
#define atomic_dec_return(v) (atomic_sub_return(1, v))
static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
{
return cmpxchg(&v->counter, old, new);
ffffffff81109654: 89 d0 mov %edx,%eax
ffffffff81109656: f0 41 0f b1 8c 24 30 lock cmpxchg %ecx,0x130(%r12)
ffffffff8110965d: 01 00 00
if (likely(v1 == v))
ffffffff81109660: 39 d0 cmp %edx,%eax
ffffffff81109662: 0f 84 09 01 00 00 je ffffffff81109771 <do_last.isra.44+0x99e>
#ifndef atomic_inc_unless_negative
static inline int atomic_inc_unless_negative(atomic_t *p)
{
int v, v1;
for (v = 0; v >= 0; v = v1) {
ffffffff81109668: 85 c0 test %eax,%eax
ffffffff8110966a: 89 c2 mov %eax,%edx
ffffffff8110966c: 79 e3 jns ffffffff81109651 <do_last.isra.44+0x87e>
* use {get,deny}_write_access() - these functions check the sign and refuse
* to do the change if sign is wrong.
*/
static inline int get_write_access(struct inode *inode)
{
return atomic_inc_unless_negative(&inode->i_writecount) ? 0 : -ETXTBSY;
ffffffff8110966e: 41 be e6 ff ff ff mov $0xffffffe6,%r14d
ffffffff81109674: eb 6c jmp ffffffff811096e2 <do_last.isra.44+0x90f>
* but no group execute bit - an otherwise meaningless combination.
*/
static inline int __mandatory_lock(struct inode *ino)
{
return (ino->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID;
ffffffff81109676: 66 8b 00 mov (%rax),%ax
ffffffff81109679: 66 25 08 04 and $0x408,%ax
* otherwise these will be advisory locks
*/
static inline int mandatory_lock(struct inode *ino)
{
return IS_MANDLOCK(ino) && __mandatory_lock(ino);
ffffffff8110967d: 66 3d 00 04 cmp $0x400,%ax
ffffffff81109681: 0f 84 01 01 00 00 je ffffffff81109788 <do_last.isra.44+0x9b5>
*/
error = locks_verify_locked(filp);
if (!error)
error = security_path_truncate(path);
if (!error) {
error = do_truncate(path->dentry, 0,
ffffffff81109687: 49 8b 7d 18 mov 0x18(%r13),%rdi
ffffffff8110968b: 4c 89 e9 mov %r13,%rcx
ffffffff8110968e: ba 60 80 00 00 mov $0x8060,%edx
ffffffff81109693: 31 f6 xor %esi,%esi
ffffffff81109695: e8 1c 2a ff ff callq ffffffff810fc0b6 <do_truncate>
ffffffff8110969a: 41 89 c6 mov %eax,%r14d
*
* Atomically decrements @v by 1.
*/
static inline void atomic_dec(atomic_t *v)
{
asm volatile(LOCK_PREFIX "decl %0"
ffffffff8110969d: f0 41 ff 8c 24 30 01 lock decl 0x130(%r12)
ffffffff811096a4: 00 00
if (error)
goto exit_fput;
if (will_truncate) {
error = handle_truncate(file);
if (error)
ffffffff811096a6: 45 85 f6 test %r14d,%r14d
ffffffff811096a9: 75 37 jne ffffffff811096e2 <do_last.isra.44+0x90f>
goto exit_fput;
}
out:
if (got_write)
ffffffff811096ab: 80 7d ab 00 cmpb $0x0,-0x55(%rbp)
ffffffff811096af: 74 08 je ffffffff811096b9 <do_last.isra.44+0x8e6>
mnt_drop_write(nd->path.mnt);
ffffffff811096b1: 48 8b 3b mov (%rbx),%rdi
ffffffff811096b4: e8 cf bc 00 00 callq ffffffff81115388 <mnt_drop_write>
path_put(&save_parent);
ffffffff811096b9: 48 8d 7d c0 lea -0x40(%rbp),%rdi
ffffffff811096bd: e8 9b b9 ff ff callq ffffffff8110505d <path_put>
terminate_walk(nd);
ffffffff811096c2: 48 89 df mov %rbx,%rdi
ffffffff811096c5: e8 b8 b9 ff ff callq ffffffff81105082 <terminate_walk>
ffffffff811096ca: e9 dc 00 00 00 jmpq ffffffff811097ab <do_last.isra.44+0x9d8>
if (got_write) {
mnt_drop_write(nd->path.mnt);
got_write = false;
}
error = -EEXIST;
ffffffff811096cf: 41 be ef ff ff ff mov $0xffffffef,%r14d
path_put(&save_parent);
terminate_walk(nd);
return error;
exit_dput:
path_put_conditional(path, nd);
ffffffff811096d5: 48 89 de mov %rbx,%rsi
ffffffff811096d8: 4c 89 e7 mov %r12,%rdi
ffffffff811096db: e8 8b c4 ff ff callq ffffffff81105b6b <path_put_conditional.isra.28>
ffffffff811096e0: eb d7 jmp ffffffff811096b9 <do_last.isra.44+0x8e6>
goto out;
exit_fput:
fput(file);
ffffffff811096e2: 4c 89 ef mov %r13,%rdi
ffffffff811096e5: e8 0c 52 ff ff callq ffffffff810fe8f6 <fput>
ffffffff811096ea: eb bf jmp ffffffff811096ab <do_last.isra.44+0x8d8>
goto out;
stale_open:
/* If no saved parent or already retried then can't retry */
if (!save_parent.dentry || retried)
ffffffff811096ec: 48 8b 45 c8 mov -0x38(%rbp),%rax
ffffffff811096f0: 48 85 c0 test %rax,%rax
ffffffff811096f3: 74 b6 je ffffffff811096ab <do_last.isra.44+0x8d8>
ffffffff811096f5: 80 7d 92 00 cmpb $0x0,-0x6e(%rbp)
ffffffff811096f9: 75 b0 jne ffffffff811096ab <do_last.isra.44+0x8d8>
goto out;
BUG_ON(save_parent.dentry != dir);
ffffffff811096fb: 48 3b 45 80 cmp -0x80(%rbp),%rax
ffffffff811096ff: 74 02 je ffffffff81109703 <do_last.isra.44+0x930>
ffffffff81109701: 0f 0b ud2
path_put(&nd->path);
ffffffff81109703: 48 89 df mov %rbx,%rdi
ffffffff81109706: e8 52 b9 ff ff callq ffffffff8110505d <path_put>
nd->path = save_parent;
ffffffff8110970b: 48 8b 45 c8 mov -0x38(%rbp),%rax
ffffffff8110970f: 48 8b 7d c0 mov -0x40(%rbp),%rdi
nd->inode = dir->d_inode;
ffffffff81109713: 48 8b 55 80 mov -0x80(%rbp),%rdx
save_parent.mnt = NULL;
save_parent.dentry = NULL;
if (got_write) {
ffffffff81109717: 80 7d ab 00 cmpb $0x0,-0x55(%rbp)
BUG_ON(save_parent.dentry != dir);
path_put(&nd->path);
nd->path = save_parent;
nd->inode = dir->d_inode;
save_parent.mnt = NULL;
ffffffff8110971b: 48 c7 45 c0 00 00 00 movq $0x0,-0x40(%rbp)
ffffffff81109722: 00
save_parent.dentry = NULL;
ffffffff81109723: 48 c7 45 c8 00 00 00 movq $0x0,-0x38(%rbp)
ffffffff8110972a: 00
if (!save_parent.dentry || retried)
goto out;
BUG_ON(save_parent.dentry != dir);
path_put(&nd->path);
nd->path = save_parent;
ffffffff8110972b: 48 89 3b mov %rdi,(%rbx)
ffffffff8110972e: 48 89 43 08 mov %rax,0x8(%rbx)
nd->inode = dir->d_inode;
ffffffff81109732: 48 8b 42 30 mov 0x30(%rdx),%rax
save_parent.dentry = NULL;
if (got_write) {
mnt_drop_write(nd->path.mnt);
got_write = false;
}
retried = true;
ffffffff81109736: c6 45 92 01 movb $0x1,-0x6e(%rbp)
goto out;
BUG_ON(save_parent.dentry != dir);
path_put(&nd->path);
nd->path = save_parent;
nd->inode = dir->d_inode;
ffffffff8110973a: 48 89 43 30 mov %rax,0x30(%rbx)
save_parent.mnt = NULL;
save_parent.dentry = NULL;
if (got_write) {
ffffffff8110973e: 0f 84 c0 f7 ff ff je ffffffff81108f04 <do_last.isra.44+0x131>
mnt_drop_write(nd->path.mnt);
ffffffff81109744: e8 3f bc 00 00 callq ffffffff81115388 <mnt_drop_write>
ffffffff81109749: e9 b6 f7 ff ff jmpq ffffffff81108f04 <do_last.isra.44+0x131>
static inline int handle_dots(struct nameidata *nd, int type)
{
if (type == LAST_DOTDOT) {
if (nd->flags & LOOKUP_RCU) {
if (follow_dotdot_rcu(nd))
return -ECHILD;
ffffffff8110974e: 41 be f6 ff ff ff mov $0xfffffff6,%r14d
ffffffff81109754: eb 55 jmp ffffffff811097ab <do_last.isra.44+0x9d8>
bool got_write = false;
int acc_mode = op->acc_mode;
struct inode *inode;
bool symlink_ok = false;
struct path save_parent = { .dentry = NULL, .mnt = NULL };
bool retried = false;
ffffffff81109756: c6 45 92 00 movb $0x0,-0x6e(%rbp)
int open_flag = op->open_flag;
bool will_truncate = (open_flag & O_TRUNC) != 0;
bool got_write = false;
int acc_mode = op->acc_mode;
struct inode *inode;
bool symlink_ok = false;
ffffffff8110975a: c6 45 93 00 movb $0x0,-0x6d(%rbp)
ffffffff8110975e: e9 cd fd ff ff jmpq ffffffff81109530 <do_last.isra.44+0x75d>
if (error) { /* returned 1, that is */
if (WARN_ON(file->f_path.dentry == DENTRY_NOT_SET)) {
error = -EIO;
goto out;
}
if (file->f_path.dentry) {
ffffffff81109763: 48 85 c0 test %rax,%rax
ffffffff81109766: 0f 85 d2 f9 ff ff jne ffffffff8110913e <do_last.isra.44+0x36b>
ffffffff8110976c: e9 d9 f9 ff ff jmpq ffffffff8110914a <do_last.isra.44+0x377>
const struct inode_operations page_symlink_inode_operations = {
.readlink = generic_readlink,
.follow_link = page_follow_link_light,
.put_link = page_put_link,
};
EXPORT_SYMBOL(page_symlink_inode_operations);
ffffffff81109771: 49 8b 45 20 mov 0x20(%r13),%rax
ffffffff81109775: 48 8b 50 28 mov 0x28(%rax),%rdx
ffffffff81109779: f6 42 50 40 testb $0x40,0x50(%rdx)
ffffffff8110977d: 0f 85 f3 fe ff ff jne ffffffff81109676 <do_last.isra.44+0x8a3>
ffffffff81109783: e9 ff fe ff ff jmpq ffffffff81109687 <do_last.isra.44+0x8b4>
}
static inline int locks_verify_locked(struct file *file)
{
if (mandatory_lock(file_inode(file)))
return locks_mandatory_locked(file);
ffffffff81109788: 4c 89 ef mov %r13,%rdi
ffffffff8110978b: e8 52 0c 03 00 callq ffffffff8113a3e2 <locks_mandatory_locked>
return error;
/*
* Refuse to truncate files with mandatory locks held on them.
*/
error = locks_verify_locked(filp);
if (!error)
ffffffff81109790: 85 c0 test %eax,%eax
ffffffff81109792: 41 89 c6 mov %eax,%r14d
ffffffff81109795: 0f 85 02 ff ff ff jne ffffffff8110969d <do_last.isra.44+0x8ca>
ffffffff8110979b: e9 e7 fe ff ff jmpq ffffffff81109687 <do_last.isra.44+0x8b4>
}
if (should_follow_link(path->dentry, !symlink_ok)) {
if (nd->flags & LOOKUP_RCU) {
if (unlikely(unlazy_walk(nd, path->dentry))) {
error = -ECHILD;
ffffffff811097a0: 41 be f6 ff ff ff mov $0xfffffff6,%r14d
ffffffff811097a6: e9 0e ff ff ff jmpq ffffffff811096b9 <do_last.isra.44+0x8e6>
mnt_drop_write(nd->path.mnt);
got_write = false;
}
retried = true;
goto retry_lookup;
}
ffffffff811097ab: 48 83 c4 78 add $0x78,%rsp
ffffffff811097af: 44 89 f0 mov %r14d,%eax
ffffffff811097b2: 5b pop %rbx
ffffffff811097b3: 41 5c pop %r12
ffffffff811097b5: 41 5d pop %r13
ffffffff811097b7: 41 5e pop %r14
ffffffff811097b9: 41 5f pop %r15
ffffffff811097bb: 5d pop %rbp
ffffffff811097bc: c3 retq
^ permalink raw reply [flat|nested] 12+ messages in thread