~ubuntu-branches/debian/wheezy/linux-2.6/wheezy

« back to all changes in this revision

Viewing changes to fs/cifs/xattr.c

  • Committer: Bazaar Package Importer
  • Author(s): Ben Hutchings, Ben Hutchings, Aurelien Jarno, Martin Michlmayr
  • Date: 2011-04-06 13:53:30 UTC
  • mfrom: (43.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20110406135330-wjufxhd0tvn3zx4z
Tags: 2.6.38-3
[ Ben Hutchings ]
* [ppc64] Add to linux-tools package architectures (Closes: #620124)
* [amd64] Save cr4 to mmu_cr4_features at boot time (Closes: #620284)
* appletalk: Fix bugs introduced when removing use of BKL
* ALSA: Fix yet another race in disconnection
* cciss: Fix lost command issue
* ath9k: Fix kernel panic in AR2427
* ses: Avoid kernel panic when lun 0 is not mapped
* PCI/ACPI: Report ASPM support to BIOS if not disabled from command line

[ Aurelien Jarno ]
* rtlwifi: fix build when PCI is not enabled.

[ Martin Michlmayr ]
* rtlwifi: Eliminate udelay calls with too large values (Closes: #620204)

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 
22
22
#include <linux/fs.h>
23
23
#include <linux/posix_acl_xattr.h>
 
24
#include <linux/slab.h>
24
25
#include "cifsfs.h"
25
26
#include "cifspdu.h"
26
27
#include "cifsglob.h"
29
30
 
30
31
#define MAX_EA_VALUE_SIZE 65535
31
32
#define CIFS_XATTR_DOS_ATTRIB "user.DosAttrib"
 
33
#define CIFS_XATTR_CIFS_ACL "system.cifs_acl"
32
34
#define CIFS_XATTR_USER_PREFIX "user."
33
35
#define CIFS_XATTR_SYSTEM_PREFIX "system."
34
36
#define CIFS_XATTR_OS2_PREFIX "os2."
35
 
#define CIFS_XATTR_SECURITY_PREFIX ".security"
 
37
#define CIFS_XATTR_SECURITY_PREFIX "security."
36
38
#define CIFS_XATTR_TRUSTED_PREFIX "trusted."
37
39
#define XATTR_TRUSTED_PREFIX_LEN  8
38
40
#define XATTR_SECURITY_PREFIX_LEN 9
46
48
#ifdef CONFIG_CIFS_XATTR
47
49
        int xid;
48
50
        struct cifs_sb_info *cifs_sb;
 
51
        struct tcon_link *tlink;
49
52
        struct cifsTconInfo *pTcon;
50
53
        struct super_block *sb;
51
 
        char *full_path;
 
54
        char *full_path = NULL;
52
55
 
53
56
        if (direntry == NULL)
54
57
                return -EIO;
57
60
        sb = direntry->d_inode->i_sb;
58
61
        if (sb == NULL)
59
62
                return -EIO;
 
63
 
 
64
        cifs_sb = CIFS_SB(sb);
 
65
        tlink = cifs_sb_tlink(cifs_sb);
 
66
        if (IS_ERR(tlink))
 
67
                return PTR_ERR(tlink);
 
68
        pTcon = tlink_tcon(tlink);
 
69
 
60
70
        xid = GetXid();
61
71
 
62
 
        cifs_sb = CIFS_SB(sb);
63
 
        pTcon = cifs_sb->tcon;
64
 
 
65
72
        full_path = build_path_from_dentry(direntry);
66
73
        if (full_path == NULL) {
67
74
                rc = -ENOMEM;
68
 
                FreeXid(xid);
69
 
                return rc;
 
75
                goto remove_ea_exit;
70
76
        }
71
77
        if (ea_name == NULL) {
72
 
                cFYI(1, ("Null xattr names not supported"));
 
78
                cFYI(1, "Null xattr names not supported");
73
79
        } else if (strncmp(ea_name, CIFS_XATTR_USER_PREFIX, 5)
74
80
                && (strncmp(ea_name, CIFS_XATTR_OS2_PREFIX, 4))) {
75
81
                cFYI(1,
76
 
                    ("illegal xattr request %s (only user namespace supported)",
77
 
                        ea_name));
 
82
                     "illegal xattr request %s (only user namespace supported)",
 
83
                     ea_name);
78
84
                /* BB what if no namespace prefix? */
79
85
                /* Should we just pass them to server, except for
80
86
                system and perhaps security prefixes? */
90
96
remove_ea_exit:
91
97
        kfree(full_path);
92
98
        FreeXid(xid);
 
99
        cifs_put_tlink(tlink);
93
100
#endif
94
101
        return rc;
95
102
}
101
108
#ifdef CONFIG_CIFS_XATTR
102
109
        int xid;
103
110
        struct cifs_sb_info *cifs_sb;
 
111
        struct tcon_link *tlink;
104
112
        struct cifsTconInfo *pTcon;
105
113
        struct super_block *sb;
106
114
        char *full_path;
112
120
        sb = direntry->d_inode->i_sb;
113
121
        if (sb == NULL)
114
122
                return -EIO;
 
123
 
 
124
        cifs_sb = CIFS_SB(sb);
 
125
        tlink = cifs_sb_tlink(cifs_sb);
 
126
        if (IS_ERR(tlink))
 
127
                return PTR_ERR(tlink);
 
128
        pTcon = tlink_tcon(tlink);
 
129
 
115
130
        xid = GetXid();
116
131
 
117
 
        cifs_sb = CIFS_SB(sb);
118
 
        pTcon = cifs_sb->tcon;
119
 
 
120
132
        full_path = build_path_from_dentry(direntry);
121
133
        if (full_path == NULL) {
122
134
                rc = -ENOMEM;
123
 
                FreeXid(xid);
124
 
                return rc;
 
135
                goto set_ea_exit;
125
136
        }
126
137
        /* return dos attributes as pseudo xattr */
127
138
        /* return alt name if available as pseudo attr */
130
141
                search server for EAs or streams to
131
142
                returns as xattrs */
132
143
        if (value_size > MAX_EA_VALUE_SIZE) {
133
 
                cFYI(1, ("size of EA value too large"));
134
 
                kfree(full_path);
135
 
                FreeXid(xid);
136
 
                return -EOPNOTSUPP;
 
144
                cFYI(1, "size of EA value too large");
 
145
                rc = -EOPNOTSUPP;
 
146
                goto set_ea_exit;
137
147
        }
138
148
 
139
149
        if (ea_name == NULL) {
140
 
                cFYI(1, ("Null xattr names not supported"));
 
150
                cFYI(1, "Null xattr names not supported");
141
151
        } else if (strncmp(ea_name, CIFS_XATTR_USER_PREFIX, 5) == 0) {
142
152
                if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
143
153
                        goto set_ea_exit;
144
154
                if (strncmp(ea_name, CIFS_XATTR_DOS_ATTRIB, 14) == 0)
145
 
                        cFYI(1, ("attempt to set cifs inode metadata"));
 
155
                        cFYI(1, "attempt to set cifs inode metadata");
146
156
 
147
157
                ea_name += 5; /* skip past user. prefix */
148
158
                rc = CIFSSMBSetEA(xid, pTcon, full_path, ea_name, ea_value,
168
178
                                        ACL_TYPE_ACCESS, cifs_sb->local_nls,
169
179
                                        cifs_sb->mnt_cifs_flags &
170
180
                                                CIFS_MOUNT_MAP_SPECIAL_CHR);
171
 
                        cFYI(1, ("set POSIX ACL rc %d", rc));
 
181
                        cFYI(1, "set POSIX ACL rc %d", rc);
172
182
#else
173
 
                        cFYI(1, ("set POSIX ACL not supported"));
 
183
                        cFYI(1, "set POSIX ACL not supported");
174
184
#endif
175
185
                } else if (strncmp(ea_name, POSIX_ACL_XATTR_DEFAULT,
176
186
                                   strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) {
181
191
                                        ACL_TYPE_DEFAULT, cifs_sb->local_nls,
182
192
                                        cifs_sb->mnt_cifs_flags &
183
193
                                                CIFS_MOUNT_MAP_SPECIAL_CHR);
184
 
                        cFYI(1, ("set POSIX default ACL rc %d", rc));
 
194
                        cFYI(1, "set POSIX default ACL rc %d", rc);
185
195
#else
186
 
                        cFYI(1, ("set default POSIX ACL not supported"));
 
196
                        cFYI(1, "set default POSIX ACL not supported");
187
197
#endif
188
198
                } else {
189
 
                        cFYI(1, ("illegal xattr request %s (only user namespace"
190
 
                                 " supported)", ea_name));
 
199
                        cFYI(1, "illegal xattr request %s (only user namespace"
 
200
                                " supported)", ea_name);
191
201
                  /* BB what if no namespace prefix? */
192
202
                  /* Should we just pass them to server, except for
193
203
                  system and perhaps security prefixes? */
197
207
set_ea_exit:
198
208
        kfree(full_path);
199
209
        FreeXid(xid);
 
210
        cifs_put_tlink(tlink);
200
211
#endif
201
212
        return rc;
202
213
}
208
219
#ifdef CONFIG_CIFS_XATTR
209
220
        int xid;
210
221
        struct cifs_sb_info *cifs_sb;
 
222
        struct tcon_link *tlink;
211
223
        struct cifsTconInfo *pTcon;
212
224
        struct super_block *sb;
213
225
        char *full_path;
220
232
        if (sb == NULL)
221
233
                return -EIO;
222
234
 
 
235
        cifs_sb = CIFS_SB(sb);
 
236
        tlink = cifs_sb_tlink(cifs_sb);
 
237
        if (IS_ERR(tlink))
 
238
                return PTR_ERR(tlink);
 
239
        pTcon = tlink_tcon(tlink);
 
240
 
223
241
        xid = GetXid();
224
242
 
225
 
        cifs_sb = CIFS_SB(sb);
226
 
        pTcon = cifs_sb->tcon;
227
 
 
228
243
        full_path = build_path_from_dentry(direntry);
229
244
        if (full_path == NULL) {
230
245
                rc = -ENOMEM;
231
 
                FreeXid(xid);
232
 
                return rc;
 
246
                goto get_ea_exit;
233
247
        }
234
248
        /* return dos attributes as pseudo xattr */
235
249
        /* return alt name if available as pseudo attr */
236
250
        if (ea_name == NULL) {
237
 
                cFYI(1, ("Null xattr names not supported"));
 
251
                cFYI(1, "Null xattr names not supported");
238
252
        } else if (strncmp(ea_name, CIFS_XATTR_USER_PREFIX, 5) == 0) {
239
253
                if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
240
254
                        goto get_ea_exit;
241
255
 
242
256
                if (strncmp(ea_name, CIFS_XATTR_DOS_ATTRIB, 14) == 0) {
243
 
                        cFYI(1, ("attempt to query cifs inode metadata"));
 
257
                        cFYI(1, "attempt to query cifs inode metadata");
244
258
                        /* revalidate/getattr then populate from inode */
245
259
                } /* BB add else when above is implemented */
246
260
                ea_name += 5; /* skip past user. prefix */
247
 
                rc = CIFSSMBQueryEA(xid, pTcon, full_path, ea_name, ea_value,
 
261
                rc = CIFSSMBQAllEAs(xid, pTcon, full_path, ea_name, ea_value,
248
262
                        buf_size, cifs_sb->local_nls,
249
263
                        cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
250
264
        } else if (strncmp(ea_name, CIFS_XATTR_OS2_PREFIX, 4) == 0) {
252
266
                        goto get_ea_exit;
253
267
 
254
268
                ea_name += 4; /* skip past os2. prefix */
255
 
                rc = CIFSSMBQueryEA(xid, pTcon, full_path, ea_name, ea_value,
 
269
                rc = CIFSSMBQAllEAs(xid, pTcon, full_path, ea_name, ea_value,
256
270
                        buf_size, cifs_sb->local_nls,
257
271
                        cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
258
272
        } else if (strncmp(ea_name, POSIX_ACL_XATTR_ACCESS,
264
278
                                cifs_sb->local_nls,
265
279
                                cifs_sb->mnt_cifs_flags &
266
280
                                        CIFS_MOUNT_MAP_SPECIAL_CHR);
267
 
#ifdef CONFIG_CIFS_EXPERIMENTAL
268
 
                else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
269
 
                        __u16 fid;
270
 
                        int oplock = 0;
271
 
                        struct cifs_ntsd *pacl = NULL;
272
 
                        __u32 buflen = 0;
273
 
                        if (experimEnabled)
274
 
                                rc = CIFSSMBOpen(xid, pTcon, full_path,
275
 
                                        FILE_OPEN, GENERIC_READ, 0, &fid,
276
 
                                        &oplock, NULL, cifs_sb->local_nls,
277
 
                                        cifs_sb->mnt_cifs_flags &
278
 
                                        CIFS_MOUNT_MAP_SPECIAL_CHR);
279
 
                        /* else rc is EOPNOTSUPP from above */
280
 
 
281
 
                        if (rc == 0) {
282
 
                                rc = CIFSSMBGetCIFSACL(xid, pTcon, fid, &pacl,
283
 
                                                      &buflen);
284
 
                                CIFSSMBClose(xid, pTcon, fid);
285
 
                        }
286
 
                }
287
 
#endif /* EXPERIMENTAL */
288
281
#else
289
 
                cFYI(1, ("query POSIX ACL not supported yet"));
 
282
                cFYI(1, "Query POSIX ACL not supported yet");
290
283
#endif /* CONFIG_CIFS_POSIX */
291
284
        } else if (strncmp(ea_name, POSIX_ACL_XATTR_DEFAULT,
292
285
                          strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) {
298
291
                                cifs_sb->mnt_cifs_flags &
299
292
                                        CIFS_MOUNT_MAP_SPECIAL_CHR);
300
293
#else
301
 
                cFYI(1, ("query POSIX default ACL not supported yet"));
302
 
#endif
 
294
                cFYI(1, "Query POSIX default ACL not supported yet");
 
295
#endif /* CONFIG_CIFS_POSIX */
 
296
        } else if (strncmp(ea_name, CIFS_XATTR_CIFS_ACL,
 
297
                                strlen(CIFS_XATTR_CIFS_ACL)) == 0) {
 
298
#ifdef CONFIG_CIFS_ACL
 
299
                        u32 acllen;
 
300
                        struct cifs_ntsd *pacl;
 
301
 
 
302
                        pacl = get_cifs_acl(cifs_sb, direntry->d_inode,
 
303
                                                full_path, &acllen);
 
304
                        if (IS_ERR(pacl)) {
 
305
                                rc = PTR_ERR(pacl);
 
306
                                cERROR(1, "%s: error %zd getting sec desc",
 
307
                                                __func__, rc);
 
308
                        } else {
 
309
                                if (ea_value) {
 
310
                                        if (acllen > buf_size)
 
311
                                                acllen = -ERANGE;
 
312
                                        else
 
313
                                                memcpy(ea_value, pacl, acllen);
 
314
                                }
 
315
                                rc = acllen;
 
316
                                kfree(pacl);
 
317
                        }
 
318
#else
 
319
                cFYI(1, "Query CIFS ACL not supported yet");
 
320
#endif /* CONFIG_CIFS_ACL */
303
321
        } else if (strncmp(ea_name,
304
322
                  CIFS_XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) == 0) {
305
 
                cFYI(1, ("Trusted xattr namespace not supported yet"));
 
323
                cFYI(1, "Trusted xattr namespace not supported yet");
306
324
        } else if (strncmp(ea_name,
307
325
                  CIFS_XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) == 0) {
308
 
                cFYI(1, ("Security xattr namespace not supported yet"));
 
326
                cFYI(1, "Security xattr namespace not supported yet");
309
327
        } else
310
328
                cFYI(1,
311
 
                    ("illegal xattr request %s (only user namespace supported)",
312
 
                        ea_name));
 
329
                    "illegal xattr request %s (only user namespace supported)",
 
330
                     ea_name);
313
331
 
314
332
        /* We could add an additional check for streams ie
315
333
            if proc/fs/cifs/streamstoxattr is set then
322
340
get_ea_exit:
323
341
        kfree(full_path);
324
342
        FreeXid(xid);
 
343
        cifs_put_tlink(tlink);
325
344
#endif
326
345
        return rc;
327
346
}
332
351
#ifdef CONFIG_CIFS_XATTR
333
352
        int xid;
334
353
        struct cifs_sb_info *cifs_sb;
 
354
        struct tcon_link *tlink;
335
355
        struct cifsTconInfo *pTcon;
336
356
        struct super_block *sb;
337
357
        char *full_path;
345
365
                return -EIO;
346
366
 
347
367
        cifs_sb = CIFS_SB(sb);
348
 
        pTcon = cifs_sb->tcon;
349
 
 
350
368
        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
351
369
                return -EOPNOTSUPP;
352
370
 
 
371
        tlink = cifs_sb_tlink(cifs_sb);
 
372
        if (IS_ERR(tlink))
 
373
                return PTR_ERR(tlink);
 
374
        pTcon = tlink_tcon(tlink);
 
375
 
353
376
        xid = GetXid();
354
377
 
355
378
        full_path = build_path_from_dentry(direntry);
356
379
        if (full_path == NULL) {
357
380
                rc = -ENOMEM;
358
 
                FreeXid(xid);
359
 
                return rc;
 
381
                goto list_ea_exit;
360
382
        }
361
383
        /* return dos attributes as pseudo xattr */
362
384
        /* return alt name if available as pseudo attr */
364
386
        /* if proc/fs/cifs/streamstoxattr is set then
365
387
                search server for EAs or streams to
366
388
                returns as xattrs */
367
 
        rc = CIFSSMBQAllEAs(xid, pTcon, full_path, data, buf_size,
368
 
                                cifs_sb->local_nls,
 
389
        rc = CIFSSMBQAllEAs(xid, pTcon, full_path, NULL, data,
 
390
                                buf_size, cifs_sb->local_nls,
369
391
                                cifs_sb->mnt_cifs_flags &
370
392
                                        CIFS_MOUNT_MAP_SPECIAL_CHR);
371
393
 
 
394
list_ea_exit:
372
395
        kfree(full_path);
373
396
        FreeXid(xid);
 
397
        cifs_put_tlink(tlink);
374
398
#endif
375
399
        return rc;
376
400
}