aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
Commit message (Expand)AuthorAge
* [PATCH] show MCP menu only on ARCH_SA1100Adrian Bunk2006-03-24
* [PATCH] Add MCP bus_type probe and remove methodsRussell King2006-01-13
* [MMC+MFD] Convert mmc to mutexesArjan van de Ven2006-01-12
* [PATCH] drivers/mfd: header included twiceNicolas Kaiser2006-01-08
* [PATCH] IRQ type flagsRussell King2006-01-08
* [PATCH] input: fix ucb1x00-ts breakage after conversion to dynamic input_dev ...Nicolas Pitre2005-12-12
* [DRIVER MODEL] Convert platform drivers to use struct platform_driverRussell King2005-11-09
* [PATCH] fix remaining missing includesTim Schmielau2005-11-07
* Merge master.kernel.org:/home/rmk/linux-2.6-drvmodelLinus Torvalds2005-10-31
|\
| * Create platform_device.h to contain all the platform device details.Russell King2005-10-29
* | [ARM] Sharp sl-5500 touchscreen supportPavel Machek2005-10-30
|/
* [PATCH] DRIVER MODEL: Get rid of the obsolete tri-level suspend/resume callbacksRussell King2005-10-28
* [PATCH] Input: convert ucb1x00-ts to dynamic input_dev allocationDmitry Torokhov2005-10-28
* [ARM] 2956/1: fix the "Fix gcc4 build errors in ucb1x00-core.c"Nicolas Pitre2005-10-10
* [MFD] Fix gcc4 build errors in ucb1x00-core.cRussell King2005-10-06
* [MFD] Fix "bious one-bit signed bitfield" errorsRussell King2005-09-24
* [MFD] Cleanups suggested by Dmitri, Vojtech and lists.Pavel Machek2005-09-11
* [MFD] Add code UCB1200/UCB1300 assabet platform supportRussell King2005-09-11
* [MFD] Add code UCB1200/UCB1300 touchscreen supportRussell King2005-09-11
* [MFD] Add code UCB1200/UCB1300 device supportRussell King2005-09-11
* [MFD] Add SA11x0 MCP platform device supportRussell King2005-08-18
* [MFD] Add SA11x0 MCP supportRussell King2005-08-18
* [MFD] Add multimedia communication port core supportRussell King2005-08-18
f='/cgit/cgit.cgi/litmus-rt.git/commit/fs/statfs.c?h=test&id=7ed1ee6118ae77330cae2a6d5e9383532f7dfb48'>7ed1ee6118ae
c8b91accfa10


7ed1ee6118ae





c8b91accfa10

7ed1ee6118ae
c8b91accfa10

7ed1ee6118ae


c8b91accfa10











7ed1ee6118ae
c8b91accfa10

7ed1ee6118ae


c8b91accfa10
7ed1ee6118ae
c8b91accfa10


7ed1ee6118ae
c8b91accfa10











7ed1ee6118ae
c8b91accfa10

7ed1ee6118ae




c8b91accfa10



7ed1ee6118ae




c8b91accfa10

7ed1ee6118ae

c8b91accfa10


7ed1ee6118ae




c8b91accfa10



7ed1ee6118ae




c8b91accfa10
7ed1ee6118ae




c8b91accfa10


7ed1ee6118ae













ebabe9a9001a
7ed1ee6118ae









1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229



                           
                        




                           




































                                                        
                                                                
 











                                                         


                      

                                                      





                                                            
 

                          
                                                                
 







                                               
 









                                                      
 





                                                                        
              


                                                                        





                                                                            

                                                                  
                                                  

                                                                  


                                                  











                                                            
         

                                               


                 
                                                                     
 


                                              
              











                                                            
         

                                               




                                                                                   



                                                   




                                                                                                   

                          

                               


                                              




                                                                       



                                                   




                                                                                       
                          




                               


                                              













                                                                  
                                                 









                                                                            
#include <linux/syscalls.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/mount.h>
#include <linux/namei.h>
#include <linux/statfs.h>
#include <linux/security.h>
#include <linux/uaccess.h>

static int flags_by_mnt(int mnt_flags)
{
	int flags = 0;

	if (mnt_flags & MNT_READONLY)
		flags |= ST_RDONLY;
	if (mnt_flags & MNT_NOSUID)
		flags |= ST_NOSUID;
	if (mnt_flags & MNT_NODEV)
		flags |= ST_NODEV;
	if (mnt_flags & MNT_NOEXEC)
		flags |= ST_NOEXEC;
	if (mnt_flags & MNT_NOATIME)
		flags |= ST_NOATIME;
	if (mnt_flags & MNT_NODIRATIME)
		flags |= ST_NODIRATIME;
	if (mnt_flags & MNT_RELATIME)
		flags |= ST_RELATIME;
	return flags;
}

static int flags_by_sb(int s_flags)
{
	int flags = 0;
	if (s_flags & MS_SYNCHRONOUS)
		flags |= ST_SYNCHRONOUS;
	if (s_flags & MS_MANDLOCK)
		flags |= ST_MANDLOCK;
	return flags;
}

static int calculate_f_flags(struct vfsmount *mnt)
{
	return ST_VALID | flags_by_mnt(mnt->mnt_flags) |
		flags_by_sb(mnt->mnt_sb->s_flags);
}

