[GFS2] Fix build warnings
[safe/jmp/linux-2.6] / fs / gfs2 / eaops.c
1 /*
2  * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
3  * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
4  *
5  * This copyrighted material is made available to anyone wishing to use,
6  * modify, copy, or redistribute it subject to the terms and conditions
7  * of the GNU General Public License version 2.
8  */
9
10 #include <linux/slab.h>
11 #include <linux/spinlock.h>
12 #include <linux/completion.h>
13 #include <linux/buffer_head.h>
14 #include <linux/capability.h>
15 #include <linux/xattr.h>
16 #include <linux/gfs2_ondisk.h>
17 #include <linux/lm_interface.h>
18 #include <asm/uaccess.h>
19
20 #include "gfs2.h"
21 #include "incore.h"
22 #include "acl.h"
23 #include "eaops.h"
24 #include "eattr.h"
25 #include "util.h"
26
27 /**
28  * gfs2_ea_name2type - get the type of the ea, and truncate type from the name
29  * @namep: ea name, possibly with type appended
30  *
31  * Returns: GFS2_EATYPE_XXX
32  */
33
34 unsigned int gfs2_ea_name2type(const char *name, const char **truncated_name)
35 {
36         unsigned int type;
37
38         if (strncmp(name, "system.", 7) == 0) {
39                 type = GFS2_EATYPE_SYS;
40                 if (truncated_name)
41                         *truncated_name = name + sizeof("system.") - 1;
42         } else if (strncmp(name, "user.", 5) == 0) {
43                 type = GFS2_EATYPE_USR;
44                 if (truncated_name)
45                         *truncated_name = name + sizeof("user.") - 1;
46         } else if (strncmp(name, "security.", 9) == 0) {
47                 type = GFS2_EATYPE_SECURITY;
48                 if (truncated_name)
49                         *truncated_name = name + sizeof("security.") - 1;
50         } else {
51                 type = GFS2_EATYPE_UNUSED;
52                 if (truncated_name)
53                         *truncated_name = NULL;
54         }
55
56         return type;
57 }
58
59 static int user_eo_get(struct gfs2_inode *ip, struct gfs2_ea_request *er)
60 {
61         return gfs2_ea_get_i(ip, er);
62 }
63
64 static int user_eo_set(struct gfs2_inode *ip, struct gfs2_ea_request *er)
65 {
66         return gfs2_ea_set_i(ip, er);
67 }
68
69 static int user_eo_remove(struct gfs2_inode *ip, struct gfs2_ea_request *er)
70 {
71         return gfs2_ea_remove_i(ip, er);
72 }
73
74 static int system_eo_get(struct gfs2_inode *ip, struct gfs2_ea_request *er)
75 {
76         if (!GFS2_ACL_IS_ACCESS(er->er_name, er->er_name_len) &&
77             !GFS2_ACL_IS_DEFAULT(er->er_name, er->er_name_len) &&
78             !capable(CAP_SYS_ADMIN))
79                 return -EPERM;
80
81         if (GFS2_SB(&ip->i_inode)->sd_args.ar_posix_acl == 0 &&
82             (GFS2_ACL_IS_ACCESS(er->er_name, er->er_name_len) ||
83              GFS2_ACL_IS_DEFAULT(er->er_name, er->er_name_len)))
84                 return -EOPNOTSUPP;
85
86         return gfs2_ea_get_i(ip, er);
87 }
88
89 static int system_eo_set(struct gfs2_inode *ip, struct gfs2_ea_request *er)
90 {
91         int remove = 0;
92         int error;
93
94         if (GFS2_ACL_IS_ACCESS(er->er_name, er->er_name_len)) {
95                 if (!(er->er_flags & GFS2_ERF_MODE)) {
96                         er->er_mode = ip->i_inode.i_mode;
97                         er->er_flags |= GFS2_ERF_MODE;
98                 }
99                 error = gfs2_acl_validate_set(ip, 1, er,
100                                               &remove, &er->er_mode);
101                 if (error)
102                         return error;
103                 error = gfs2_ea_set_i(ip, er);
104                 if (error)
105                         return error;
106                 if (remove)
107                         gfs2_ea_remove_i(ip, er);
108                 return 0;
109
110         } else if (GFS2_ACL_IS_DEFAULT(er->er_name, er->er_name_len)) {
111                 error = gfs2_acl_validate_set(ip, 0, er,
112                                               &remove, NULL);
113                 if (error)
114                         return error;
115                 if (!remove)
116                         error = gfs2_ea_set_i(ip, er);
117                 else {
118                         error = gfs2_ea_remove_i(ip, er);
119                         if (error == -ENODATA)
120                                 error = 0;
121                 }
122                 return error;
123         }
124
125         return -EPERM;
126 }
127
128 static int system_eo_remove(struct gfs2_inode *ip, struct gfs2_ea_request *er)
129 {
130         if (GFS2_ACL_IS_ACCESS(er->er_name, er->er_name_len)) {
131                 int error = gfs2_acl_validate_remove(ip, 1);
132                 if (error)
133                         return error;
134
135         } else if (GFS2_ACL_IS_DEFAULT(er->er_name, er->er_name_len)) {
136                 int error = gfs2_acl_validate_remove(ip, 0);
137                 if (error)
138                         return error;
139
140         } else
141                 return -EPERM;
142
143         return gfs2_ea_remove_i(ip, er);
144 }
145
146 static int security_eo_get(struct gfs2_inode *ip, struct gfs2_ea_request *er)
147 {
148         return gfs2_ea_get_i(ip, er);
149 }
150
151 static int security_eo_set(struct gfs2_inode *ip, struct gfs2_ea_request *er)
152 {
153         return gfs2_ea_set_i(ip, er);
154 }
155
156 static int security_eo_remove(struct gfs2_inode *ip, struct gfs2_ea_request *er)
157 {
158         return gfs2_ea_remove_i(ip, er);
159 }
160
161 static const struct gfs2_eattr_operations gfs2_user_eaops = {
162         .eo_get = user_eo_get,
163         .eo_set = user_eo_set,
164         .eo_remove = user_eo_remove,
165         .eo_name = "user",
166 };
167
168 const struct gfs2_eattr_operations gfs2_system_eaops = {
169         .eo_get = system_eo_get,
170         .eo_set = system_eo_set,
171         .eo_remove = system_eo_remove,
172         .eo_name = "system",
173 };
174
175 static const struct gfs2_eattr_operations gfs2_security_eaops = {
176         .eo_get = security_eo_get,
177         .eo_set = security_eo_set,
178         .eo_remove = security_eo_remove,
179         .eo_name = "security",
180 };
181
182 const struct gfs2_eattr_operations *gfs2_ea_ops[] = {
183         NULL,
184         &gfs2_user_eaops,
185         &gfs2_system_eaops,
186         &gfs2_security_eaops,
187 };
188