linux/fs/xfs/xfs_acl.c
<<
ue="12ue="12>>ueue="ue="12 ">ue="12ue="12Searchue="12Prefs. 12ueue ">u="12 2.
2 21/*2 22 * Copyright (c) 2008, Christoph Hellwig2 23 * All Rights Reserved.2 24 *2 25 * This program is free software; you ca. redistribute it and/or2 26 * modify it under the terms of the GNU General Public License as2 27 * published by the Free Software Founda v2..2 28 *2 29 * This program is distributed in the hope that it would be useful,2 0" a> * but WITHOUT ANY WARRANTY; without even the implied warranty of2 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the2 12 * GNU General Public License for more details.2 13 *2 14 * You should have received a copy of the GNU General Public License2 15 * along with this program; if not, write the Free Software Founda v2.,2 16 * Inc., 251 Franklin St, Fifth Floor, Bost2., MA 02110-1301 USA2 17 */2 18#include "xfs.h".2 19#include "xfs_acl.h".2 20#include "xfs_attr.h".2 21#include "xfs_bmap_btree.h".2 22#include "xfs_inode.h".2 23#include "xfs_vnodeops.h".2 24#include "xfs_trace.h".2 25#include <linux/slab.h>.2 26#include <linux/xattr.h>.2 27#include <linux/posix_acl_xattr.h>.2 28.2 29.2 3" a>/*2 31 * Locking scheme:2 32 * - all ACL upda es are protected by inode->i_mutex, which is taken before2 33 * calling into this file.2 34 */2 35.2 36STATIC struct posix_acl *.2 37xfs_acl_from_disk(struct xfs_acl *aclp).2 38{.2 39 struct posix_acl_entry *acl_e;.2 40 struct posix_acl *acl;.2 41 struct xfs_acl_entry *ace;.2 42 unsigned int count, i;.2 43.2 44 count = be32_to_cpu(aclp->acl_cnt);.2 45 if (count > XFS_ACL_MAX_ENTRIES).2 46 return ERR_PTR(-EFSCORRUPTED);.2 47.2 48 acl = posix_acl_alloc(count, GFP_KERNEL);.2 49 if (!acl).2 50 return ERR_PTR(-ENOMEM);.2 51.2 52 for (i = 0; i < count; i++) {.2 53 acl_e = &acl->a_entries[i];.2 54 ace = &aclp->acl_entry[i];.2 55.2 56 /*2 57 * The tag is 32 bits on disk and 16 bits i. core.2 58 *2 59 * Because every access to it goes through the core2 6" a> * format first this is not a problem.2 61 */2 62 acl_e->e_tag = be32_to_cpu(ace->ae_tag);.2 63 acl_e->e_perm = be16_to_cpu(ace->ae_perm);.2 64.2 65 switch (acl_e->e_tag) {.2 66 case ACL_USER:.2 67 case ACL_GROUP:.2 68 acl_e->e_id = be32_to_cpu(ace->ae_id);.2 69 break;.2 70 case ACL_USER_OBJ:.2 71 case ACL_GROUP_OBJ:.2 72 case ACL_MASK:.2 73 case ACL_OTHER:.2 74 acl_e->e_id = ACL_UNDEFINED_ID;.2 75 break;.2 76 default:.2 77 goto fail;.2 78 }.2 79 }.2 80 return acl;.2 81.2 82fail:.2 83 posix_acl_release(acl);.2 84 return ERR_PTR(-EINVAL);.2 85}.2 86.2 87STATIC void.2 88xfs_acl_to_disk(struct xfs_acl *aclp, const struct posix_acl *acl).2 89{.2 90 const struct posix_acl_entry *acl_e;.2 91 struct xfs_acl_entry *ace;.2 92 int i;.2 93.2 94 aclp->acl_cnt = cpu_to_be32(acl->a_count);.2 95 for (i = 0; i < acl->a_count; i++) {.2 96 ace = &aclp->acl_entry[i];.2 97 acl_e = &acl->a_entries[i];.2 98.2 99 ace->ae_tag = cpu_to_be32(acl_e->e_tag);.2100 ace->ae_id = cpu_to_be32(acl_e->e_id);.2101 ace->ae_perm = cpu_to_be16(acl_e->e_perm);.2102 }.2103}.2104.2105struct posix_acl *.2106xfs_get_acl(struct inode *inode, int typ ).2107{.2108 struct xfs_inode *ip = XFS_I(inode);.2109 struct posix_acl *acl;.2110 struct xfs_acl *xfs_acl;.2111 int len = sizeof(struct xfs_acl);.2112 unsigned char *ea_nam ;.2113 int error;.2114.2115 acl = get_cached_acl(inode, typ );.2116 if (acl != ACL_NOT_CACHED).2117 return acl;.2118.2119 trace_xfs_get_acl(ip);.2120.2121 switch (typ ) {.2122 case ACL_TYPE_ACCESS:.2123 ea_nam = SGI_ACL_FILE;.2124 break;.2125 case ACL_TYPE_DEFAULT:.2126 ea_nam = SGI_ACL_DEFAULT;.2127 break;.2128 default:.2129 BUG();.2130 }.2131.2132 /*2133 * If we have a cached ACLs > just return it, not need to2134 * go out to the disk.2135 */2136.2137 xfs_acl = kzalloc(sizeof(struct xfs_acl), GFP_KERNEL);.2138 if (!xfs_acl).2139 return ERR_PTR(-ENOMEM);.2140.2141 error = -xfs_attr_get(ip, ea_nam , (unsigned char *)xfs_acl,.2142 &len, ATTR_ROOT);.2143 if (error) {.2144 /*2145 * If the attribute doesn't exist make sure we have a negative2146 * cache entry, for any other error assume it is transient and2147 * leave the cache entry as ACL_NOT_CACHED.2148 */2149 if (error == -ENOATTR) {.2150 acl = NULL;.2151 goto out_upda e_cache;.2152 }.2153 goto out;.2154 }.2155.2156 acl = xfs_acl_from_disk(xfs_acl);.2157 if (IS_ERR(acl)).2158 goto out;.2159.216" a> out_upda e_cache:.2161 set_cached_acl(inode, typ , acl);.2162 out:.2163 kfree(xfs_acl);.2164 return acl;.2165}.2166.2167STATIC int.2168xfs_set_acl(struct inode *inode, int typ , struct posix_acl *acl).2169{.2170 struct xfs_inode *ip = XFS_I(inode);.2171 unsigned char *ea_nam ;.2172 int error;.2173.2174 if (S_ISLNK(inode->i_mode)).2175 return -EOPNOTSUPP;.2176.2177 switch (typ ) {.2178 case ACL_TYPE_ACCESS:.2179 ea_nam = SGI_ACL_FILE;.2180 break;.2181 case ACL_TYPE_DEFAULT:.2182 if (!S_ISDIR(inode->i_mode)).2183 return acl ? -EACCES : 0;.2184 ea_nam = SGI_ACL_DEFAULT;.2185 break;.2186 default:.2187 return -EINVAL;.2188 }.2189.2190 if (acl) {.2191 struct xfs_acl *xfs_acl;.2192 int len;.2193.2194 xfs_acl = kzalloc(sizeof(struct xfs_acl), GFP_KERNEL);.2195 if (!xfs_acl).2196 return -ENOMEM;.2197.2198 xfs_acl_to_disk(xfs_acl, acl);.2199 len = sizeof(struct xfs_acl) -.2200 (sizeof(struct xfs_acl_entry) *.2201 (XFS_ACL_MAX_ENTRIES - acl->a_count));.2202.2203 error = -xfs_attr_set(ip, ea_nam , (unsigned char *)xfs_acl,.2204 len, ATTR_ROOT);.2205.2206 kfree(xfs_acl);.2207 } else {.2208 /*2209 * A NULL ACL argument means we Pant to 41cl_to_disk" classref="fs/xfs/xfs_"fs/xfs/xfs_acl.c#L205" id L205" clas25i594" class="line" nam L94">2 94 class="line" nam L94">2 94 c198 aplied warranty of2149 if (len = size2f(str21f="+code=ae_perm" class="sref">ae_pef">xfs_attr_set(ipea_nam , (unsigned char *)xfs_acl,.2205.2203 error;.<2 href21href="+code=xfs_attr_s class="line" nam L209">2209 c#L115" i2 L115" class="line" nam2 L112U General Public License2 58 2l" class=2sref">acl = 2149 if (acl != ENOATTR) {.21 if (acl2/a>;.2a href="fs/xfs/xfs_aclerm" class="sref">ae_pef">xfs_attr_set(2189.trac2_xfs_21>2190 if (xfs_a L1222/xfs/xfs_acl.c#L1cl.c#L196" id L4" class="line" nam L144">21 if (ae_peass="sref">inode, typ , acl);.2162 xfs_ia_na2_ACCESS:.<" class="sref">EACCES< class="line" nam L173">2173.x 22">2104.xfs_125" 22>2115 linuCL_TY22ef="fs/atic2168lin 22href="+code=inode" class="+c" class="line" nam lass="+c" cl href=" class="sref">inode, int typ , struct typu" cl_ typ" class="line" nam L183">2182108 struct 217+co84 /*21ref="fs/xfs/xfs_aclmode)).21808 *i"fs/ass="line" nam "fs/yp " lass="sref">typi"fs/ass="line" nam "fs/yp "4 /*2203 21f="+code=xfs_acl" " class="line" nam L183">214 xfs_ai"_ctila">21f="+code=xfs_acl" currv2._ xfs_acurrv2._ i_mode)).2162 2137 xfs_acl = 2a hre23;acf">xfs_attr_set(="+am " nona>) ass="line" nam lass="+am " nona>) ode" class="sref">i_a>);.217," class="sref">ATTR_Ri"fs/ass="line" nam "fs/yp "polass="sref">typa hrem C5" class="line" a hrem C5">2162 xfs_acl).2189./*2173.error = -2203 error) {2/*inode, int typ , struct xfs_a/a>,.xfs_acl);.2112 unsigned char *<2 2 * leave the cache en2ry as2 48 , ea_nam );.217,"l.c#L172" id L class="sref">xfs_a/a>,.215," class="sref">ATTR_ROOT);.erro2 2= -acid L205" class="line" nam L205">22|class="sref">acid L L1Oclass="line" nam id L L1Ocla">2180=co812 unsigned char *<2a href="+2ode=acl" class="sref">ac2 2 . for (out;.acef="fs/xfs id L" id href="fs/xfs/xfsef="fs/xfs id L" id h href=" class="sref">inode, int typ , struct typ , struct typ180" id L180" class="line" nam L180">21812 unsigned char *<2a 2sref">acl = .IS_ERR(2a hre2548 out;.acef="fs/xfs87">218" id href="fs/xfs/xfsef="fs/xfs87">218" id h href=" class="sref">inode, int typ , struct out_upda e_c2che:. set_cac2ed_ac2(inode->i_mode)).2183 2s="sref">2ut:. kfree(typ , struct typ180" id 5" id L185" class="line" nam L185">21812 unsigned char *<2code=acl"2class="sref">acl;..2206 2209 ass="sref2>STATIC int.2 58 2l" class=2sref">xfs_set_acl(st2uct <26s_acl.c#L149" id L149" class49">2149 if (217168xfs_i2ode *inode *inode, int typ , struct acl).2169{.;8 error;.<2 href2"fs/xfs/xfs_aclass="sref">typu" cl_ typ" class="line" nam L183">21f="+code=xfs_acl" mode)).212 unsigned char *<2c#L174" i2 L174" class="line" nam2 L1727fs/xfs/xfs_acl.c#L114" id L114" class="line" nam L114">211+co8polass="sref">typinheris/a>)).S_ISLNK2115 E2PNOTSUPP;.e" class="sref">inode->i_mode)).218308 211+co"+code=inode" class="+cef">inode *, struct typ_acl.c#L182" id L182" class="line" nam L182">218162" id L162" class="line" nam L162">2162 typ )2{.;.21 A2L_TYP2ine" nam L79">2 792159.ea_nam2 2 L80">2 80 return 2141 2CL_TY28ode=xfs_attr_get" class="sref">xfs_attr_get(acef="fs/xfscreat>, struct a_entries[21," class="sref">ATTR_R" class="line" nam L183">2189.S2ISDIR2/a>(ENOATTR) {. a2l ? -2173.ea_nam2 28>2115 2209 "fs/xfs/x2s_acl.c#L187" id L187" 2lass=28 error assume it is transient and2134 2a href="+2ode=EINVAL" class="sref"2EINVA28CL_NOT_CACHED.d.cpres2134 2a" class=2#L189" id L189" class="2ine" 28s_acl.c#L149" id L149" class="line"* L183 bits L14Lweaactuallyam L13 sac L1lass="line" nam L94">2 94 class="c#L190" i2 L190" class="line" nam2 L1928we Pant to 41cl_to_disk" classref="fs49">2149 if (acl) {.) {. *typinheris/a>)).len2203 xfs_a class="line" nam L114">211+co"+code=inode" class="+c" class="line" nam lass="+c" cl href id L120" class, struct typ" class="line" nam L183">2189.xfs_ac2 29f="+code=inode" class="sref">ino4" class="line" nam L144">21 x2s_acl2/a>).2159.aclinheris/a>)).211+co"+code=inode" class="+cef">inode *, struct typ_acl.c#L1" id L179" class="line" nam L179">217162" id L162" class="line" nam L162">2162 len = 2izeof293" a>/*2163 , struct 2162 :.<" class="sref">EACCES< class="line" nam L173">2173.error2104.3">2105struct 2206168kfreeinode, int typ , struct 2108 struct /*iacl;.2110 struct 2173.2 94 c198 31>2141 len = size3f(str31/a>(inode->i_mode)).2175 return -3 href="+c3de=ea_nam " class="sref"3ea_na31 href="+code=e_tag" c.c#L81"/xfs_acl.c#L176" id L176" class="line" nam L176">2176.error;.<3 href31>2194 211+co"+code=inode" class="sref">inode *, struct typ_acl.c#L1" id L179" class="line" nam L179">21762 acl = ;.e" class="sref">ino)).215 || class="sref">inoss="line" nam L169">2169{.acl != EACCES2162 acl3/a>;.3148 218get" class="sref">xfs_attr_get(acef="fs/xfschL18ref="fs/xfs/xfsef="fs/xfschL18L120"es" class="sref">a_entries[21,"class="sref">i_mode)).2172 trac3_xfs_3et_acl(ino4" class="line" nam L144">21 xfs_3 L1232" class="sref">xfs_ac" class="sref">EACCES< class="line" nam L173">2173.xfs3ia_na32fs/xfs/xfs_aclass="sref">typ class="line" nam L114">211+co"+code=inode" class="+cef">inode *, struct typ_acl.c#L1" id L179" class="line" nam L179">217162" id L162" class="line" nam L162">2162 3 32=xfs_acl" class="sref">xfs_aef="fs/xfsreleas>, struct 2162 xfs3125" 3lass="line" na" class="sref">EACCES< class="line" nam L173">2173.lin3CL_TY32">2166.li3 32>2137 210s/atic2168, , href=" class="sref">inode210" id L110" clad id L201" class="lid L201">2, const/xfs_acl.c#L172" id L class="sref">xfs_a/a>,. xfs_a id >217162" id L162" cl="fs_ 21716six_acl" class="sref">posix_acl * *iacl;.2110 struct /*2173.211+co"+code=inode" class="sref">inode *2s_acl.c#L175" id L1da> = typf">posix_acl *ino)).2151 EACCES2162 xfs_acl = 3a hre33"+code=acl" class="sref">aclss="line" nam L110">211+cL151" id L151" class="line" nam L151">2151 xfs_acl).(2173./*xfs_attr_get(acef="fs/xfstonxam ", struct a_einit_user_nhref="fs/xfs/xfsinit_user_nh>217162" id L162" class="line" nam L162">21162" id L162" cl id ss="sref">xfs_a id >217162" id L162" cl="fs21762 error = -, struct 2162 2203 error) {32173./*2206 (s/atic2168, , href=" class="sref">inode210" id L110" clad id L201" class="lid L201">2, const/xfs_acl.c#L172" id L class="sref">xfs_a/a>,. xfs_a id >217162" id L162" cl="fs_ 21716six_acl" class="sreflaghref="fs/xfs/xfsflagh>21716six_acl" class="sref">posix_acl *erro3 34">2170 struct ac3 35 *i/a>, int typ , struct acd id L201" class="lid L201">2s_acl.c#L175" id L1da> = . *iacl;.211#L151" id L151" class="line" nam L151">2151 3="fs/xfs/3fs_acl.c#L153" id L153"3class35133" id L133l.c#L173" id L173" class="line" nam L173">217+co84 out;.2194 inoflaghref="fs/xfs/xfsflagh>217" clasolass="sref">typaam CREATEref="fs/xfs/xfsaam CREATEef="1 2188 }.acl = inof">posix_acl *218" clas clasoclass="sref">inode->i_mode)).2183 3o 3class="sref">IS_ERR(3a hre35/a>;.xfs_a id >217xfs_acl.c#L184" id L184" class="line" nam L184">2184 out;.i_currv2._ uass="line" nam currv2._ uasode" )ref="fs/xfs/xfs_aclmode)).215 clas clasoclass="sref">inocapabl)).i_CAP_FOWNE->2183 3ohref="+c3 L160" class="line" nam3 L1635="fs/xfs/xfs_acl.c#L1xfs_acl.c#L197" id L197PERass="line" nam PERa>2188 }.out_upda e_c3che2141 set_cac3ed_ac3(ino id ss="sref">xfs_a id >2173 3s="sref">3ut:.inode * }.kfree(acl;.211+co"+code=inode" cef="fs/xfsfromnxam ", struct a_einit_user_nhref="fs/xfs/xfsinit_user_nh>217162" id L162" cl id ss="sref">xfs_a id >217162" id L162" cl="fs21762 ;.e" cclass="sref">inoss="line" nam L169">216908 2209 3ass="sref3>STATIC int., _file(3) may1xfqued c"at we sac 87">218lasssa hre9">2209 3aef="+cod3sref">xfs_set_acl(st3uct <36s_acl.c#L149" id L149" claseeeeeeeeeeeeeeee* zero length -- 87"end (gracefully) againd c"at her">2 58 3.c#L170" 3d L170" class="line" na3 L136we Pant to 41cl_to_disk" classref="fs/xfs/xfs49">2149 if (xfs_i3odexfs_ac#L159" id L159" class="line" nam L159">2159.;..error;.<3 href3"fs/xfs/xfs_acl" class="sref">ino)).215108 xfs_attr_set(EACCES2162 S_ISLNKxfs_ac#L159" id L159" class="line" nam L159">2159.E3PNOTSUPP;.9.2177 switch (typ )3{.;.xfs_attr_get(acef="fs/xfsvalass="line" nam ef="fs/xfsvalasL120" id L120" clasass="line" nam L162">2162 A3L_TYP37ref="fs/xfs/xe" cget" class="sref">xfs_attr_get(ea_nam3 3 , struct >2159.2141 3CL_TY38ode=xfs_attr_get" class="sref">xfs_attr_get(2188 }.S3ISDIR3/a>(Eass="line" nam L162">21/xfs_acl.c#L202" id L202" class="line" nam L202">2/"gclalass="sref">typae=acl" class="sref">acl-> 3eturn a3l ? -, struct >2159.ea_nam3 38>2115 ;.e" class="sref">inof">posix_acl *217608 typ" class="line" nam L183">21f="+code=xfs_acl" mode)).212 unsigned char *<3a href="+3ode=EINVAL" class="sref"3EINVA3;.xfs_attr_get(acef="fs/xfsfquiv3" class="line" nam ef="fs/xfsfquiv3" clL120" id L120" clasass="line" nam L162">21," class="sref">ATTR_R" class="line" nam L183">2189..ENOATTR) {. acl) {.xfs_acl_entry, struct 2162 *211#L151" id L151" class="line" nam L151">2151 3ef="+code3len" class="sref">len2203 ? -ENOATTR) {. xfs_ac3 39f="+code=inod">xfs_accccccccccccccccc.c#L81""fs/xfs/xfs_acl class="line" nam L173">2173.x3s_acl3/a>).;.xfs_attr_get(acxass="+c" class="line" nam lass="+c" cl href id L120" class, struct typ" class="line" nam L183">2189.xfs_attr_get(len = 3izeof39 -, struct >2159. for (inode * errorxfs_a class="line" nam L114">211+co"+code=inode" class="+cef">inode *, struct typ2162 4en," id L159" class=sreleas>, struct >2153 x4 L20405xfs_acl" class="sref">xfs_aef="fs/xfsreleas>, struct 2162 kfree2153 2173./*len = 4 mean403" a>/*2 94 c198 41>2141const/s/xfs_acl.c#L112" id Lam " handless="line" nam Lam " handles="+co" id L159" claxa_nxam " /xfs id L"handless="line" nam La_nxam " /xfs id L"handles>211+co8 len = size4f(str41/a>(EACCES 217"f="+code=xfs_acl" aacl.c#L1" id L179" class="line" nam L179">2171 error;.<4 href41href="+code=x.set" class="sre>, , , hre1 , , hre1 acl = .acl != acl4/a>;.4148218"handless="line" nam La_nxam " /xfs87">218"handles>211+co8 len3Cne=ea_nxam " /xfs>, hre1 f="fs/xfsout" cla3e 3t_acl4 clas4="sref">trac3_a_na41 href="+code=.set" class="sreflaghref="fs/xfs/xfsflagh>217"f="+code"sref">typ_acl.c#L182" id L182" class="linnxam " /xfs>, hre1 ef="+code4out" cla3xfs/xfs_a3ttr.h4 clas4="fref">xfs_3 href41href="+code=x.set" class="sre>, , , hre1 ef="fs/xf4/xfs_acl3x=len" cl3map_b4ree.h42 = size4f(str41/a>(, , hre1 or (
The original LXR software by>d.cpef=4+codehttp://sourceforge.net/ LXR 6we unit201" clthis clferi Panal verf* fsby>ef=4+codemailto:lx @errux.no">lx @errux.no01" .
lx .errux.no kiam y hosl.c#by>ef=4+codehttp://www.redpill-err Redpill Lrr