| /* { dg-do compile } */ |
| /* { dg-additional-options "-std=gnu99" } */ |
| |
| struct thread_info { |
| struct task_struct *task; |
| }; |
| |
| static inline __attribute__((always_inline)) |
| __attribute__((no_instrument_function)) |
| struct thread_info *current_thread_info(void) |
| { |
| struct thread_info *ti; |
| |
| unsigned long __dummy; |
| |
| __asm__ __volatile__ ( |
| "mov r15, %0\n\t" |
| "and %1, %0\n\t" |
| : "=&r" (ti), "=r" (__dummy) |
| : "1" (~((1 << 13) - 1)) |
| : "memory"); |
| |
| return ti; |
| } |
| |
| typedef struct seqcount { |
| unsigned sequence; |
| } seqcount_t; |
| |
| struct inode; |
| |
| struct dentry { |
| seqcount_t d_seq; |
| struct inode *d_inode; |
| }; |
| |
| struct path { |
| struct vfsmount *mnt; |
| struct dentry *dentry; |
| }; |
| |
| struct file { |
| struct path f_path; |
| } __attribute__((aligned(4))); |
| |
| struct task_struct |
| { |
| int link_count, total_link_count; |
| struct fs_struct *fs; |
| }; |
| |
| struct fd { |
| struct file *file; |
| unsigned int flags; |
| }; |
| |
| static inline __attribute__((always_inline)) |
| __attribute__((no_instrument_function)) |
| struct fd |
| fdget_raw(unsigned int fd) |
| { |
| return (struct fd){(struct file *)(fd & ~3),fd & 3}; |
| } |
| |
| |
| struct fs_struct; |
| |
| struct nameidata { |
| struct path path; |
| struct path root; |
| struct inode *inode; |
| unsigned int flags; |
| unsigned seq, m_seq; |
| struct file *base; |
| }; |
| |
| int read_seqcount_retry(const seqcount_t *s, unsigned start); |
| |
| int |
| path_init(int dfd, const char *name, unsigned int flags, |
| struct nameidata *nd) |
| { |
| int retval = 0; |
| |
| if (*name=='/') { |
| nd->path = nd->root; |
| } else if (dfd == -100) { |
| |
| if (flags & 0x0040) { |
| struct fs_struct *fs = (current_thread_info()->task)->fs; |
| } |
| } else { |
| |
| struct fd f = fdget_raw(dfd); |
| struct dentry *dentry; |
| |
| if (!f.file) |
| return -9; |
| |
| dentry = f.file->f_path.dentry; |
| |
| nd->path = f.file->f_path; |
| if (flags & 0x0040) { |
| if (f.flags & 1) |
| nd->base = f.file; |
| } |
| } |
| |
| nd->inode = nd->path.dentry->d_inode; |
| if (!(flags & 0x0040)) |
| goto done; |
| if (__builtin_expect(!!(!read_seqcount_retry(&nd->path.dentry->d_seq, nd->seq)), 1)) |
| goto done; |
| if (!(nd->flags & 0x2000)) |
| nd->root.mnt = ((void *)0); |
| |
| return -10; |
| done: |
| (current_thread_info()->task)->total_link_count = 0; |
| return 0; |
| } |