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