1 /* { dg-do compile } */
2 /* { dg-additional-options "-std=gnu99" } */
3
4 struct thread_info {
5 struct task_struct *task;
6 };
7
8 static inline __attribute__((always_inline))
9 __attribute__((no_instrument_function))
current_thread_info(void)10 struct thread_info *current_thread_info(void)
11 {
12 struct thread_info *ti;
13
14 unsigned long __dummy;
15
16 __asm__ __volatile__ (
17 "mov r15, %0\n\t"
18 "and %1, %0\n\t"
19 : "=&r" (ti), "=r" (__dummy)
20 : "1" (~((1 << 13) - 1))
21 : "memory");
22
23 return ti;
24 }
25
26 typedef struct seqcount {
27 unsigned sequence;
28 } seqcount_t;
29
30 struct inode;
31
32 struct dentry {
33 seqcount_t d_seq;
34 struct inode *d_inode;
35 };
36
37 struct path {
38 struct vfsmount *mnt;
39 struct dentry *dentry;
40 };
41
42 struct file {
43 struct path f_path;
44 } __attribute__((aligned(4)));
45
46 struct task_struct
47 {
48 int link_count, total_link_count;
49 struct fs_struct *fs;
50 };
51
52 struct fd {
53 struct file *file;
54 unsigned int flags;
55 };
56
57 static inline __attribute__((always_inline))
58 __attribute__((no_instrument_function))
59 struct fd
fdget_raw(unsigned int fd)60 fdget_raw(unsigned int fd)
61 {
62 return (struct fd){(struct file *)(fd & ~3),fd & 3};
63 }
64
65
66 struct fs_struct;
67
68 struct nameidata {
69 struct path path;
70 struct path root;
71 struct inode *inode;
72 unsigned int flags;
73 unsigned seq, m_seq;
74 struct file *base;
75 };
76
77 int read_seqcount_retry(const seqcount_t *s, unsigned start);
78
79 int
path_init(int dfd,const char * name,unsigned int flags,struct nameidata * nd)80 path_init(int dfd, const char *name, unsigned int flags,
81 struct nameidata *nd)
82 {
83 int retval = 0;
84
85 if (*name=='/') {
86 nd->path = nd->root;
87 } else if (dfd == -100) {
88
89 if (flags & 0x0040) {
90 struct fs_struct *fs = (current_thread_info()->task)->fs;
91 }
92 } else {
93
94 struct fd f = fdget_raw(dfd);
95 struct dentry *dentry;
96
97 if (!f.file)
98 return -9;
99
100 dentry = f.file->f_path.dentry;
101
102 nd->path = f.file->f_path;
103 if (flags & 0x0040) {
104 if (f.flags & 1)
105 nd->base = f.file;
106 }
107 }
108
109 nd->inode = nd->path.dentry->d_inode;
110 if (!(flags & 0x0040))
111 goto done;
112 if (__builtin_expect(!!(!read_seqcount_retry(&nd->path.dentry->d_seq, nd->seq)), 1))
113 goto done;
114 if (!(nd->flags & 0x2000))
115 nd->root.mnt = ((void *)0);
116
117 return -10;
118 done:
119 (current_thread_info()->task)->total_link_count = 0;
120 return 0;
121 }
122