int statfs_by_dentry(struct dentry *dentry, struct kstatfs *buf)
{
	int retval;

	if (!dentry->d_sb->s_op->statfs)
		return -ENOSYS;

	memset(buf, 0, sizeof(*buf));
	retval = security_sb_statfs(dentry);
	if (retval)
		return retval;
	retval = dentry->d_sb->s_op->statfs(dentry, buf);
	if (retval == 0 && buf->f_frsize == 0)
		buf->f_frsize = buf->f_bsize;
	return retval;
}

int vfs_statfs(struct path *path, struct kstatfs *buf)
{
	int error;

	error = statfs_by_dentry(path->dentry, buf);
	if (!error)
		buf->f_flags = calculate_f_flags(path->mnt);
	return error;
}
EXPORT_SYMBOL(vfs_statfs);

int user_statfs(const char __user *pathname, struct kstatfs *st)
{
	struct path path;
	int error = user_path(pathname, &path);
	if (!error) {
		error = vfs_statfs(&path, st);
		path_put(&path);
	}
	return error;
}

int fd_statfs(int fd, struct kstatfs *st)
{
	struct file *file = fget(fd);
	int error = -EBADF;
	if (file) {
		error = vfs_statfs(&file->f_path, st);
		fput(file);
	}
	return error;
}

static int do_statfs_native(struct kstatfs *st, struct statfs __user *p)
{
	struct statfs buf;

	if (sizeof(buf) == sizeof(*st))
		memcpy(&buf, st, sizeof(*st));
	else {
		if (sizeof buf.f_blocks == 4) {
			if ((st->f_blocks | st->f_bfree | st->f_bavail |
			     st->f_bsize | st->f_frsize) &
			    0xffffffff00000000ULL)
				return -EOVERFLOW;
			/*
			 * f_files and f_ffree may be -1; it's okay to stuff
			 * that into 32 bits
			 */
			if (st->f_files != -1 &&
			    (st->f_files & 0xffffffff00000000ULL))
				return -EOVERFLOW;
			if (st->f_ffree != -1 &&
			    (st->f_ffree & 0xffffffff00000000ULL))
				return -EOVERFLOW;
		}

		buf.f_type = st->f_type;
		buf.f_bsize = st->f_bsize;
		buf.f_blocks = st->f_blocks;
		buf.f_bfree = st->f_bfree;
		buf.f_bavail = st->f_bavail;
		buf.f_files = st->f_files;
		buf.f_ffree = st->f_ffree;
		buf.f_fsid = st->f_fsid;
		buf.f_namelen = st->f_namelen;
		buf.f_frsize = st->f_frsize;
		buf.f_flags = st->f_flags;
		memset(buf.f_spare, 0, sizeof(buf.f_spare));
	}
	if (copy_to_user(p, &buf, sizeof(buf)))
		return -EFAULT;
	return 0;
}

static int do_statfs64(struct kstatfs *st, struct statfs64 __user *p)
{
	struct statfs64 buf;
	if (sizeof(buf) == sizeof(*st))
		memcpy(&buf, st, sizeof(*st));
	else {
		buf.f_type = st->f_type;
		buf.f_bsize = st->f_bsize;
		buf.f_blocks = st->f_blocks;
		buf.f_bfree = st->f_bfree;
		buf.f_bavail = st->f_bavail;
		buf.f_files = st->f_files;
		buf.f_ffree = st->f_ffree;
		buf.f_fsid = st->f_fsid;
		buf.f_namelen = st->f_namelen;
		buf.f_frsize = st->f_frsize;
		buf.f_flags = st->f_flags;
		memset(buf.f_spare, 0, sizeof(buf.f_spare));
	}
	if (copy_to_user(p, &buf, sizeof(buf)))
		return -EFAULT;
	return 0;
}

SYSCALL_DEFINE2(statfs, const char __user *, pathname, struct statfs __user *, buf)
{
	struct kstatfs st;
	int error = user_statfs(pathname, &st);
	if (!error)
		error = do_statfs_native(&st, buf);
	return error;
}

SYSCALL_DEFINE3(statfs64, const char __user *, pathname, size_t, sz, struct statfs64 __user *, buf)
{
	struct kstatfs st;
	int error;
	if (sz != sizeof(*buf))
		return -EINVAL;
	error = user_statfs(pathname, &st);
	if (!error)
		error = do_statfs64(&st, buf);
	return error;
}

SYSCALL_DEFINE2(fstatfs, unsigned int, fd, struct statfs __user *, buf)
{
	struct kstatfs st;
	int error = fd_statfs(fd, &st);
	if (!error)
		error = do_statfs_native(&st, buf);
	return error;
}

SYSCALL_DEFINE3(fstatfs64, unsigned int, fd, size_t, sz, struct statfs64 __user *, buf)
{
	struct kstatfs st;
	int error;

	if (sz != sizeof(*buf))
		return -EINVAL;

	error = fd_statfs(fd, &st);
	if (!error)
		error = do_statfs64(&st, buf);
	return error;
}

SYSCALL_DEFINE2(ustat, unsigned, dev, struct ustat __user *, ubuf)
{
	struct super_block *s;
	struct ustat tmp;
	struct kstatfs sbuf;
	int err;

	s = user_get_super(new_decode_dev(dev));
	if (!s)
		return -EINVAL;

	err = statfs_by_dentry(s->s_root, &sbuf);
	drop_super(s);
	if (err)
		return err;

	memset(&tmp,0,sizeof(struct ustat));
	tmp.f_tfree = sbuf.f_bfree;
	tmp.f_tinode = sbuf.f_ffree;

	return copy_to_user(ubuf, &tmp, sizeof(struct ustat)) ? -EFAULT : 0;
}