Blame view
fs/reiserfs/xattr.c
24.2 KB
1da177e4c Linux-2.6.12-rc2 |
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 |
/* * linux/fs/reiserfs/xattr.c * * Copyright (c) 2002 by Jeff Mahoney, <jeffm@suse.com> * */ /* * In order to implement EA/ACLs in a clean, backwards compatible manner, * they are implemented as files in a "private" directory. * Each EA is in it's own file, with the directory layout like so (/ is assumed * to be relative to fs root). Inside the /.reiserfs_priv/xattrs directory, * directories named using the capital-hex form of the objectid and * generation number are used. Inside each directory are individual files * named with the name of the extended attribute. * * So, for objectid 12648430, we could have: * /.reiserfs_priv/xattrs/C0FFEE.0/system.posix_acl_access * /.reiserfs_priv/xattrs/C0FFEE.0/system.posix_acl_default * /.reiserfs_priv/xattrs/C0FFEE.0/user.Content-Type * .. or similar. * * The file contents are the text of the EA. The size is known based on the * stat data describing the file. * * In the case of system.posix_acl_access and system.posix_acl_default, since * these are special cases for filesystem ACLs, they are interpreted by the * kernel, in addition, they are negatively and positively cached and attached * to the inode so that unnecessary lookups are avoided. |
d984561b3 reiserfs: elimina... |
30 31 |
* * Locking works like so: |
8b6dd72a4 reiserfs: make pe... |
32 33 |
* Directory components (xattr root, xattr dir) are protectd by their i_mutex. * The xattrs themselves are protected by the xattr_sem. |
1da177e4c Linux-2.6.12-rc2 |
34 |
*/ |
f466c6fdb move private bits... |
35 |
#include "reiserfs.h" |
16f7e0fe2 [PATCH] capable/c... |
36 |
#include <linux/capability.h> |
1da177e4c Linux-2.6.12-rc2 |
37 38 39 |
#include <linux/dcache.h> #include <linux/namei.h> #include <linux/errno.h> |
5a0e3ad6a include cleanup: ... |
40 |
#include <linux/gfp.h> |
1da177e4c Linux-2.6.12-rc2 |
41 42 43 44 |
#include <linux/fs.h> #include <linux/file.h> #include <linux/pagemap.h> #include <linux/xattr.h> |
c45ac8887 take private bits... |
45 |
#include "xattr.h" |
a3063ab88 move reiserfs_acl... |
46 |
#include "acl.h" |
17093991a fs/reiserfs: use ... |
47 |
#include <linux/uaccess.h> |
3277c39f8 [NET]: Kill direc... |
48 |
#include <net/checksum.h> |
1da177e4c Linux-2.6.12-rc2 |
49 |
#include <linux/stat.h> |
6c17675e1 reiserfs: simplif... |
50 |
#include <linux/quotaops.h> |
431547b3c sanitize xattr ha... |
51 |
#include <linux/security.h> |
47f70d08f reiserfs: use gen... |
52 |
#include <linux/posix_acl_xattr.h> |
1da177e4c Linux-2.6.12-rc2 |
53 |
|
1da177e4c Linux-2.6.12-rc2 |
54 55 |
#define PRIVROOT_NAME ".reiserfs_priv" #define XAROOT_NAME "xattrs" |
1da177e4c Linux-2.6.12-rc2 |
56 |
|
098297b27 reiserfs: cleanup... |
57 58 |
/* * Helpers for inode ops. We do this so that we don't have all the VFS |
6c17675e1 reiserfs: simplif... |
59 |
* overhead and also for proper i_mutex annotation. |
098297b27 reiserfs: cleanup... |
60 61 |
* dir->i_mutex must be held for all of them. */ |
3a355cc61 reiserfs: xattr_c... |
62 |
#ifdef CONFIG_REISERFS_FS_XATTR |
6c17675e1 reiserfs: simplif... |
63 |
static int xattr_create(struct inode *dir, struct dentry *dentry, int mode) |
1da177e4c Linux-2.6.12-rc2 |
64 |
{ |
5955102c9 wrappers for ->i_... |
65 |
BUG_ON(!inode_is_locked(dir)); |
ebfc3b49a don't pass nameid... |
66 |
return dir->i_op->create(dir, dentry, mode, true); |
6c17675e1 reiserfs: simplif... |
67 |
} |
3a355cc61 reiserfs: xattr_c... |
68 |
#endif |
bd4c625c0 reiserfs: run scr... |
69 |
|
18bb1db3e switch vfs_mkdir(... |
70 |
static int xattr_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) |
6c17675e1 reiserfs: simplif... |
71 |
{ |
5955102c9 wrappers for ->i_... |
72 |
BUG_ON(!inode_is_locked(dir)); |
6c17675e1 reiserfs: simplif... |
73 74 |
return dir->i_op->mkdir(dir, dentry, mode); } |
bd4c625c0 reiserfs: run scr... |
75 |
|
098297b27 reiserfs: cleanup... |
76 77 |
/* * We use I_MUTEX_CHILD here to silence lockdep. It's safe because xattr |
6c17675e1 reiserfs: simplif... |
78 79 |
* mutation ops aren't called during rename or splace, which are the * only other users of I_MUTEX_CHILD. It violates the ordering, but that's |
098297b27 reiserfs: cleanup... |
80 81 |
* better than allocating another subclass just for this code. */ |
6c17675e1 reiserfs: simplif... |
82 83 84 |
static int xattr_unlink(struct inode *dir, struct dentry *dentry) { int error; |
f3fb9e273 fs/reiserfs/xattr... |
85 |
|
5955102c9 wrappers for ->i_... |
86 |
BUG_ON(!inode_is_locked(dir)); |
bd4c625c0 reiserfs: run scr... |
87 |
|
5955102c9 wrappers for ->i_... |
88 |
inode_lock_nested(d_inode(dentry), I_MUTEX_CHILD); |
6c17675e1 reiserfs: simplif... |
89 |
error = dir->i_op->unlink(dir, dentry); |
5955102c9 wrappers for ->i_... |
90 |
inode_unlock(d_inode(dentry)); |
6c17675e1 reiserfs: simplif... |
91 92 93 94 95 96 97 98 99 |
if (!error) d_delete(dentry); return error; } static int xattr_rmdir(struct inode *dir, struct dentry *dentry) { int error; |
f3fb9e273 fs/reiserfs/xattr... |
100 |
|
5955102c9 wrappers for ->i_... |
101 |
BUG_ON(!inode_is_locked(dir)); |
6c17675e1 reiserfs: simplif... |
102 |
|
5955102c9 wrappers for ->i_... |
103 |
inode_lock_nested(d_inode(dentry), I_MUTEX_CHILD); |
6c17675e1 reiserfs: simplif... |
104 105 |
error = dir->i_op->rmdir(dir, dentry); if (!error) |
2b0143b5c VFS: normal files... |
106 |
d_inode(dentry)->i_flags |= S_DEAD; |
5955102c9 wrappers for ->i_... |
107 |
inode_unlock(d_inode(dentry)); |
6c17675e1 reiserfs: simplif... |
108 109 |
if (!error) d_delete(dentry); |
6c17675e1 reiserfs: simplif... |
110 111 112 |
return error; } |
6c17675e1 reiserfs: simplif... |
113 |
#define xattr_may_create(flags) (!flags || flags & XATTR_CREATE) |
ab17c4f02 reiserfs: fixup x... |
114 |
static struct dentry *open_xa_root(struct super_block *sb, int flags) |
6c17675e1 reiserfs: simplif... |
115 |
{ |
ab17c4f02 reiserfs: fixup x... |
116 117 |
struct dentry *privroot = REISERFS_SB(sb)->priv_root; struct dentry *xaroot; |
f3fb9e273 fs/reiserfs/xattr... |
118 |
|
2b0143b5c VFS: normal files... |
119 |
if (d_really_is_negative(privroot)) |
ab17c4f02 reiserfs: fixup x... |
120 |
return ERR_PTR(-ENODATA); |
6c17675e1 reiserfs: simplif... |
121 |
|
5955102c9 wrappers for ->i_... |
122 |
inode_lock_nested(d_inode(privroot), I_MUTEX_XATTR); |
6c17675e1 reiserfs: simplif... |
123 |
|
ab17c4f02 reiserfs: fixup x... |
124 |
xaroot = dget(REISERFS_SB(sb)->xattr_root); |
ceb5edc45 reiserfs: deal wi... |
125 126 |
if (!xaroot) xaroot = ERR_PTR(-ENODATA); |
2b0143b5c VFS: normal files... |
127 |
else if (d_really_is_negative(xaroot)) { |
ab17c4f02 reiserfs: fixup x... |
128 |
int err = -ENODATA; |
f3fb9e273 fs/reiserfs/xattr... |
129 |
|
5a6059c35 reiserfs: Expand ... |
130 |
if (xattr_may_create(flags)) |
2b0143b5c VFS: normal files... |
131 |
err = xattr_mkdir(d_inode(privroot), xaroot, 0700); |
9b7f37550 reiserfs: fix xat... |
132 |
if (err) { |
ab17c4f02 reiserfs: fixup x... |
133 134 |
dput(xaroot); xaroot = ERR_PTR(err); |
9b7f37550 reiserfs: fix xat... |
135 |
} |
bd4c625c0 reiserfs: run scr... |
136 |
} |
6c17675e1 reiserfs: simplif... |
137 |
|
5955102c9 wrappers for ->i_... |
138 |
inode_unlock(d_inode(privroot)); |
ab17c4f02 reiserfs: fixup x... |
139 |
return xaroot; |
1da177e4c Linux-2.6.12-rc2 |
140 |
} |
bd4c625c0 reiserfs: run scr... |
141 |
static struct dentry *open_xa_dir(const struct inode *inode, int flags) |
1da177e4c Linux-2.6.12-rc2 |
142 |
{ |
bd4c625c0 reiserfs: run scr... |
143 144 |
struct dentry *xaroot, *xadir; char namebuf[17]; |
6c17675e1 reiserfs: simplif... |
145 |
xaroot = open_xa_root(inode->i_sb, flags); |
9b7f37550 reiserfs: fix xat... |
146 |
if (IS_ERR(xaroot)) |
bd4c625c0 reiserfs: run scr... |
147 |
return xaroot; |
bd4c625c0 reiserfs: run scr... |
148 |
|
bd4c625c0 reiserfs: run scr... |
149 150 151 |
snprintf(namebuf, sizeof(namebuf), "%X.%X", le32_to_cpu(INODE_PKEY(inode)->k_objectid), inode->i_generation); |
bd4c625c0 reiserfs: run scr... |
152 |
|
5955102c9 wrappers for ->i_... |
153 |
inode_lock_nested(d_inode(xaroot), I_MUTEX_XATTR); |
ab17c4f02 reiserfs: fixup x... |
154 155 |
xadir = lookup_one_len(namebuf, xaroot, strlen(namebuf)); |
2b0143b5c VFS: normal files... |
156 |
if (!IS_ERR(xadir) && d_really_is_negative(xadir)) { |
ab17c4f02 reiserfs: fixup x... |
157 |
int err = -ENODATA; |
f3fb9e273 fs/reiserfs/xattr... |
158 |
|
ab17c4f02 reiserfs: fixup x... |
159 |
if (xattr_may_create(flags)) |
2b0143b5c VFS: normal files... |
160 |
err = xattr_mkdir(d_inode(xaroot), xadir, 0700); |
ab17c4f02 reiserfs: fixup x... |
161 162 163 164 165 |
if (err) { dput(xadir); xadir = ERR_PTR(err); } } |
5955102c9 wrappers for ->i_... |
166 |
inode_unlock(d_inode(xaroot)); |
bd4c625c0 reiserfs: run scr... |
167 168 |
dput(xaroot); return xadir; |
1da177e4c Linux-2.6.12-rc2 |
169 |
} |
098297b27 reiserfs: cleanup... |
170 171 |
/* * The following are side effects of other operations that aren't explicitly |
48b32a355 reiserfs: use gen... |
172 |
* modifying extended attributes. This includes operations such as permissions |
098297b27 reiserfs: cleanup... |
173 174 |
* or ownership changes, object deletions, etc. */ |
a41f1a471 reiserfs: use gen... |
175 |
struct reiserfs_dentry_buf { |
4acf381e1 [readdir] convert... |
176 |
struct dir_context ctx; |
a41f1a471 reiserfs: use gen... |
177 178 179 180 |
struct dentry *xadir; int count; struct dentry *dentries[8]; }; |
bd4c625c0 reiserfs: run scr... |
181 |
|
a72bdb1cd reiserfs: Clean u... |
182 |
static int |
ac7576f4b vfs: make first a... |
183 184 |
fill_with_dentries(struct dir_context *ctx, const char *name, int namelen, loff_t offset, u64 ino, unsigned int d_type) |
a72bdb1cd reiserfs: Clean u... |
185 |
{ |
ac7576f4b vfs: make first a... |
186 187 |
struct reiserfs_dentry_buf *dbuf = container_of(ctx, struct reiserfs_dentry_buf, ctx); |
a72bdb1cd reiserfs: Clean u... |
188 |
struct dentry *dentry; |
f3fb9e273 fs/reiserfs/xattr... |
189 |
|
5955102c9 wrappers for ->i_... |
190 |
WARN_ON_ONCE(!inode_is_locked(d_inode(dbuf->xadir))); |
bd4c625c0 reiserfs: run scr... |
191 |
|
a41f1a471 reiserfs: use gen... |
192 193 |
if (dbuf->count == ARRAY_SIZE(dbuf->dentries)) return -ENOSPC; |
bd4c625c0 reiserfs: run scr... |
194 |
|
35e5cbc0a reiserfs: Fix war... |
195 196 |
if (name[0] == '.' && (namelen < 2 || (namelen == 2 && name[1] == '.'))) |
a41f1a471 reiserfs: use gen... |
197 |
return 0; |
bd4c625c0 reiserfs: run scr... |
198 |
|
a41f1a471 reiserfs: use gen... |
199 |
dentry = lookup_one_len(name, dbuf->xadir, namelen); |
a72bdb1cd reiserfs: Clean u... |
200 |
if (IS_ERR(dentry)) { |
a41f1a471 reiserfs: use gen... |
201 |
return PTR_ERR(dentry); |
2b0143b5c VFS: normal files... |
202 |
} else if (d_really_is_negative(dentry)) { |
a41f1a471 reiserfs: use gen... |
203 204 |
/* A directory entry exists, but no file? */ reiserfs_error(dentry->d_sb, "xattr-20003", |
a455589f1 assorted conversi... |
205 206 207 208 |
"Corrupted directory: xattr %pd listed but " "not found for file %pd. ", dentry, dbuf->xadir); |
a41f1a471 reiserfs: use gen... |
209 210 |
dput(dentry); return -EIO; |
bd4c625c0 reiserfs: run scr... |
211 |
} |
1da177e4c Linux-2.6.12-rc2 |
212 |
|
a41f1a471 reiserfs: use gen... |
213 214 |
dbuf->dentries[dbuf->count++] = dentry; return 0; |
1da177e4c Linux-2.6.12-rc2 |
215 |
} |
a41f1a471 reiserfs: use gen... |
216 217 |
static void cleanup_dentry_buf(struct reiserfs_dentry_buf *buf) |
1da177e4c Linux-2.6.12-rc2 |
218 |
{ |
a41f1a471 reiserfs: use gen... |
219 |
int i; |
f3fb9e273 fs/reiserfs/xattr... |
220 |
|
a41f1a471 reiserfs: use gen... |
221 222 223 |
for (i = 0; i < buf->count; i++) if (buf->dentries[i]) dput(buf->dentries[i]); |
a72bdb1cd reiserfs: Clean u... |
224 |
} |
a41f1a471 reiserfs: use gen... |
225 226 227 |
static int reiserfs_for_each_xattr(struct inode *inode, int (*action)(struct dentry *, void *), void *data) |
a72bdb1cd reiserfs: Clean u... |
228 |
{ |
a41f1a471 reiserfs: use gen... |
229 230 |
struct dentry *dir; int i, err = 0; |
a41f1a471 reiserfs: use gen... |
231 |
struct reiserfs_dentry_buf buf = { |
4acf381e1 [readdir] convert... |
232 |
.ctx.actor = fill_with_dentries, |
a41f1a471 reiserfs: use gen... |
233 |
}; |
1da177e4c Linux-2.6.12-rc2 |
234 |
|
a72bdb1cd reiserfs: Clean u... |
235 236 237 |
/* Skip out, an xattr has no xattrs associated with it */ if (IS_PRIVATE(inode) || get_inode_sd_version(inode) == STAT_DATA_V1) return 0; |
1da177e4c Linux-2.6.12-rc2 |
238 |
|
6c17675e1 reiserfs: simplif... |
239 |
dir = open_xa_dir(inode, XATTR_REPLACE); |
a72bdb1cd reiserfs: Clean u... |
240 241 242 |
if (IS_ERR(dir)) { err = PTR_ERR(dir); goto out; |
2b0143b5c VFS: normal files... |
243 |
} else if (d_really_is_negative(dir)) { |
a41f1a471 reiserfs: use gen... |
244 245 |
err = 0; goto out_dir; |
a72bdb1cd reiserfs: Clean u... |
246 |
} |
1da177e4c Linux-2.6.12-rc2 |
247 |
|
5955102c9 wrappers for ->i_... |
248 |
inode_lock_nested(d_inode(dir), I_MUTEX_XATTR); |
27026a05b reiserfs: Fix rei... |
249 |
|
a41f1a471 reiserfs: use gen... |
250 |
buf.xadir = dir; |
cd62cdae0 reiserfs: switch ... |
251 |
while (1) { |
2b0143b5c VFS: normal files... |
252 |
err = reiserfs_readdir_inode(d_inode(dir), &buf.ctx); |
cd62cdae0 reiserfs: switch ... |
253 254 255 256 257 |
if (err) break; if (!buf.count) break; for (i = 0; !err && i < buf.count && buf.dentries[i]; i++) { |
a41f1a471 reiserfs: use gen... |
258 |
struct dentry *dentry = buf.dentries[i]; |
1da177e4c Linux-2.6.12-rc2 |
259 |
|
e36cb0b89 VFS: (Scripted) C... |
260 |
if (!d_is_dir(dentry)) |
cd62cdae0 reiserfs: switch ... |
261 |
err = action(dentry, data); |
1da177e4c Linux-2.6.12-rc2 |
262 |
|
a41f1a471 reiserfs: use gen... |
263 264 |
dput(dentry); buf.dentries[i] = NULL; |
bd4c625c0 reiserfs: run scr... |
265 |
} |
cd62cdae0 reiserfs: switch ... |
266 267 |
if (err) break; |
a41f1a471 reiserfs: use gen... |
268 |
buf.count = 0; |
8b6dd72a4 reiserfs: make pe... |
269 |
} |
5955102c9 wrappers for ->i_... |
270 |
inode_unlock(d_inode(dir)); |
1da177e4c Linux-2.6.12-rc2 |
271 |
|
a41f1a471 reiserfs: use gen... |
272 |
cleanup_dentry_buf(&buf); |
1da177e4c Linux-2.6.12-rc2 |
273 |
|
d984561b3 reiserfs: elimina... |
274 |
if (!err) { |
098297b27 reiserfs: cleanup... |
275 276 |
/* * We start a transaction here to avoid a ABBA situation |
a41f1a471 reiserfs: use gen... |
277 278 279 |
* between the xattr root's i_mutex and the journal lock. * This doesn't incur much additional overhead since the * new transaction will just nest inside the |
098297b27 reiserfs: cleanup... |
280 281 |
* outer transaction. */ |
a41f1a471 reiserfs: use gen... |
282 283 284 |
int blocks = JOURNAL_PER_BALANCE_CNT * 2 + 2 + 4 * REISERFS_QUOTA_TRANS_BLOCKS(inode->i_sb); struct reiserfs_transaction_handle th; |
f3fb9e273 fs/reiserfs/xattr... |
285 |
|
4c05141df reiserfs: locking... |
286 |
reiserfs_write_lock(inode->i_sb); |
a41f1a471 reiserfs: use gen... |
287 |
err = journal_begin(&th, inode->i_sb, blocks); |
4c05141df reiserfs: locking... |
288 |
reiserfs_write_unlock(inode->i_sb); |
a41f1a471 reiserfs: use gen... |
289 290 |
if (!err) { int jerror; |
f3fb9e273 fs/reiserfs/xattr... |
291 |
|
5955102c9 wrappers for ->i_... |
292 |
inode_lock_nested(d_inode(dir->d_parent), |
4c05141df reiserfs: locking... |
293 |
I_MUTEX_XATTR); |
a41f1a471 reiserfs: use gen... |
294 |
err = action(dir, data); |
4c05141df reiserfs: locking... |
295 |
reiserfs_write_lock(inode->i_sb); |
58d854265 reiserfs: cleanup... |
296 |
jerror = journal_end(&th); |
4c05141df reiserfs: locking... |
297 |
reiserfs_write_unlock(inode->i_sb); |
5955102c9 wrappers for ->i_... |
298 |
inode_unlock(d_inode(dir->d_parent)); |
a41f1a471 reiserfs: use gen... |
299 300 |
err = jerror ?: err; } |
a72bdb1cd reiserfs: Clean u... |
301 |
} |
a41f1a471 reiserfs: use gen... |
302 303 |
out_dir: dput(dir); |
a72bdb1cd reiserfs: Clean u... |
304 |
out: |
a41f1a471 reiserfs: use gen... |
305 306 307 |
/* -ENODATA isn't an error */ if (err == -ENODATA) err = 0; |
a72bdb1cd reiserfs: Clean u... |
308 309 |
return err; } |
1da177e4c Linux-2.6.12-rc2 |
310 |
|
a41f1a471 reiserfs: use gen... |
311 |
static int delete_one_xattr(struct dentry *dentry, void *data) |
a72bdb1cd reiserfs: Clean u... |
312 |
{ |
2b0143b5c VFS: normal files... |
313 |
struct inode *dir = d_inode(dentry->d_parent); |
1da177e4c Linux-2.6.12-rc2 |
314 |
|
a41f1a471 reiserfs: use gen... |
315 |
/* This is the xattr dir, handle specially. */ |
e36cb0b89 VFS: (Scripted) C... |
316 |
if (d_is_dir(dentry)) |
a41f1a471 reiserfs: use gen... |
317 |
return xattr_rmdir(dir, dentry); |
1da177e4c Linux-2.6.12-rc2 |
318 |
|
a41f1a471 reiserfs: use gen... |
319 320 |
return xattr_unlink(dir, dentry); } |
bd4c625c0 reiserfs: run scr... |
321 |
|
a41f1a471 reiserfs: use gen... |
322 323 324 |
static int chown_one_xattr(struct dentry *dentry, void *data) { struct iattr *attrs = data; |
4a8570112 reiserfs: fix pro... |
325 326 327 328 329 330 331 332 333 334 335 336 337 |
int ia_valid = attrs->ia_valid; int err; /* * We only want the ownership bits. Otherwise, we'll do * things like change a directory to a regular file if * ATTR_MODE is set. */ attrs->ia_valid &= (ATTR_UID|ATTR_GID); err = reiserfs_setattr(dentry, attrs); attrs->ia_valid = ia_valid; return err; |
a41f1a471 reiserfs: use gen... |
338 |
} |
1da177e4c Linux-2.6.12-rc2 |
339 |
|
a41f1a471 reiserfs: use gen... |
340 341 342 343 |
/* No i_mutex, but the inode is unconnected. */ int reiserfs_delete_xattrs(struct inode *inode) { int err = reiserfs_for_each_xattr(inode, delete_one_xattr, NULL); |
f3fb9e273 fs/reiserfs/xattr... |
344 |
|
a41f1a471 reiserfs: use gen... |
345 346 347 348 |
if (err) reiserfs_warning(inode->i_sb, "jdm-20004", "Couldn't delete all xattrs (%d) ", err); |
a72bdb1cd reiserfs: Clean u... |
349 350 |
return err; } |
1da177e4c Linux-2.6.12-rc2 |
351 |
|
a41f1a471 reiserfs: use gen... |
352 |
/* inode->i_mutex: down */ |
a72bdb1cd reiserfs: Clean u... |
353 354 |
int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs) { |
a41f1a471 reiserfs: use gen... |
355 |
int err = reiserfs_for_each_xattr(inode, chown_one_xattr, attrs); |
f3fb9e273 fs/reiserfs/xattr... |
356 |
|
8b6dd72a4 reiserfs: make pe... |
357 358 359 360 |
if (err) reiserfs_warning(inode->i_sb, "jdm-20007", "Couldn't chown all xattrs (%d) ", err); |
a72bdb1cd reiserfs: Clean u... |
361 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
362 |
} |
a72bdb1cd reiserfs: Clean u... |
363 |
#ifdef CONFIG_REISERFS_FS_XATTR |
098297b27 reiserfs: cleanup... |
364 365 |
/* * Returns a dentry corresponding to a specific extended attribute file |
a72bdb1cd reiserfs: Clean u... |
366 |
* for the inode. If flags allow, the file is created. Otherwise, a |
098297b27 reiserfs: cleanup... |
367 368 |
* valid or negative dentry, or an error is returned. */ |
48b32a355 reiserfs: use gen... |
369 370 |
static struct dentry *xattr_lookup(struct inode *inode, const char *name, int flags) |
1da177e4c Linux-2.6.12-rc2 |
371 |
{ |
a72bdb1cd reiserfs: Clean u... |
372 373 374 375 |
struct dentry *xadir, *xafile; int err = 0; xadir = open_xa_dir(inode, flags); |
6c17675e1 reiserfs: simplif... |
376 |
if (IS_ERR(xadir)) |
a72bdb1cd reiserfs: Clean u... |
377 |
return ERR_CAST(xadir); |
a72bdb1cd reiserfs: Clean u... |
378 |
|
5955102c9 wrappers for ->i_... |
379 |
inode_lock_nested(d_inode(xadir), I_MUTEX_XATTR); |
a72bdb1cd reiserfs: Clean u... |
380 381 |
xafile = lookup_one_len(name, xadir, strlen(name)); if (IS_ERR(xafile)) { |
6c17675e1 reiserfs: simplif... |
382 383 |
err = PTR_ERR(xafile); goto out; |
bd4c625c0 reiserfs: run scr... |
384 |
} |
a72bdb1cd reiserfs: Clean u... |
385 |
|
2b0143b5c VFS: normal files... |
386 |
if (d_really_is_positive(xafile) && (flags & XATTR_CREATE)) |
6c17675e1 reiserfs: simplif... |
387 |
err = -EEXIST; |
a72bdb1cd reiserfs: Clean u... |
388 |
|
2b0143b5c VFS: normal files... |
389 |
if (d_really_is_negative(xafile)) { |
6c17675e1 reiserfs: simplif... |
390 |
err = -ENODATA; |
5a6059c35 reiserfs: Expand ... |
391 |
if (xattr_may_create(flags)) |
2b0143b5c VFS: normal files... |
392 |
err = xattr_create(d_inode(xadir), xafile, |
6c17675e1 reiserfs: simplif... |
393 |
0700|S_IFREG); |
a72bdb1cd reiserfs: Clean u... |
394 |
} |
6c17675e1 reiserfs: simplif... |
395 396 |
if (err) dput(xafile); |
a72bdb1cd reiserfs: Clean u... |
397 |
out: |
5955102c9 wrappers for ->i_... |
398 |
inode_unlock(d_inode(xadir)); |
a72bdb1cd reiserfs: Clean u... |
399 400 |
dput(xadir); if (err) |
6c17675e1 reiserfs: simplif... |
401 |
return ERR_PTR(err); |
a72bdb1cd reiserfs: Clean u... |
402 |
return xafile; |
1da177e4c Linux-2.6.12-rc2 |
403 |
} |
1da177e4c Linux-2.6.12-rc2 |
404 |
/* Internal operations on file data */ |
bd4c625c0 reiserfs: run scr... |
405 |
static inline void reiserfs_put_page(struct page *page) |
1da177e4c Linux-2.6.12-rc2 |
406 |
{ |
bd4c625c0 reiserfs: run scr... |
407 |
kunmap(page); |
09cbfeaf1 mm, fs: get rid o... |
408 |
put_page(page); |
1da177e4c Linux-2.6.12-rc2 |
409 |
} |
ec6ea56b2 reiserfs: xattr r... |
410 |
static struct page *reiserfs_get_page(struct inode *dir, size_t n) |
1da177e4c Linux-2.6.12-rc2 |
411 |
{ |
bd4c625c0 reiserfs: run scr... |
412 413 |
struct address_space *mapping = dir->i_mapping; struct page *page; |
098297b27 reiserfs: cleanup... |
414 415 416 417 |
/* * We can deadlock if we try to free dentries, * and an unlink/rmdir has just occurred - GFP_NOFS avoids this */ |
c4cdd0383 [PATCH] gfp_t: re... |
418 |
mapping_set_gfp_mask(mapping, GFP_NOFS); |
09cbfeaf1 mm, fs: get rid o... |
419 |
page = read_mapping_page(mapping, n >> PAGE_SHIFT, NULL); |
bd4c625c0 reiserfs: run scr... |
420 |
if (!IS_ERR(page)) { |
bd4c625c0 reiserfs: run scr... |
421 |
kmap(page); |
bd4c625c0 reiserfs: run scr... |
422 423 424 425 |
if (PageError(page)) goto fail; } return page; |
cf776a7a4 reiserfs: cleanup... |
426 |
fail: |
bd4c625c0 reiserfs: run scr... |
427 428 |
reiserfs_put_page(page); return ERR_PTR(-EIO); |
1da177e4c Linux-2.6.12-rc2 |
429 |
} |
bd4c625c0 reiserfs: run scr... |
430 |
static inline __u32 xattr_hash(const char *msg, int len) |
1da177e4c Linux-2.6.12-rc2 |
431 |
{ |
bd4c625c0 reiserfs: run scr... |
432 |
return csum_partial(msg, len, 0); |
1da177e4c Linux-2.6.12-rc2 |
433 |
} |
ba9d8cec6 reiserfs: convert... |
434 435 |
int reiserfs_commit_write(struct file *f, struct page *page, unsigned from, unsigned to); |
ba9d8cec6 reiserfs: convert... |
436 |
|
48b32a355 reiserfs: use gen... |
437 438 |
static void update_ctime(struct inode *inode) { |
02027d42c fs: Replace CURRE... |
439 |
struct timespec now = current_time(inode); |
f3fb9e273 fs/reiserfs/xattr... |
440 |
|
1d3382cbf new helper: inode... |
441 |
if (inode_unhashed(inode) || !inode->i_nlink || |
48b32a355 reiserfs: use gen... |
442 443 |
timespec_equal(&inode->i_ctime, &now)) return; |
02027d42c fs: Replace CURRE... |
444 |
inode->i_ctime = current_time(inode); |
48b32a355 reiserfs: use gen... |
445 446 447 448 449 450 451 452 453 454 455 |
mark_inode_dirty(inode); } static int lookup_and_delete_xattr(struct inode *inode, const char *name) { int err = 0; struct dentry *dentry, *xadir; xadir = open_xa_dir(inode, XATTR_REPLACE); if (IS_ERR(xadir)) return PTR_ERR(xadir); |
5955102c9 wrappers for ->i_... |
456 |
inode_lock_nested(d_inode(xadir), I_MUTEX_XATTR); |
48b32a355 reiserfs: use gen... |
457 458 459 460 461 |
dentry = lookup_one_len(name, xadir, strlen(name)); if (IS_ERR(dentry)) { err = PTR_ERR(dentry); goto out_dput; } |
2b0143b5c VFS: normal files... |
462 463 |
if (d_really_is_positive(dentry)) { err = xattr_unlink(d_inode(xadir), dentry); |
48b32a355 reiserfs: use gen... |
464 465 466 467 468 |
update_ctime(inode); } dput(dentry); out_dput: |
5955102c9 wrappers for ->i_... |
469 |
inode_unlock(d_inode(xadir)); |
48b32a355 reiserfs: use gen... |
470 471 472 |
dput(xadir); return err; } |
ba9d8cec6 reiserfs: convert... |
473 |
|
1da177e4c Linux-2.6.12-rc2 |
474 475 476 |
/* Generic extended attribute operations that can be used by xa plugins */ /* |
1b1dcc1b5 [PATCH] mutex sub... |
477 |
* inode->i_mutex: down |
1da177e4c Linux-2.6.12-rc2 |
478 479 |
*/ int |
0ab2621eb reiserfs: journal... |
480 481 482 |
reiserfs_xattr_set_handle(struct reiserfs_transaction_handle *th, struct inode *inode, const char *name, const void *buffer, size_t buffer_size, int flags) |
1da177e4c Linux-2.6.12-rc2 |
483 |
{ |
bd4c625c0 reiserfs: run scr... |
484 |
int err = 0; |
3227e14c3 [PATCH] reiserfs:... |
485 |
struct dentry *dentry; |
bd4c625c0 reiserfs: run scr... |
486 487 |
struct page *page; char *data; |
bd4c625c0 reiserfs: run scr... |
488 489 |
size_t file_pos = 0; size_t buffer_pos = 0; |
48b32a355 reiserfs: use gen... |
490 |
size_t new_size; |
bd4c625c0 reiserfs: run scr... |
491 |
__u32 xahash = 0; |
bd4c625c0 reiserfs: run scr... |
492 493 |
if (get_inode_sd_version(inode) == STAT_DATA_V1) return -EOPNOTSUPP; |
4f3be1b5a reiserfs: Relax l... |
494 495 |
if (!buffer) { err = lookup_and_delete_xattr(inode, name); |
4f3be1b5a reiserfs: Relax l... |
496 497 |
return err; } |
48b32a355 reiserfs: use gen... |
498 |
dentry = xattr_lookup(inode, name, flags); |
4c05141df reiserfs: locking... |
499 |
if (IS_ERR(dentry)) |
48b32a355 reiserfs: use gen... |
500 |
return PTR_ERR(dentry); |
3f14fea6b reiserfs: Relax l... |
501 |
|
f3e22f48f reiserfs: Fix mis... |
502 |
down_write(&REISERFS_I(inode)->i_xattr_sem); |
bd4c625c0 reiserfs: run scr... |
503 |
|
8b6dd72a4 reiserfs: make pe... |
504 |
xahash = xattr_hash(buffer, buffer_size); |
bd4c625c0 reiserfs: run scr... |
505 506 507 |
while (buffer_pos < buffer_size || buffer_pos == 0) { size_t chunk; size_t skip = 0; |
09cbfeaf1 mm, fs: get rid o... |
508 |
size_t page_offset = (file_pos & (PAGE_SIZE - 1)); |
f3fb9e273 fs/reiserfs/xattr... |
509 |
|
09cbfeaf1 mm, fs: get rid o... |
510 511 |
if (buffer_size - buffer_pos > PAGE_SIZE) chunk = PAGE_SIZE; |
bd4c625c0 reiserfs: run scr... |
512 513 |
else chunk = buffer_size - buffer_pos; |
2b0143b5c VFS: normal files... |
514 |
page = reiserfs_get_page(d_inode(dentry), file_pos); |
bd4c625c0 reiserfs: run scr... |
515 516 |
if (IS_ERR(page)) { err = PTR_ERR(page); |
48b32a355 reiserfs: use gen... |
517 |
goto out_unlock; |
bd4c625c0 reiserfs: run scr... |
518 519 520 521 522 523 524 |
} lock_page(page); data = page_address(page); if (file_pos == 0) { struct reiserfs_xattr_header *rxh; |
f3fb9e273 fs/reiserfs/xattr... |
525 |
|
bd4c625c0 reiserfs: run scr... |
526 |
skip = file_pos = sizeof(struct reiserfs_xattr_header); |
09cbfeaf1 mm, fs: get rid o... |
527 528 |
if (chunk + skip > PAGE_SIZE) chunk = PAGE_SIZE - skip; |
bd4c625c0 reiserfs: run scr... |
529 530 531 532 |
rxh = (struct reiserfs_xattr_header *)data; rxh->h_magic = cpu_to_le32(REISERFS_XATTR_MAGIC); rxh->h_hash = cpu_to_le32(xahash); } |
4c05141df reiserfs: locking... |
533 |
reiserfs_write_lock(inode->i_sb); |
ebdec241d fs: kill block_pr... |
534 |
err = __reiserfs_write_begin(page, page_offset, chunk + skip); |
bd4c625c0 reiserfs: run scr... |
535 536 537 |
if (!err) { if (buffer) memcpy(data + skip, buffer + buffer_pos, chunk); |
3227e14c3 [PATCH] reiserfs:... |
538 539 540 |
err = reiserfs_commit_write(NULL, page, page_offset, page_offset + chunk + skip); |
bd4c625c0 reiserfs: run scr... |
541 |
} |
4c05141df reiserfs: locking... |
542 |
reiserfs_write_unlock(inode->i_sb); |
bd4c625c0 reiserfs: run scr... |
543 544 545 546 547 548 549 550 |
unlock_page(page); reiserfs_put_page(page); buffer_pos += chunk; file_pos += chunk; skip = 0; if (err || buffer_size == 0 || !buffer) break; } |
48b32a355 reiserfs: use gen... |
551 |
new_size = buffer_size + sizeof(struct reiserfs_xattr_header); |
2b0143b5c VFS: normal files... |
552 |
if (!err && new_size < i_size_read(d_inode(dentry))) { |
48b32a355 reiserfs: use gen... |
553 |
struct iattr newattrs = { |
02027d42c fs: Replace CURRE... |
554 |
.ia_ctime = current_time(inode), |
fb2162df7 reiserfs: fix cor... |
555 |
.ia_size = new_size, |
48b32a355 reiserfs: use gen... |
556 557 |
.ia_valid = ATTR_SIZE | ATTR_CTIME, }; |
31370f62b reiserfs: Relax r... |
558 |
|
5955102c9 wrappers for ->i_... |
559 |
inode_lock_nested(d_inode(dentry), I_MUTEX_XATTR); |
2b0143b5c VFS: normal files... |
560 |
inode_dio_wait(d_inode(dentry)); |
31370f62b reiserfs: Relax r... |
561 |
|
48b32a355 reiserfs: use gen... |
562 |
err = reiserfs_setattr(dentry, &newattrs); |
5955102c9 wrappers for ->i_... |
563 |
inode_unlock(d_inode(dentry)); |
48b32a355 reiserfs: use gen... |
564 565 566 |
} else update_ctime(inode); out_unlock: |
8b6dd72a4 reiserfs: make pe... |
567 |
up_write(&REISERFS_I(inode)->i_xattr_sem); |
3227e14c3 [PATCH] reiserfs:... |
568 |
dput(dentry); |
48b32a355 reiserfs: use gen... |
569 570 |
return err; } |
bd4c625c0 reiserfs: run scr... |
571 |
|
0ab2621eb reiserfs: journal... |
572 573 574 |
/* We need to start a transaction to maintain lock ordering */ int reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, size_t buffer_size, int flags) |
48b32a355 reiserfs: use gen... |
575 |
{ |
0ab2621eb reiserfs: journal... |
576 577 578 579 580 581 582 583 584 585 |
struct reiserfs_transaction_handle th; int error, error2; size_t jbegin_count = reiserfs_xattr_nblocks(inode, buffer_size); if (!(flags & XATTR_REPLACE)) jbegin_count += reiserfs_xattr_jcreate_nblocks(inode); reiserfs_write_lock(inode->i_sb); error = journal_begin(&th, inode->i_sb, jbegin_count); |
4c05141df reiserfs: locking... |
586 |
reiserfs_write_unlock(inode->i_sb); |
0ab2621eb reiserfs: journal... |
587 |
if (error) { |
0ab2621eb reiserfs: journal... |
588 |
return error; |
1da177e4c Linux-2.6.12-rc2 |
589 |
} |
bd4c625c0 reiserfs: run scr... |
590 |
|
0ab2621eb reiserfs: journal... |
591 592 |
error = reiserfs_xattr_set_handle(&th, inode, name, buffer, buffer_size, flags); |
bd4c625c0 reiserfs: run scr... |
593 |
|
4c05141df reiserfs: locking... |
594 |
reiserfs_write_lock(inode->i_sb); |
58d854265 reiserfs: cleanup... |
595 |
error2 = journal_end(&th); |
4c05141df reiserfs: locking... |
596 |
reiserfs_write_unlock(inode->i_sb); |
0ab2621eb reiserfs: journal... |
597 598 |
if (error == 0) error = error2; |
0ab2621eb reiserfs: journal... |
599 600 |
return error; |
1da177e4c Linux-2.6.12-rc2 |
601 602 603 |
} /* |
1b1dcc1b5 [PATCH] mutex sub... |
604 |
* inode->i_mutex: down |
1da177e4c Linux-2.6.12-rc2 |
605 606 |
*/ int |
48b32a355 reiserfs: use gen... |
607 |
reiserfs_xattr_get(struct inode *inode, const char *name, void *buffer, |
bd4c625c0 reiserfs: run scr... |
608 |
size_t buffer_size) |
1da177e4c Linux-2.6.12-rc2 |
609 |
{ |
bd4c625c0 reiserfs: run scr... |
610 |
ssize_t err = 0; |
3227e14c3 [PATCH] reiserfs:... |
611 |
struct dentry *dentry; |
bd4c625c0 reiserfs: run scr... |
612 613 614 615 |
size_t isize; size_t file_pos = 0; size_t buffer_pos = 0; struct page *page; |
bd4c625c0 reiserfs: run scr... |
616 617 618 619 |
__u32 hash = 0; if (name == NULL) return -EINVAL; |
098297b27 reiserfs: cleanup... |
620 621 622 623 |
/* * We can't have xattrs attached to v1 items since they don't have * generation numbers */ |
bd4c625c0 reiserfs: run scr... |
624 625 |
if (get_inode_sd_version(inode) == STAT_DATA_V1) return -EOPNOTSUPP; |
48b32a355 reiserfs: use gen... |
626 |
dentry = xattr_lookup(inode, name, XATTR_REPLACE); |
3227e14c3 [PATCH] reiserfs:... |
627 628 |
if (IS_ERR(dentry)) { err = PTR_ERR(dentry); |
bd4c625c0 reiserfs: run scr... |
629 630 |
goto out; } |
8b6dd72a4 reiserfs: make pe... |
631 |
down_read(&REISERFS_I(inode)->i_xattr_sem); |
d984561b3 reiserfs: elimina... |
632 |
|
2b0143b5c VFS: normal files... |
633 |
isize = i_size_read(d_inode(dentry)); |
bd4c625c0 reiserfs: run scr... |
634 635 636 637 |
/* Just return the size needed */ if (buffer == NULL) { err = isize - sizeof(struct reiserfs_xattr_header); |
8b6dd72a4 reiserfs: make pe... |
638 |
goto out_unlock; |
bd4c625c0 reiserfs: run scr... |
639 640 641 642 |
} if (buffer_size < isize - sizeof(struct reiserfs_xattr_header)) { err = -ERANGE; |
8b6dd72a4 reiserfs: make pe... |
643 |
goto out_unlock; |
bd4c625c0 reiserfs: run scr... |
644 645 646 647 648 649 |
} while (file_pos < isize) { size_t chunk; char *data; size_t skip = 0; |
f3fb9e273 fs/reiserfs/xattr... |
650 |
|
09cbfeaf1 mm, fs: get rid o... |
651 652 |
if (isize - file_pos > PAGE_SIZE) chunk = PAGE_SIZE; |
bd4c625c0 reiserfs: run scr... |
653 654 |
else chunk = isize - file_pos; |
2b0143b5c VFS: normal files... |
655 |
page = reiserfs_get_page(d_inode(dentry), file_pos); |
bd4c625c0 reiserfs: run scr... |
656 657 |
if (IS_ERR(page)) { err = PTR_ERR(page); |
8b6dd72a4 reiserfs: make pe... |
658 |
goto out_unlock; |
bd4c625c0 reiserfs: run scr... |
659 660 661 662 663 664 665 666 667 668 669 670 671 |
} lock_page(page); data = page_address(page); if (file_pos == 0) { struct reiserfs_xattr_header *rxh = (struct reiserfs_xattr_header *)data; skip = file_pos = sizeof(struct reiserfs_xattr_header); chunk -= skip; /* Magic doesn't match up.. */ if (rxh->h_magic != cpu_to_le32(REISERFS_XATTR_MAGIC)) { unlock_page(page); reiserfs_put_page(page); |
a72bdb1cd reiserfs: Clean u... |
672 |
reiserfs_warning(inode->i_sb, "jdm-20001", |
bd4c625c0 reiserfs: run scr... |
673 674 675 676 |
"Invalid magic for xattr (%s) " "associated with %k", name, INODE_PKEY(inode)); err = -EIO; |
8b6dd72a4 reiserfs: make pe... |
677 |
goto out_unlock; |
bd4c625c0 reiserfs: run scr... |
678 679 680 681 682 683 684 685 686 687 688 689 690 691 |
} hash = le32_to_cpu(rxh->h_hash); } memcpy(buffer + buffer_pos, data + skip, chunk); unlock_page(page); reiserfs_put_page(page); file_pos += chunk; buffer_pos += chunk; skip = 0; } err = isize - sizeof(struct reiserfs_xattr_header); if (xattr_hash(buffer, isize - sizeof(struct reiserfs_xattr_header)) != hash) { |
a72bdb1cd reiserfs: Clean u... |
692 |
reiserfs_warning(inode->i_sb, "jdm-20002", |
bd4c625c0 reiserfs: run scr... |
693 694 695 696 |
"Invalid hash for xattr (%s) associated " "with %k", name, INODE_PKEY(inode)); err = -EIO; } |
8b6dd72a4 reiserfs: make pe... |
697 698 |
out_unlock: up_read(&REISERFS_I(inode)->i_xattr_sem); |
3227e14c3 [PATCH] reiserfs:... |
699 |
dput(dentry); |
bd4c625c0 reiserfs: run scr... |
700 |
|
a72bdb1cd reiserfs: Clean u... |
701 |
out: |
bd4c625c0 reiserfs: run scr... |
702 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
703 |
} |
48b32a355 reiserfs: use gen... |
704 705 706 707 708 709 710 711 712 713 714 715 716 |
/* * In order to implement different sets of xattr operations for each xattr * prefix with the generic xattr API, a filesystem should create a * null-terminated array of struct xattr_handler (one for each prefix) and * hang a pointer to it off of the s_xattr field of the superblock. * * The generic_fooxattr() functions will use this list to dispatch xattr * operations to the correct xattr_handler. */ #define for_each_xattr_handler(handlers, handler) \ for ((handler) = *(handlers)++; \ (handler) != NULL; \ (handler) = *(handlers)++) |
1da177e4c Linux-2.6.12-rc2 |
717 |
|
48b32a355 reiserfs: use gen... |
718 |
/* This is the implementation for the xattr plugin infrastructure */ |
94d09a98c reiserfs: constif... |
719 720 |
static inline const struct xattr_handler * find_xattr_handler_prefix(const struct xattr_handler **handlers, |
48b32a355 reiserfs: use gen... |
721 |
const char *name) |
1da177e4c Linux-2.6.12-rc2 |
722 |
{ |
94d09a98c reiserfs: constif... |
723 |
const struct xattr_handler *xah; |
bd4c625c0 reiserfs: run scr... |
724 |
|
48b32a355 reiserfs: use gen... |
725 726 |
if (!handlers) return NULL; |
bd4c625c0 reiserfs: run scr... |
727 |
|
48b32a355 reiserfs: use gen... |
728 |
for_each_xattr_handler(handlers, xah) { |
98e9cb571 vfs: Distinguish ... |
729 730 |
const char *prefix = xattr_prefix(xah); if (strncmp(prefix, name, strlen(prefix)) == 0) |
48b32a355 reiserfs: use gen... |
731 |
break; |
bd4c625c0 reiserfs: run scr... |
732 |
} |
48b32a355 reiserfs: use gen... |
733 |
return xah; |
bd4c625c0 reiserfs: run scr... |
734 |
} |
1da177e4c Linux-2.6.12-rc2 |
735 |
|
48b32a355 reiserfs: use gen... |
736 |
struct listxattr_buf { |
4acf381e1 [readdir] convert... |
737 |
struct dir_context ctx; |
48b32a355 reiserfs: use gen... |
738 739 740 |
size_t size; size_t pos; char *buf; |
431547b3c sanitize xattr ha... |
741 |
struct dentry *dentry; |
1da177e4c Linux-2.6.12-rc2 |
742 |
}; |
ac7576f4b vfs: make first a... |
743 744 745 |
static int listxattr_filler(struct dir_context *ctx, const char *name, int namelen, loff_t offset, u64 ino, unsigned int d_type) |
1da177e4c Linux-2.6.12-rc2 |
746 |
{ |
ac7576f4b vfs: make first a... |
747 748 |
struct listxattr_buf *b = container_of(ctx, struct listxattr_buf, ctx); |
48b32a355 reiserfs: use gen... |
749 |
size_t size; |
f3fb9e273 fs/reiserfs/xattr... |
750 |
|
48b32a355 reiserfs: use gen... |
751 752 |
if (name[0] != '.' || (namelen != 1 && (name[1] != '.' || namelen != 2))) { |
94d09a98c reiserfs: constif... |
753 |
const struct xattr_handler *handler; |
f3fb9e273 fs/reiserfs/xattr... |
754 |
|
431547b3c sanitize xattr ha... |
755 |
handler = find_xattr_handler_prefix(b->dentry->d_sb->s_xattr, |
48b32a355 reiserfs: use gen... |
756 |
name); |
764a5c6b1 xattr handlers: S... |
757 758 |
if (!handler /* Unsupported xattr name */ || (handler->list && !handler->list(b->dentry))) |
48b32a355 reiserfs: use gen... |
759 |
return 0; |
764a5c6b1 xattr handlers: S... |
760 |
size = namelen + 1; |
48b32a355 reiserfs: use gen... |
761 |
if (b->buf) { |
48b32a355 reiserfs: use gen... |
762 763 |
if (size > b->size) return -ERANGE; |
764a5c6b1 xattr handlers: S... |
764 765 |
memcpy(b->buf + b->pos, name, namelen); b->buf[b->pos + namelen] = 0; |
bd4c625c0 reiserfs: run scr... |
766 |
} |
48b32a355 reiserfs: use gen... |
767 768 |
b->pos += size; } |
bd4c625c0 reiserfs: run scr... |
769 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
770 |
} |
bd4c625c0 reiserfs: run scr... |
771 |
|
1da177e4c Linux-2.6.12-rc2 |
772 773 774 |
/* * Inode operation listxattr() * |
48b32a355 reiserfs: use gen... |
775 776 777 |
* We totally ignore the generic listxattr here because it would be stupid * not to. Since the xattrs are organized in a directory, we can just * readdir to find them. |
1da177e4c Linux-2.6.12-rc2 |
778 |
*/ |
bd4c625c0 reiserfs: run scr... |
779 |
ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size) |
1da177e4c Linux-2.6.12-rc2 |
780 |
{ |
bd4c625c0 reiserfs: run scr... |
781 782 |
struct dentry *dir; int err = 0; |
48b32a355 reiserfs: use gen... |
783 |
struct listxattr_buf buf = { |
4acf381e1 [readdir] convert... |
784 |
.ctx.actor = listxattr_filler, |
431547b3c sanitize xattr ha... |
785 |
.dentry = dentry, |
48b32a355 reiserfs: use gen... |
786 787 788 |
.buf = buffer, .size = buffer ? size : 0, }; |
bd4c625c0 reiserfs: run scr... |
789 |
|
2b0143b5c VFS: normal files... |
790 |
if (d_really_is_negative(dentry)) |
bd4c625c0 reiserfs: run scr... |
791 |
return -EINVAL; |
677c9b2e3 reiserfs: remove ... |
792 |
if (!dentry->d_sb->s_xattr || |
2b0143b5c VFS: normal files... |
793 |
get_inode_sd_version(d_inode(dentry)) == STAT_DATA_V1) |
bd4c625c0 reiserfs: run scr... |
794 |
return -EOPNOTSUPP; |
2b0143b5c VFS: normal files... |
795 |
dir = open_xa_dir(d_inode(dentry), XATTR_REPLACE); |
bd4c625c0 reiserfs: run scr... |
796 797 798 |
if (IS_ERR(dir)) { err = PTR_ERR(dir); if (err == -ENODATA) |
48b32a355 reiserfs: use gen... |
799 |
err = 0; /* Not an error if there aren't any xattrs */ |
bd4c625c0 reiserfs: run scr... |
800 801 |
goto out; } |
5955102c9 wrappers for ->i_... |
802 |
inode_lock_nested(d_inode(dir), I_MUTEX_XATTR); |
2b0143b5c VFS: normal files... |
803 |
err = reiserfs_readdir_inode(d_inode(dir), &buf.ctx); |
5955102c9 wrappers for ->i_... |
804 |
inode_unlock(d_inode(dir)); |
bd4c625c0 reiserfs: run scr... |
805 |
|
48b32a355 reiserfs: use gen... |
806 807 |
if (!err) err = buf.pos; |
bd4c625c0 reiserfs: run scr... |
808 |
|
3227e14c3 [PATCH] reiserfs:... |
809 |
dput(dir); |
8b6dd72a4 reiserfs: make pe... |
810 |
out: |
bd4c625c0 reiserfs: run scr... |
811 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
812 |
} |
a72bdb1cd reiserfs: Clean u... |
813 |
static int create_privroot(struct dentry *dentry) |
1da177e4c Linux-2.6.12-rc2 |
814 |
{ |
a72bdb1cd reiserfs: Clean u... |
815 |
int err; |
2b0143b5c VFS: normal files... |
816 |
struct inode *inode = d_inode(dentry->d_parent); |
f3fb9e273 fs/reiserfs/xattr... |
817 |
|
5955102c9 wrappers for ->i_... |
818 |
WARN_ON_ONCE(!inode_is_locked(inode)); |
5a6059c35 reiserfs: Expand ... |
819 |
|
6c17675e1 reiserfs: simplif... |
820 |
err = xattr_mkdir(inode, dentry, 0700); |
2b0143b5c VFS: normal files... |
821 |
if (err || d_really_is_negative(dentry)) { |
edcc37a04 Always lookup pri... |
822 823 824 825 826 |
reiserfs_warning(dentry->d_sb, "jdm-20006", "xattrs/ACLs enabled and couldn't " "find/create .reiserfs_priv. " "Failing mount."); return -EOPNOTSUPP; |
bd4c625c0 reiserfs: run scr... |
827 |
} |
2b0143b5c VFS: normal files... |
828 |
d_inode(dentry)->i_flags |= S_PRIVATE; |
edcc37a04 Always lookup pri... |
829 830 831 |
reiserfs_info(dentry->d_sb, "Created %s - reserved for xattr " "storage. ", PRIVROOT_NAME); |
bd4c625c0 reiserfs: run scr... |
832 |
|
edcc37a04 Always lookup pri... |
833 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
834 |
} |
12abb35a0 reiserfs: clean u... |
835 836 837 838 839 840 841 |
#else int __init reiserfs_xattr_register_handlers(void) { return 0; } void reiserfs_xattr_unregister_handlers(void) {} static int create_privroot(struct dentry *dentry) { return 0; } #endif /* Actual operations that are exported to VFS-land */ |
da02eb72f reiserfs: Make re... |
842 |
static const struct xattr_handler *reiserfs_xattr_handlers[] = { |
12abb35a0 reiserfs: clean u... |
843 844 845 846 847 848 849 850 |
#ifdef CONFIG_REISERFS_FS_XATTR &reiserfs_xattr_user_handler, &reiserfs_xattr_trusted_handler, #endif #ifdef CONFIG_REISERFS_FS_SECURITY &reiserfs_xattr_security_handler, #endif #ifdef CONFIG_REISERFS_FS_POSIX_ACL |
47f70d08f reiserfs: use gen... |
851 852 |
&posix_acl_access_xattr_handler, &posix_acl_default_xattr_handler, |
12abb35a0 reiserfs: clean u... |
853 854 855 |
#endif NULL }; |
a72bdb1cd reiserfs: Clean u... |
856 |
static int xattr_mount_check(struct super_block *s) |
1da177e4c Linux-2.6.12-rc2 |
857 |
{ |
098297b27 reiserfs: cleanup... |
858 859 860 861 |
/* * We need generation numbers to ensure that the oid mapping is correct * v3.5 filesystems don't have them. */ |
48b32a355 reiserfs: use gen... |
862 863 |
if (old_format_only(s)) { if (reiserfs_xattrs_optional(s)) { |
098297b27 reiserfs: cleanup... |
864 865 866 867 |
/* * Old format filesystem, but optional xattrs have * been enabled. Error out. */ |
48b32a355 reiserfs: use gen... |
868 869 870 871 872 873 |
reiserfs_warning(s, "jdm-2005", "xattrs/ACLs not supported " "on pre-v3.6 format filesystems. " "Failing mount."); return -EOPNOTSUPP; } |
a72bdb1cd reiserfs: Clean u... |
874 875 876 |
} return 0; |
1da177e4c Linux-2.6.12-rc2 |
877 |
} |
10556cb21 ->permission() sa... |
878 |
int reiserfs_permission(struct inode *inode, int mask) |
b83674c0d reiserfs: fixup p... |
879 880 881 882 883 884 885 |
{ /* * We don't do permission checks on the internal objects. * Permissions are determined by the "owning" object. */ if (IS_PRIVATE(inode)) return 0; |
2830ba7f3 ->permission() sa... |
886 |
return generic_permission(inode, mask); |
b83674c0d reiserfs: fixup p... |
887 |
} |
0b728e191 stop passing name... |
888 |
static int xattr_hide_revalidate(struct dentry *dentry, unsigned int flags) |
1da177e4c Linux-2.6.12-rc2 |
889 |
{ |
cac36f707 reiserfs: fix per... |
890 |
return -EPERM; |
1da177e4c Linux-2.6.12-rc2 |
891 |
} |
e16404ed0 constify dentry_o... |
892 |
static const struct dentry_operations xattr_lookup_poison_ops = { |
cac36f707 reiserfs: fix per... |
893 |
.d_revalidate = xattr_hide_revalidate, |
1da177e4c Linux-2.6.12-rc2 |
894 |
}; |
edcc37a04 Always lookup pri... |
895 896 897 898 899 900 |
int reiserfs_lookup_privroot(struct super_block *s) { struct dentry *dentry; int err = 0; /* If we don't have the privroot located yet - go find it */ |
5955102c9 wrappers for ->i_... |
901 |
inode_lock(d_inode(s->s_root)); |
edcc37a04 Always lookup pri... |
902 903 904 905 |
dentry = lookup_one_len(PRIVROOT_NAME, s->s_root, strlen(PRIVROOT_NAME)); if (!IS_ERR(dentry)) { REISERFS_SB(s)->priv_root = dentry; |
fb045adb9 fs: dcache reduce... |
906 |
d_set_d_op(dentry, &xattr_lookup_poison_ops); |
2b0143b5c VFS: normal files... |
907 908 |
if (d_really_is_positive(dentry)) d_inode(dentry)->i_flags |= S_PRIVATE; |
edcc37a04 Always lookup pri... |
909 910 |
} else err = PTR_ERR(dentry); |
5955102c9 wrappers for ->i_... |
911 |
inode_unlock(d_inode(s->s_root)); |
edcc37a04 Always lookup pri... |
912 913 914 |
return err; } |
098297b27 reiserfs: cleanup... |
915 916 |
/* * We need to take a copy of the mount flags since things like |
1da177e4c Linux-2.6.12-rc2 |
917 |
* MS_RDONLY don't get set until *after* we're called. |
098297b27 reiserfs: cleanup... |
918 919 |
* mount_flags != mount_options */ |
bd4c625c0 reiserfs: run scr... |
920 |
int reiserfs_xattr_init(struct super_block *s, int mount_flags) |
1da177e4c Linux-2.6.12-rc2 |
921 |
{ |
bd4c625c0 reiserfs: run scr... |
922 |
int err = 0; |
ab17c4f02 reiserfs: fixup x... |
923 |
struct dentry *privroot = REISERFS_SB(s)->priv_root; |
bd4c625c0 reiserfs: run scr... |
924 |
|
a72bdb1cd reiserfs: Clean u... |
925 926 |
err = xattr_mount_check(s); if (err) |
bd4c625c0 reiserfs: run scr... |
927 |
goto error; |
bd4c625c0 reiserfs: run scr... |
928 |
|
2b0143b5c VFS: normal files... |
929 |
if (d_really_is_negative(privroot) && !(mount_flags & MS_RDONLY)) { |
5955102c9 wrappers for ->i_... |
930 |
inode_lock(d_inode(s->s_root)); |
edcc37a04 Always lookup pri... |
931 |
err = create_privroot(REISERFS_SB(s)->priv_root); |
5955102c9 wrappers for ->i_... |
932 |
inode_unlock(d_inode(s->s_root)); |
bd4c625c0 reiserfs: run scr... |
933 |
} |
ab17c4f02 reiserfs: fixup x... |
934 |
|
2b0143b5c VFS: normal files... |
935 |
if (d_really_is_positive(privroot)) { |
48b32a355 reiserfs: use gen... |
936 |
s->s_xattr = reiserfs_xattr_handlers; |
5955102c9 wrappers for ->i_... |
937 |
inode_lock(d_inode(privroot)); |
ab17c4f02 reiserfs: fixup x... |
938 939 |
if (!REISERFS_SB(s)->xattr_root) { struct dentry *dentry; |
f3fb9e273 fs/reiserfs/xattr... |
940 |
|
ab17c4f02 reiserfs: fixup x... |
941 942 943 944 945 946 947 |
dentry = lookup_one_len(XAROOT_NAME, privroot, strlen(XAROOT_NAME)); if (!IS_ERR(dentry)) REISERFS_SB(s)->xattr_root = dentry; else err = PTR_ERR(dentry); } |
5955102c9 wrappers for ->i_... |
948 |
inode_unlock(d_inode(privroot)); |
ab17c4f02 reiserfs: fixup x... |
949 |
} |
48b32a355 reiserfs: use gen... |
950 |
|
a72bdb1cd reiserfs: Clean u... |
951 |
error: |
bd4c625c0 reiserfs: run scr... |
952 |
if (err) { |
a228bf8f0 reiserfs: cleanup... |
953 954 |
clear_bit(REISERFS_XATTRS_USER, &REISERFS_SB(s)->s_mount_opt); clear_bit(REISERFS_POSIXACL, &REISERFS_SB(s)->s_mount_opt); |
bd4c625c0 reiserfs: run scr... |
955 956 957 |
} /* The super_block MS_POSIXACL must mirror the (no)acl mount option. */ |
bd4c625c0 reiserfs: run scr... |
958 959 |
if (reiserfs_posixacl(s)) s->s_flags |= MS_POSIXACL; |
ab17c4f02 reiserfs: fixup x... |
960 |
else |
ab17c4f02 reiserfs: fixup x... |
961 |
s->s_flags &= ~MS_POSIXACL; |
bd4c625c0 reiserfs: run scr... |
962 963 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
964 |
} |