diff options
Diffstat (limited to 'fs/reiserfs/xattr.c')
-rw-r--r-- | fs/reiserfs/xattr.c | 2173 |
1 files changed, 1087 insertions, 1086 deletions
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 45582fe8b466..e386d3db3051 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c | |||
@@ -51,67 +51,68 @@ | |||
51 | #define PRIVROOT_NAME ".reiserfs_priv" | 51 | #define PRIVROOT_NAME ".reiserfs_priv" |
52 | #define XAROOT_NAME "xattrs" | 52 | #define XAROOT_NAME "xattrs" |
53 | 53 | ||
54 | static struct reiserfs_xattr_handler *find_xattr_handler_prefix (const char *prefix); | 54 | static struct reiserfs_xattr_handler *find_xattr_handler_prefix(const char |
55 | *prefix); | ||
55 | 56 | ||
56 | static struct dentry * | 57 | static struct dentry *create_xa_root(struct super_block *sb) |
57 | create_xa_root (struct super_block *sb) | ||
58 | { | 58 | { |
59 | struct dentry *privroot = dget (REISERFS_SB(sb)->priv_root); | 59 | struct dentry *privroot = dget(REISERFS_SB(sb)->priv_root); |
60 | struct dentry *xaroot; | 60 | struct dentry *xaroot; |
61 | 61 | ||
62 | /* This needs to be created at mount-time */ | 62 | /* This needs to be created at mount-time */ |
63 | if (!privroot) | 63 | if (!privroot) |
64 | return ERR_PTR(-EOPNOTSUPP); | 64 | return ERR_PTR(-EOPNOTSUPP); |
65 | 65 | ||
66 | xaroot = lookup_one_len (XAROOT_NAME, privroot, strlen (XAROOT_NAME)); | 66 | xaroot = lookup_one_len(XAROOT_NAME, privroot, strlen(XAROOT_NAME)); |
67 | if (IS_ERR (xaroot)) { | 67 | if (IS_ERR(xaroot)) { |
68 | goto out; | 68 | goto out; |
69 | } else if (!xaroot->d_inode) { | 69 | } else if (!xaroot->d_inode) { |
70 | int err; | 70 | int err; |
71 | down (&privroot->d_inode->i_sem); | 71 | down(&privroot->d_inode->i_sem); |
72 | err = privroot->d_inode->i_op->mkdir (privroot->d_inode, xaroot, 0700); | 72 | err = |
73 | up (&privroot->d_inode->i_sem); | 73 | privroot->d_inode->i_op->mkdir(privroot->d_inode, xaroot, |
74 | 74 | 0700); | |
75 | if (err) { | 75 | up(&privroot->d_inode->i_sem); |
76 | dput (xaroot); | 76 | |
77 | dput (privroot); | 77 | if (err) { |
78 | return ERR_PTR (err); | 78 | dput(xaroot); |
79 | } | 79 | dput(privroot); |
80 | REISERFS_SB(sb)->xattr_root = dget (xaroot); | 80 | return ERR_PTR(err); |
81 | } | 81 | } |
82 | 82 | REISERFS_SB(sb)->xattr_root = dget(xaroot); | |
83 | out: | 83 | } |
84 | dput (privroot); | 84 | |
85 | return xaroot; | 85 | out: |
86 | dput(privroot); | ||
87 | return xaroot; | ||
86 | } | 88 | } |
87 | 89 | ||
88 | /* This will return a dentry, or error, refering to the xa root directory. | 90 | /* This will return a dentry, or error, refering to the xa root directory. |
89 | * If the xa root doesn't exist yet, the dentry will be returned without | 91 | * If the xa root doesn't exist yet, the dentry will be returned without |
90 | * an associated inode. This dentry can be used with ->mkdir to create | 92 | * an associated inode. This dentry can be used with ->mkdir to create |
91 | * the xa directory. */ | 93 | * the xa directory. */ |
92 | static struct dentry * | 94 | static struct dentry *__get_xa_root(struct super_block *s) |
93 | __get_xa_root (struct super_block *s) | ||
94 | { | 95 | { |
95 | struct dentry *privroot = dget (REISERFS_SB(s)->priv_root); | 96 | struct dentry *privroot = dget(REISERFS_SB(s)->priv_root); |
96 | struct dentry *xaroot = NULL; | 97 | struct dentry *xaroot = NULL; |
97 | 98 | ||
98 | if (IS_ERR (privroot) || !privroot) | 99 | if (IS_ERR(privroot) || !privroot) |
99 | return privroot; | 100 | return privroot; |
100 | 101 | ||
101 | xaroot = lookup_one_len (XAROOT_NAME, privroot, strlen (XAROOT_NAME)); | 102 | xaroot = lookup_one_len(XAROOT_NAME, privroot, strlen(XAROOT_NAME)); |
102 | if (IS_ERR (xaroot)) { | 103 | if (IS_ERR(xaroot)) { |
103 | goto out; | 104 | goto out; |
104 | } else if (!xaroot->d_inode) { | 105 | } else if (!xaroot->d_inode) { |
105 | dput (xaroot); | 106 | dput(xaroot); |
106 | xaroot = NULL; | 107 | xaroot = NULL; |
107 | goto out; | 108 | goto out; |
108 | } | 109 | } |
109 | 110 | ||
110 | REISERFS_SB(s)->xattr_root = dget (xaroot); | 111 | REISERFS_SB(s)->xattr_root = dget(xaroot); |
111 | 112 | ||
112 | out: | 113 | out: |
113 | dput (privroot); | 114 | dput(privroot); |
114 | return xaroot; | 115 | return xaroot; |
115 | } | 116 | } |
116 | 117 | ||
117 | /* Returns the dentry (or NULL) referring to the root of the extended | 118 | /* Returns the dentry (or NULL) referring to the root of the extended |
@@ -119,147 +120,145 @@ out: | |||
119 | * Otherwise, we attempt to retreive it from disk. It may also return | 120 | * Otherwise, we attempt to retreive it from disk. It may also return |
120 | * a pointer-encoded error. | 121 | * a pointer-encoded error. |
121 | */ | 122 | */ |
122 | static inline struct dentry * | 123 | static inline struct dentry *get_xa_root(struct super_block *s) |
123 | get_xa_root (struct super_block *s) | ||
124 | { | 124 | { |
125 | struct dentry *dentry = dget (REISERFS_SB(s)->xattr_root); | 125 | struct dentry *dentry = dget(REISERFS_SB(s)->xattr_root); |
126 | 126 | ||
127 | if (!dentry) | 127 | if (!dentry) |
128 | dentry = __get_xa_root (s); | 128 | dentry = __get_xa_root(s); |
129 | 129 | ||
130 | return dentry; | 130 | return dentry; |
131 | } | 131 | } |
132 | 132 | ||
133 | /* Opens the directory corresponding to the inode's extended attribute store. | 133 | /* Opens the directory corresponding to the inode's extended attribute store. |
134 | * If flags allow, the tree to the directory may be created. If creation is | 134 | * If flags allow, the tree to the directory may be created. If creation is |
135 | * prohibited, -ENODATA is returned. */ | 135 | * prohibited, -ENODATA is returned. */ |
136 | static struct dentry * | 136 | static struct dentry *open_xa_dir(const struct inode *inode, int flags) |
137 | open_xa_dir (const struct inode *inode, int flags) | ||
138 | { | 137 | { |
139 | struct dentry *xaroot, *xadir; | 138 | struct dentry *xaroot, *xadir; |
140 | char namebuf[17]; | 139 | char namebuf[17]; |
141 | 140 | ||
142 | xaroot = get_xa_root (inode->i_sb); | 141 | xaroot = get_xa_root(inode->i_sb); |
143 | if (IS_ERR (xaroot)) { | 142 | if (IS_ERR(xaroot)) { |
144 | return xaroot; | 143 | return xaroot; |
145 | } else if (!xaroot) { | 144 | } else if (!xaroot) { |
146 | if (flags == 0 || flags & XATTR_CREATE) { | 145 | if (flags == 0 || flags & XATTR_CREATE) { |
147 | xaroot = create_xa_root (inode->i_sb); | 146 | xaroot = create_xa_root(inode->i_sb); |
148 | if (IS_ERR (xaroot)) | 147 | if (IS_ERR(xaroot)) |
149 | return xaroot; | 148 | return xaroot; |
150 | } | 149 | } |
151 | if (!xaroot) | 150 | if (!xaroot) |
152 | return ERR_PTR (-ENODATA); | 151 | return ERR_PTR(-ENODATA); |
153 | } | 152 | } |
154 | 153 | ||
155 | /* ok, we have xaroot open */ | 154 | /* ok, we have xaroot open */ |
156 | 155 | ||
157 | snprintf (namebuf, sizeof (namebuf), "%X.%X", | 156 | snprintf(namebuf, sizeof(namebuf), "%X.%X", |
158 | le32_to_cpu (INODE_PKEY (inode)->k_objectid), | 157 | le32_to_cpu(INODE_PKEY(inode)->k_objectid), |
159 | inode->i_generation); | 158 | inode->i_generation); |
160 | xadir = lookup_one_len (namebuf, xaroot, strlen (namebuf)); | 159 | xadir = lookup_one_len(namebuf, xaroot, strlen(namebuf)); |
161 | if (IS_ERR (xadir)) { | 160 | if (IS_ERR(xadir)) { |
162 | dput (xaroot); | 161 | dput(xaroot); |
163 | return xadir; | 162 | return xadir; |
164 | } | 163 | } |
165 | 164 | ||
166 | if (!xadir->d_inode) { | 165 | if (!xadir->d_inode) { |
167 | int err; | 166 | int err; |
168 | if (flags == 0 || flags & XATTR_CREATE) { | 167 | if (flags == 0 || flags & XATTR_CREATE) { |
169 | /* Although there is nothing else trying to create this directory, | 168 | /* Although there is nothing else trying to create this directory, |
170 | * another directory with the same hash may be created, so we need | 169 | * another directory with the same hash may be created, so we need |
171 | * to protect against that */ | 170 | * to protect against that */ |
172 | err = xaroot->d_inode->i_op->mkdir (xaroot->d_inode, xadir, 0700); | 171 | err = |
173 | if (err) { | 172 | xaroot->d_inode->i_op->mkdir(xaroot->d_inode, xadir, |
174 | dput (xaroot); | 173 | 0700); |
175 | dput (xadir); | 174 | if (err) { |
176 | return ERR_PTR (err); | 175 | dput(xaroot); |
177 | } | 176 | dput(xadir); |
178 | } | 177 | return ERR_PTR(err); |
179 | if (!xadir->d_inode) { | 178 | } |
180 | dput (xaroot); | 179 | } |
181 | dput (xadir); | 180 | if (!xadir->d_inode) { |
182 | return ERR_PTR (-ENODATA); | 181 | dput(xaroot); |
183 | } | 182 | dput(xadir); |
184 | } | 183 | return ERR_PTR(-ENODATA); |
185 | 184 | } | |
186 | dput (xaroot); | 185 | } |
187 | return xadir; | 186 | |
187 | dput(xaroot); | ||
188 | return xadir; | ||
188 | } | 189 | } |
189 | 190 | ||
190 | /* Returns a dentry corresponding to a specific extended attribute file | 191 | /* Returns a dentry corresponding to a specific extended attribute file |
191 | * for the inode. If flags allow, the file is created. Otherwise, a | 192 | * for the inode. If flags allow, the file is created. Otherwise, a |
192 | * valid or negative dentry, or an error is returned. */ | 193 | * valid or negative dentry, or an error is returned. */ |
193 | static struct dentry * | 194 | static struct dentry *get_xa_file_dentry(const struct inode *inode, |
194 | get_xa_file_dentry (const struct inode *inode, const char *name, int flags) | 195 | const char *name, int flags) |
195 | { | 196 | { |
196 | struct dentry *xadir, *xafile; | 197 | struct dentry *xadir, *xafile; |
197 | int err = 0; | 198 | int err = 0; |
198 | 199 | ||
199 | xadir = open_xa_dir (inode, flags); | 200 | xadir = open_xa_dir(inode, flags); |
200 | if (IS_ERR (xadir)) { | 201 | if (IS_ERR(xadir)) { |
201 | return ERR_PTR (PTR_ERR (xadir)); | 202 | return ERR_PTR(PTR_ERR(xadir)); |
202 | } else if (xadir && !xadir->d_inode) { | 203 | } else if (xadir && !xadir->d_inode) { |
203 | dput (xadir); | 204 | dput(xadir); |
204 | return ERR_PTR (-ENODATA); | 205 | return ERR_PTR(-ENODATA); |
205 | } | 206 | } |
206 | 207 | ||
207 | xafile = lookup_one_len (name, xadir, strlen (name)); | 208 | xafile = lookup_one_len(name, xadir, strlen(name)); |
208 | if (IS_ERR (xafile)) { | 209 | if (IS_ERR(xafile)) { |
209 | dput (xadir); | 210 | dput(xadir); |
210 | return ERR_PTR (PTR_ERR (xafile)); | 211 | return ERR_PTR(PTR_ERR(xafile)); |
211 | } | 212 | } |
212 | 213 | ||
213 | if (xafile->d_inode) { /* file exists */ | 214 | if (xafile->d_inode) { /* file exists */ |
214 | if (flags & XATTR_CREATE) { | 215 | if (flags & XATTR_CREATE) { |
215 | err = -EEXIST; | 216 | err = -EEXIST; |
216 | dput (xafile); | 217 | dput(xafile); |
217 | goto out; | 218 | goto out; |
218 | } | 219 | } |
219 | } else if (flags & XATTR_REPLACE || flags & FL_READONLY) { | 220 | } else if (flags & XATTR_REPLACE || flags & FL_READONLY) { |
220 | goto out; | 221 | goto out; |
221 | } else { | 222 | } else { |
222 | /* inode->i_sem is down, so nothing else can try to create | 223 | /* inode->i_sem is down, so nothing else can try to create |
223 | * the same xattr */ | 224 | * the same xattr */ |
224 | err = xadir->d_inode->i_op->create (xadir->d_inode, xafile, | 225 | err = xadir->d_inode->i_op->create(xadir->d_inode, xafile, |
225 | 0700|S_IFREG, NULL); | 226 | 0700 | S_IFREG, NULL); |
226 | 227 | ||
227 | if (err) { | 228 | if (err) { |
228 | dput (xafile); | 229 | dput(xafile); |
229 | goto out; | 230 | goto out; |
230 | } | 231 | } |
231 | } | 232 | } |
232 | |||
233 | out: | ||
234 | dput (xadir); | ||
235 | if (err) | ||
236 | xafile = ERR_PTR (err); | ||
237 | return xafile; | ||
238 | } | ||
239 | 233 | ||
234 | out: | ||
235 | dput(xadir); | ||
236 | if (err) | ||
237 | xafile = ERR_PTR(err); | ||
238 | return xafile; | ||
239 | } | ||
240 | 240 | ||
241 | /* Opens a file pointer to the attribute associated with inode */ | 241 | /* Opens a file pointer to the attribute associated with inode */ |
242 | static struct file * | 242 | static struct file *open_xa_file(const struct inode *inode, const char *name, |
243 | open_xa_file (const struct inode *inode, const char *name, int flags) | 243 | int flags) |
244 | { | 244 | { |
245 | struct dentry *xafile; | 245 | struct dentry *xafile; |
246 | struct file *fp; | 246 | struct file *fp; |
247 | 247 | ||
248 | xafile = get_xa_file_dentry (inode, name, flags); | 248 | xafile = get_xa_file_dentry(inode, name, flags); |
249 | if (IS_ERR (xafile)) | 249 | if (IS_ERR(xafile)) |
250 | return ERR_PTR (PTR_ERR (xafile)); | 250 | return ERR_PTR(PTR_ERR(xafile)); |
251 | else if (!xafile->d_inode) { | 251 | else if (!xafile->d_inode) { |
252 | dput (xafile); | 252 | dput(xafile); |
253 | return ERR_PTR (-ENODATA); | 253 | return ERR_PTR(-ENODATA); |
254 | } | 254 | } |
255 | 255 | ||
256 | fp = dentry_open (xafile, NULL, O_RDWR); | 256 | fp = dentry_open(xafile, NULL, O_RDWR); |
257 | /* dentry_open dputs the dentry if it fails */ | 257 | /* dentry_open dputs the dentry if it fails */ |
258 | 258 | ||
259 | return fp; | 259 | return fp; |
260 | } | 260 | } |
261 | 261 | ||
262 | |||
263 | /* | 262 | /* |
264 | * this is very similar to fs/reiserfs/dir.c:reiserfs_readdir, but | 263 | * this is very similar to fs/reiserfs/dir.c:reiserfs_readdir, but |
265 | * we need to drop the path before calling the filldir struct. That | 264 | * we need to drop the path before calling the filldir struct. That |
@@ -273,139 +272,146 @@ open_xa_file (const struct inode *inode, const char *name, int flags) | |||
273 | * we're called with i_sem held, so there are no worries about the directory | 272 | * we're called with i_sem held, so there are no worries about the directory |
274 | * changing underneath us. | 273 | * changing underneath us. |
275 | */ | 274 | */ |
276 | static int __xattr_readdir(struct file * filp, void * dirent, filldir_t filldir) | 275 | static int __xattr_readdir(struct file *filp, void *dirent, filldir_t filldir) |
277 | { | 276 | { |
278 | struct inode *inode = filp->f_dentry->d_inode; | 277 | struct inode *inode = filp->f_dentry->d_inode; |
279 | struct cpu_key pos_key; /* key of current position in the directory (key of directory entry) */ | 278 | struct cpu_key pos_key; /* key of current position in the directory (key of directory entry) */ |
280 | INITIALIZE_PATH (path_to_entry); | 279 | INITIALIZE_PATH(path_to_entry); |
281 | struct buffer_head * bh; | 280 | struct buffer_head *bh; |
282 | int entry_num; | 281 | int entry_num; |
283 | struct item_head * ih, tmp_ih; | 282 | struct item_head *ih, tmp_ih; |
284 | int search_res; | 283 | int search_res; |
285 | char * local_buf; | 284 | char *local_buf; |
286 | loff_t next_pos; | 285 | loff_t next_pos; |
287 | char small_buf[32] ; /* avoid kmalloc if we can */ | 286 | char small_buf[32]; /* avoid kmalloc if we can */ |
288 | struct reiserfs_de_head *deh; | 287 | struct reiserfs_de_head *deh; |
289 | int d_reclen; | 288 | int d_reclen; |
290 | char * d_name; | 289 | char *d_name; |
291 | off_t d_off; | 290 | off_t d_off; |
292 | ino_t d_ino; | 291 | ino_t d_ino; |
293 | struct reiserfs_dir_entry de; | 292 | struct reiserfs_dir_entry de; |
294 | 293 | ||
295 | 294 | /* form key for search the next directory entry using f_pos field of | |
296 | /* form key for search the next directory entry using f_pos field of | 295 | file structure */ |
297 | file structure */ | 296 | next_pos = max_reiserfs_offset(inode); |
298 | next_pos = max_reiserfs_offset(inode); | 297 | |
299 | 298 | while (1) { | |
300 | while (1) { | 299 | research: |
301 | research: | 300 | if (next_pos <= DOT_DOT_OFFSET) |
302 | if (next_pos <= DOT_DOT_OFFSET) | 301 | break; |
303 | break; | 302 | make_cpu_key(&pos_key, inode, next_pos, TYPE_DIRENTRY, 3); |
304 | make_cpu_key (&pos_key, inode, next_pos, TYPE_DIRENTRY, 3); | 303 | |
305 | 304 | search_res = | |
306 | search_res = search_by_entry_key(inode->i_sb, &pos_key, &path_to_entry, &de); | 305 | search_by_entry_key(inode->i_sb, &pos_key, &path_to_entry, |
307 | if (search_res == IO_ERROR) { | 306 | &de); |
308 | // FIXME: we could just skip part of directory which could | 307 | if (search_res == IO_ERROR) { |
309 | // not be read | 308 | // FIXME: we could just skip part of directory which could |
310 | pathrelse(&path_to_entry); | 309 | // not be read |
311 | return -EIO; | 310 | pathrelse(&path_to_entry); |
312 | } | 311 | return -EIO; |
313 | 312 | } | |
314 | if (search_res == NAME_NOT_FOUND) | ||
315 | de.de_entry_num--; | ||
316 | 313 | ||
317 | set_de_name_and_namelen(&de); | 314 | if (search_res == NAME_NOT_FOUND) |
318 | entry_num = de.de_entry_num; | 315 | de.de_entry_num--; |
319 | deh = &(de.de_deh[entry_num]); | ||
320 | 316 | ||
321 | bh = de.de_bh; | 317 | set_de_name_and_namelen(&de); |
322 | ih = de.de_ih; | 318 | entry_num = de.de_entry_num; |
319 | deh = &(de.de_deh[entry_num]); | ||
323 | 320 | ||
324 | if (!is_direntry_le_ih(ih)) { | 321 | bh = de.de_bh; |
325 | reiserfs_warning(inode->i_sb, "not direntry %h", ih); | 322 | ih = de.de_ih; |
326 | break; | ||
327 | } | ||
328 | copy_item_head(&tmp_ih, ih); | ||
329 | 323 | ||
330 | /* we must have found item, that is item of this directory, */ | 324 | if (!is_direntry_le_ih(ih)) { |
331 | RFALSE( COMP_SHORT_KEYS (&(ih->ih_key), &pos_key), | 325 | reiserfs_warning(inode->i_sb, "not direntry %h", ih); |
332 | "vs-9000: found item %h does not match to dir we readdir %K", | 326 | break; |
333 | ih, &pos_key); | 327 | } |
328 | copy_item_head(&tmp_ih, ih); | ||
334 | 329 | ||
335 | if (deh_offset(deh) <= DOT_DOT_OFFSET) { | 330 | /* we must have found item, that is item of this directory, */ |
336 | break; | 331 | RFALSE(COMP_SHORT_KEYS(&(ih->ih_key), &pos_key), |
337 | } | 332 | "vs-9000: found item %h does not match to dir we readdir %K", |
333 | ih, &pos_key); | ||
338 | 334 | ||
339 | /* look for the previous entry in the directory */ | 335 | if (deh_offset(deh) <= DOT_DOT_OFFSET) { |
340 | next_pos = deh_offset (deh) - 1; | 336 | break; |
337 | } | ||
341 | 338 | ||
342 | if (!de_visible (deh)) | 339 | /* look for the previous entry in the directory */ |
343 | /* it is hidden entry */ | 340 | next_pos = deh_offset(deh) - 1; |
344 | continue; | ||
345 | 341 | ||
346 | d_reclen = entry_length(bh, ih, entry_num); | 342 | if (!de_visible(deh)) |
347 | d_name = B_I_DEH_ENTRY_FILE_NAME (bh, ih, deh); | 343 | /* it is hidden entry */ |
348 | d_off = deh_offset (deh); | 344 | continue; |
349 | d_ino = deh_objectid (deh); | ||
350 | 345 | ||
351 | if (!d_name[d_reclen - 1]) | 346 | d_reclen = entry_length(bh, ih, entry_num); |
352 | d_reclen = strlen (d_name); | 347 | d_name = B_I_DEH_ENTRY_FILE_NAME(bh, ih, deh); |
348 | d_off = deh_offset(deh); | ||
349 | d_ino = deh_objectid(deh); | ||
353 | 350 | ||
354 | if (d_reclen > REISERFS_MAX_NAME(inode->i_sb->s_blocksize)){ | 351 | if (!d_name[d_reclen - 1]) |
355 | /* too big to send back to VFS */ | 352 | d_reclen = strlen(d_name); |
356 | continue ; | ||
357 | } | ||
358 | 353 | ||
359 | /* Ignore the .reiserfs_priv entry */ | 354 | if (d_reclen > REISERFS_MAX_NAME(inode->i_sb->s_blocksize)) { |
360 | if (reiserfs_xattrs (inode->i_sb) && | 355 | /* too big to send back to VFS */ |
361 | !old_format_only(inode->i_sb) && | 356 | continue; |
362 | deh_objectid (deh) == le32_to_cpu (INODE_PKEY(REISERFS_SB(inode->i_sb)->priv_root->d_inode)->k_objectid)) | 357 | } |
363 | continue; | ||
364 | 358 | ||
365 | if (d_reclen <= 32) { | 359 | /* Ignore the .reiserfs_priv entry */ |
366 | local_buf = small_buf ; | 360 | if (reiserfs_xattrs(inode->i_sb) && |
367 | } else { | 361 | !old_format_only(inode->i_sb) && |
368 | local_buf = reiserfs_kmalloc(d_reclen, GFP_NOFS, inode->i_sb) ; | 362 | deh_objectid(deh) == |
369 | if (!local_buf) { | 363 | le32_to_cpu(INODE_PKEY |
370 | pathrelse (&path_to_entry); | 364 | (REISERFS_SB(inode->i_sb)->priv_root->d_inode)-> |
371 | return -ENOMEM ; | 365 | k_objectid)) |
372 | } | 366 | continue; |
373 | if (item_moved (&tmp_ih, &path_to_entry)) { | 367 | |
374 | reiserfs_kfree(local_buf, d_reclen, inode->i_sb) ; | 368 | if (d_reclen <= 32) { |
375 | 369 | local_buf = small_buf; | |
376 | /* sigh, must retry. Do this same offset again */ | 370 | } else { |
377 | next_pos = d_off; | 371 | local_buf = |
378 | goto research; | 372 | reiserfs_kmalloc(d_reclen, GFP_NOFS, inode->i_sb); |
379 | } | 373 | if (!local_buf) { |
380 | } | 374 | pathrelse(&path_to_entry); |
375 | return -ENOMEM; | ||
376 | } | ||
377 | if (item_moved(&tmp_ih, &path_to_entry)) { | ||
378 | reiserfs_kfree(local_buf, d_reclen, | ||
379 | inode->i_sb); | ||
380 | |||
381 | /* sigh, must retry. Do this same offset again */ | ||
382 | next_pos = d_off; | ||
383 | goto research; | ||
384 | } | ||
385 | } | ||
381 | 386 | ||
382 | // Note, that we copy name to user space via temporary | 387 | // Note, that we copy name to user space via temporary |
383 | // buffer (local_buf) because filldir will block if | 388 | // buffer (local_buf) because filldir will block if |
384 | // user space buffer is swapped out. At that time | 389 | // user space buffer is swapped out. At that time |
385 | // entry can move to somewhere else | 390 | // entry can move to somewhere else |
386 | memcpy (local_buf, d_name, d_reclen); | 391 | memcpy(local_buf, d_name, d_reclen); |
387 | 392 | ||
388 | /* the filldir function might need to start transactions, | 393 | /* the filldir function might need to start transactions, |
389 | * or do who knows what. Release the path now that we've | 394 | * or do who knows what. Release the path now that we've |
390 | * copied all the important stuff out of the deh | 395 | * copied all the important stuff out of the deh |
391 | */ | 396 | */ |
392 | pathrelse (&path_to_entry); | 397 | pathrelse(&path_to_entry); |
393 | 398 | ||
394 | if (filldir (dirent, local_buf, d_reclen, d_off, d_ino, | 399 | if (filldir(dirent, local_buf, d_reclen, d_off, d_ino, |
395 | DT_UNKNOWN) < 0) { | 400 | DT_UNKNOWN) < 0) { |
396 | if (local_buf != small_buf) { | 401 | if (local_buf != small_buf) { |
397 | reiserfs_kfree(local_buf, d_reclen, inode->i_sb) ; | 402 | reiserfs_kfree(local_buf, d_reclen, |
398 | } | 403 | inode->i_sb); |
399 | goto end; | 404 | } |
400 | } | 405 | goto end; |
401 | if (local_buf != small_buf) { | 406 | } |
402 | reiserfs_kfree(local_buf, d_reclen, inode->i_sb) ; | 407 | if (local_buf != small_buf) { |
403 | } | 408 | reiserfs_kfree(local_buf, d_reclen, inode->i_sb); |
404 | } /* while */ | 409 | } |
410 | } /* while */ | ||
405 | 411 | ||
406 | end: | 412 | end: |
407 | pathrelse (&path_to_entry); | 413 | pathrelse(&path_to_entry); |
408 | return 0; | 414 | return 0; |
409 | } | 415 | } |
410 | 416 | ||
411 | /* | 417 | /* |
@@ -417,63 +423,59 @@ end: | |||
417 | static | 423 | static |
418 | int xattr_readdir(struct file *file, filldir_t filler, void *buf) | 424 | int xattr_readdir(struct file *file, filldir_t filler, void *buf) |
419 | { | 425 | { |
420 | struct inode *inode = file->f_dentry->d_inode; | 426 | struct inode *inode = file->f_dentry->d_inode; |
421 | int res = -ENOTDIR; | 427 | int res = -ENOTDIR; |
422 | if (!file->f_op || !file->f_op->readdir) | 428 | if (!file->f_op || !file->f_op->readdir) |
423 | goto out; | 429 | goto out; |
424 | down(&inode->i_sem); | 430 | down(&inode->i_sem); |
425 | // down(&inode->i_zombie); | 431 | // down(&inode->i_zombie); |
426 | res = -ENOENT; | 432 | res = -ENOENT; |
427 | if (!IS_DEADDIR(inode)) { | 433 | if (!IS_DEADDIR(inode)) { |
428 | lock_kernel(); | 434 | lock_kernel(); |
429 | res = __xattr_readdir(file, buf, filler); | 435 | res = __xattr_readdir(file, buf, filler); |
430 | unlock_kernel(); | 436 | unlock_kernel(); |
431 | } | 437 | } |
432 | // up(&inode->i_zombie); | 438 | // up(&inode->i_zombie); |
433 | up(&inode->i_sem); | 439 | up(&inode->i_sem); |
434 | out: | 440 | out: |
435 | return res; | 441 | return res; |
436 | } | 442 | } |
437 | 443 | ||
438 | |||
439 | /* Internal operations on file data */ | 444 | /* Internal operations on file data */ |
440 | static inline void | 445 | static inline void reiserfs_put_page(struct page *page) |
441 | reiserfs_put_page(struct page *page) | ||
442 | { | 446 | { |
443 | kunmap(page); | 447 | kunmap(page); |
444 | page_cache_release(page); | 448 | page_cache_release(page); |
445 | } | 449 | } |
446 | 450 | ||
447 | static struct page * | 451 | static struct page *reiserfs_get_page(struct inode *dir, unsigned long n) |
448 | reiserfs_get_page(struct inode *dir, unsigned long n) | ||
449 | { | 452 | { |
450 | struct address_space *mapping = dir->i_mapping; | 453 | struct address_space *mapping = dir->i_mapping; |
451 | struct page *page; | 454 | struct page *page; |
452 | /* We can deadlock if we try to free dentries, | 455 | /* We can deadlock if we try to free dentries, |
453 | and an unlink/rmdir has just occured - GFP_NOFS avoids this */ | 456 | and an unlink/rmdir has just occured - GFP_NOFS avoids this */ |
454 | mapping->flags = (mapping->flags & ~__GFP_BITS_MASK) | GFP_NOFS; | 457 | mapping->flags = (mapping->flags & ~__GFP_BITS_MASK) | GFP_NOFS; |
455 | page = read_cache_page (mapping, n, | 458 | page = read_cache_page(mapping, n, |
456 | (filler_t*)mapping->a_ops->readpage, NULL); | 459 | (filler_t *) mapping->a_ops->readpage, NULL); |
457 | if (!IS_ERR(page)) { | 460 | if (!IS_ERR(page)) { |
458 | wait_on_page_locked(page); | 461 | wait_on_page_locked(page); |
459 | kmap(page); | 462 | kmap(page); |
460 | if (!PageUptodate(page)) | 463 | if (!PageUptodate(page)) |
461 | goto fail; | 464 | goto fail; |
462 | 465 | ||
463 | if (PageError(page)) | 466 | if (PageError(page)) |
464 | goto fail; | 467 | goto fail; |
465 | } | 468 | } |
466 | return page; | 469 | return page; |
467 | 470 | ||
468 | fail: | 471 | fail: |
469 | reiserfs_put_page(page); | 472 | reiserfs_put_page(page); |
470 | return ERR_PTR(-EIO); | 473 | return ERR_PTR(-EIO); |
471 | } | 474 | } |
472 | 475 | ||
473 | static inline __u32 | 476 | static inline __u32 xattr_hash(const char *msg, int len) |
474 | xattr_hash (const char *msg, int len) | ||
475 | { | 477 | { |
476 | return csum_partial (msg, len, 0); | 478 | return csum_partial(msg, len, 0); |
477 | } | 479 | } |
478 | 480 | ||
479 | /* Generic extended attribute operations that can be used by xa plugins */ | 481 | /* Generic extended attribute operations that can be used by xa plugins */ |
@@ -482,294 +484,300 @@ xattr_hash (const char *msg, int len) | |||
482 | * inode->i_sem: down | 484 | * inode->i_sem: down |
483 | */ | 485 | */ |
484 | int | 486 | int |
485 | reiserfs_xattr_set (struct inode *inode, const char *name, const void *buffer, | 487 | reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, |
486 | size_t buffer_size, int flags) | 488 | size_t buffer_size, int flags) |
487 | { | 489 | { |
488 | int err = 0; | 490 | int err = 0; |
489 | struct file *fp; | 491 | struct file *fp; |
490 | struct page *page; | 492 | struct page *page; |
491 | char *data; | 493 | char *data; |
492 | struct address_space *mapping; | 494 | struct address_space *mapping; |
493 | size_t file_pos = 0; | 495 | size_t file_pos = 0; |
494 | size_t buffer_pos = 0; | 496 | size_t buffer_pos = 0; |
495 | struct inode *xinode; | 497 | struct inode *xinode; |
496 | struct iattr newattrs; | 498 | struct iattr newattrs; |
497 | __u32 xahash = 0; | 499 | __u32 xahash = 0; |
498 | 500 | ||
499 | if (IS_RDONLY (inode)) | 501 | if (IS_RDONLY(inode)) |
500 | return -EROFS; | 502 | return -EROFS; |
501 | 503 | ||
502 | if (IS_IMMUTABLE (inode) || IS_APPEND (inode)) | 504 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) |
503 | return -EPERM; | 505 | return -EPERM; |
504 | 506 | ||
505 | if (get_inode_sd_version (inode) == STAT_DATA_V1) | 507 | if (get_inode_sd_version(inode) == STAT_DATA_V1) |
506 | return -EOPNOTSUPP; | 508 | return -EOPNOTSUPP; |
507 | 509 | ||
508 | /* Empty xattrs are ok, they're just empty files, no hash */ | 510 | /* Empty xattrs are ok, they're just empty files, no hash */ |
509 | if (buffer && buffer_size) | 511 | if (buffer && buffer_size) |
510 | xahash = xattr_hash (buffer, buffer_size); | 512 | xahash = xattr_hash(buffer, buffer_size); |
511 | 513 | ||
512 | open_file: | 514 | open_file: |
513 | fp = open_xa_file (inode, name, flags); | 515 | fp = open_xa_file(inode, name, flags); |
514 | if (IS_ERR (fp)) { | 516 | if (IS_ERR(fp)) { |
515 | err = PTR_ERR (fp); | 517 | err = PTR_ERR(fp); |
516 | goto out; | 518 | goto out; |
517 | } | 519 | } |
518 | 520 | ||
519 | xinode = fp->f_dentry->d_inode; | 521 | xinode = fp->f_dentry->d_inode; |
520 | REISERFS_I(inode)->i_flags |= i_has_xattr_dir; | 522 | REISERFS_I(inode)->i_flags |= i_has_xattr_dir; |
521 | 523 | ||
522 | /* we need to copy it off.. */ | 524 | /* we need to copy it off.. */ |
523 | if (xinode->i_nlink > 1) { | 525 | if (xinode->i_nlink > 1) { |
524 | fput(fp); | 526 | fput(fp); |
525 | err = reiserfs_xattr_del (inode, name); | 527 | err = reiserfs_xattr_del(inode, name); |
526 | if (err < 0) | 528 | if (err < 0) |
527 | goto out; | 529 | goto out; |
528 | /* We just killed the old one, we're not replacing anymore */ | 530 | /* We just killed the old one, we're not replacing anymore */ |
529 | if (flags & XATTR_REPLACE) | 531 | if (flags & XATTR_REPLACE) |
530 | flags &= ~XATTR_REPLACE; | 532 | flags &= ~XATTR_REPLACE; |
531 | goto open_file; | 533 | goto open_file; |
532 | } | 534 | } |
533 | 535 | ||
534 | /* Resize it so we're ok to write there */ | 536 | /* Resize it so we're ok to write there */ |
535 | newattrs.ia_size = buffer_size; | 537 | newattrs.ia_size = buffer_size; |
536 | newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; | 538 | newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; |
537 | down (&xinode->i_sem); | 539 | down(&xinode->i_sem); |
538 | err = notify_change(fp->f_dentry, &newattrs); | 540 | err = notify_change(fp->f_dentry, &newattrs); |
539 | if (err) | 541 | if (err) |
540 | goto out_filp; | 542 | goto out_filp; |
541 | 543 | ||
542 | mapping = xinode->i_mapping; | 544 | mapping = xinode->i_mapping; |
543 | while (buffer_pos < buffer_size || buffer_pos == 0) { | 545 | while (buffer_pos < buffer_size || buffer_pos == 0) { |
544 | size_t chunk; | 546 | size_t chunk; |
545 | size_t skip = 0; | 547 | size_t skip = 0; |
546 | size_t page_offset = (file_pos & (PAGE_CACHE_SIZE - 1)); | 548 | size_t page_offset = (file_pos & (PAGE_CACHE_SIZE - 1)); |
547 | if (buffer_size - buffer_pos > PAGE_CACHE_SIZE) | 549 | if (buffer_size - buffer_pos > PAGE_CACHE_SIZE) |
548 | chunk = PAGE_CACHE_SIZE; | 550 | chunk = PAGE_CACHE_SIZE; |
549 | else | 551 | else |
550 | chunk = buffer_size - buffer_pos; | 552 | chunk = buffer_size - buffer_pos; |
551 | 553 | ||
552 | page = reiserfs_get_page (xinode, file_pos >> PAGE_CACHE_SHIFT); | 554 | page = reiserfs_get_page(xinode, file_pos >> PAGE_CACHE_SHIFT); |
553 | if (IS_ERR (page)) { | 555 | if (IS_ERR(page)) { |
554 | err = PTR_ERR (page); | 556 | err = PTR_ERR(page); |
555 | goto out_filp; | 557 | goto out_filp; |
556 | } | 558 | } |
557 | 559 | ||
558 | lock_page (page); | 560 | lock_page(page); |
559 | data = page_address (page); | 561 | data = page_address(page); |
560 | 562 | ||
561 | if (file_pos == 0) { | 563 | if (file_pos == 0) { |
562 | struct reiserfs_xattr_header *rxh; | 564 | struct reiserfs_xattr_header *rxh; |
563 | skip = file_pos = sizeof (struct reiserfs_xattr_header); | 565 | skip = file_pos = sizeof(struct reiserfs_xattr_header); |
564 | if (chunk + skip > PAGE_CACHE_SIZE) | 566 | if (chunk + skip > PAGE_CACHE_SIZE) |
565 | chunk = PAGE_CACHE_SIZE - skip; | 567 | chunk = PAGE_CACHE_SIZE - skip; |
566 | rxh = (struct reiserfs_xattr_header *)data; | 568 | rxh = (struct reiserfs_xattr_header *)data; |
567 | rxh->h_magic = cpu_to_le32 (REISERFS_XATTR_MAGIC); | 569 | rxh->h_magic = cpu_to_le32(REISERFS_XATTR_MAGIC); |
568 | rxh->h_hash = cpu_to_le32 (xahash); | 570 | rxh->h_hash = cpu_to_le32(xahash); |
569 | } | 571 | } |
570 | 572 | ||
571 | err = mapping->a_ops->prepare_write (fp, page, page_offset, | 573 | err = mapping->a_ops->prepare_write(fp, page, page_offset, |
572 | page_offset + chunk + skip); | 574 | page_offset + chunk + skip); |
573 | if (!err) { | 575 | if (!err) { |
574 | if (buffer) | 576 | if (buffer) |
575 | memcpy (data + skip, buffer + buffer_pos, chunk); | 577 | memcpy(data + skip, buffer + buffer_pos, chunk); |
576 | err = mapping->a_ops->commit_write (fp, page, page_offset, | 578 | err = |
577 | page_offset + chunk + skip); | 579 | mapping->a_ops->commit_write(fp, page, page_offset, |
580 | page_offset + chunk + | ||
581 | skip); | ||
582 | } | ||
583 | unlock_page(page); | ||
584 | reiserfs_put_page(page); | ||
585 | buffer_pos += chunk; | ||
586 | file_pos += chunk; | ||
587 | skip = 0; | ||
588 | if (err || buffer_size == 0 || !buffer) | ||
589 | break; | ||
590 | } | ||
591 | |||
592 | /* We can't mark the inode dirty if it's not hashed. This is the case | ||
593 | * when we're inheriting the default ACL. If we dirty it, the inode | ||
594 | * gets marked dirty, but won't (ever) make it onto the dirty list until | ||
595 | * it's synced explicitly to clear I_DIRTY. This is bad. */ | ||
596 | if (!hlist_unhashed(&inode->i_hash)) { | ||
597 | inode->i_ctime = CURRENT_TIME_SEC; | ||
598 | mark_inode_dirty(inode); | ||
578 | } | 599 | } |
579 | unlock_page (page); | 600 | |
580 | reiserfs_put_page (page); | 601 | out_filp: |
581 | buffer_pos += chunk; | 602 | up(&xinode->i_sem); |
582 | file_pos += chunk; | 603 | fput(fp); |
583 | skip = 0; | 604 | |
584 | if (err || buffer_size == 0 || !buffer) | 605 | out: |
585 | break; | 606 | return err; |
586 | } | ||
587 | |||
588 | /* We can't mark the inode dirty if it's not hashed. This is the case | ||
589 | * when we're inheriting the default ACL. If we dirty it, the inode | ||
590 | * gets marked dirty, but won't (ever) make it onto the dirty list until | ||
591 | * it's synced explicitly to clear I_DIRTY. This is bad. */ | ||
592 | if (!hlist_unhashed(&inode->i_hash)) { | ||
593 | inode->i_ctime = CURRENT_TIME_SEC; | ||
594 | mark_inode_dirty (inode); | ||
595 | } | ||
596 | |||
597 | out_filp: | ||
598 | up (&xinode->i_sem); | ||
599 | fput(fp); | ||
600 | |||
601 | out: | ||
602 | return err; | ||
603 | } | 607 | } |
604 | 608 | ||
605 | /* | 609 | /* |
606 | * inode->i_sem: down | 610 | * inode->i_sem: down |
607 | */ | 611 | */ |
608 | int | 612 | int |
609 | reiserfs_xattr_get (const struct inode *inode, const char *name, void *buffer, | 613 | reiserfs_xattr_get(const struct inode *inode, const char *name, void *buffer, |
610 | size_t buffer_size) | 614 | size_t buffer_size) |
611 | { | 615 | { |
612 | ssize_t err = 0; | 616 | ssize_t err = 0; |
613 | struct file *fp; | 617 | struct file *fp; |
614 | size_t isize; | 618 | size_t isize; |
615 | size_t file_pos = 0; | 619 | size_t file_pos = 0; |
616 | size_t buffer_pos = 0; | 620 | size_t buffer_pos = 0; |
617 | struct page *page; | 621 | struct page *page; |
618 | struct inode *xinode; | 622 | struct inode *xinode; |
619 | __u32 hash = 0; | 623 | __u32 hash = 0; |
620 | 624 | ||
621 | if (name == NULL) | 625 | if (name == NULL) |
622 | return -EINVAL; | 626 | return -EINVAL; |
623 | 627 | ||
624 | /* We can't have xattrs attached to v1 items since they don't have | 628 | /* We can't have xattrs attached to v1 items since they don't have |
625 | * generation numbers */ | 629 | * generation numbers */ |
626 | if (get_inode_sd_version (inode) == STAT_DATA_V1) | 630 | if (get_inode_sd_version(inode) == STAT_DATA_V1) |
627 | return -EOPNOTSUPP; | 631 | return -EOPNOTSUPP; |
628 | 632 | ||
629 | fp = open_xa_file (inode, name, FL_READONLY); | 633 | fp = open_xa_file(inode, name, FL_READONLY); |
630 | if (IS_ERR (fp)) { | 634 | if (IS_ERR(fp)) { |
631 | err = PTR_ERR (fp); | 635 | err = PTR_ERR(fp); |
632 | goto out; | 636 | goto out; |
633 | } | 637 | } |
634 | 638 | ||
635 | xinode = fp->f_dentry->d_inode; | 639 | xinode = fp->f_dentry->d_inode; |
636 | isize = xinode->i_size; | 640 | isize = xinode->i_size; |
637 | REISERFS_I(inode)->i_flags |= i_has_xattr_dir; | 641 | REISERFS_I(inode)->i_flags |= i_has_xattr_dir; |
638 | 642 | ||
639 | /* Just return the size needed */ | 643 | /* Just return the size needed */ |
640 | if (buffer == NULL) { | 644 | if (buffer == NULL) { |
641 | err = isize - sizeof (struct reiserfs_xattr_header); | 645 | err = isize - sizeof(struct reiserfs_xattr_header); |
642 | goto out_dput; | 646 | goto out_dput; |
643 | } | 647 | } |
644 | 648 | ||
645 | if (buffer_size < isize - sizeof (struct reiserfs_xattr_header)) { | 649 | if (buffer_size < isize - sizeof(struct reiserfs_xattr_header)) { |
646 | err = -ERANGE; | 650 | err = -ERANGE; |
647 | goto out_dput; | 651 | goto out_dput; |
648 | } | 652 | } |
649 | 653 | ||
650 | while (file_pos < isize) { | 654 | while (file_pos < isize) { |
651 | size_t chunk; | 655 | size_t chunk; |
652 | char *data; | 656 | char *data; |
653 | size_t skip = 0; | 657 | size_t skip = 0; |
654 | if (isize - file_pos > PAGE_CACHE_SIZE) | 658 | if (isize - file_pos > PAGE_CACHE_SIZE) |
655 | chunk = PAGE_CACHE_SIZE; | 659 | chunk = PAGE_CACHE_SIZE; |
656 | else | 660 | else |
657 | chunk = isize - file_pos; | 661 | chunk = isize - file_pos; |
658 | 662 | ||
659 | page = reiserfs_get_page (xinode, file_pos >> PAGE_CACHE_SHIFT); | 663 | page = reiserfs_get_page(xinode, file_pos >> PAGE_CACHE_SHIFT); |
660 | if (IS_ERR (page)) { | 664 | if (IS_ERR(page)) { |
661 | err = PTR_ERR (page); | 665 | err = PTR_ERR(page); |
662 | goto out_dput; | 666 | goto out_dput; |
663 | } | 667 | } |
664 | 668 | ||
665 | lock_page (page); | 669 | lock_page(page); |
666 | data = page_address (page); | 670 | data = page_address(page); |
667 | if (file_pos == 0) { | 671 | if (file_pos == 0) { |
668 | struct reiserfs_xattr_header *rxh = | 672 | struct reiserfs_xattr_header *rxh = |
669 | (struct reiserfs_xattr_header *)data; | 673 | (struct reiserfs_xattr_header *)data; |
670 | skip = file_pos = sizeof (struct reiserfs_xattr_header); | 674 | skip = file_pos = sizeof(struct reiserfs_xattr_header); |
671 | chunk -= skip; | 675 | chunk -= skip; |
672 | /* Magic doesn't match up.. */ | 676 | /* Magic doesn't match up.. */ |
673 | if (rxh->h_magic != cpu_to_le32 (REISERFS_XATTR_MAGIC)) { | 677 | if (rxh->h_magic != cpu_to_le32(REISERFS_XATTR_MAGIC)) { |
674 | unlock_page (page); | 678 | unlock_page(page); |
675 | reiserfs_put_page (page); | 679 | reiserfs_put_page(page); |
676 | reiserfs_warning (inode->i_sb, "Invalid magic for xattr (%s) " | 680 | reiserfs_warning(inode->i_sb, |
677 | "associated with %k", name, | 681 | "Invalid magic for xattr (%s) " |
678 | INODE_PKEY (inode)); | 682 | "associated with %k", name, |
679 | err = -EIO; | 683 | INODE_PKEY(inode)); |
680 | goto out_dput; | 684 | err = -EIO; |
681 | } | 685 | goto out_dput; |
682 | hash = le32_to_cpu (rxh->h_hash); | 686 | } |
683 | } | 687 | hash = le32_to_cpu(rxh->h_hash); |
684 | memcpy (buffer + buffer_pos, data + skip, chunk); | 688 | } |
685 | unlock_page (page); | 689 | memcpy(buffer + buffer_pos, data + skip, chunk); |
686 | reiserfs_put_page (page); | 690 | unlock_page(page); |
687 | file_pos += chunk; | 691 | reiserfs_put_page(page); |
688 | buffer_pos += chunk; | 692 | file_pos += chunk; |
689 | skip = 0; | 693 | buffer_pos += chunk; |
690 | } | 694 | skip = 0; |
691 | err = isize - sizeof (struct reiserfs_xattr_header); | 695 | } |
692 | 696 | err = isize - sizeof(struct reiserfs_xattr_header); | |
693 | if (xattr_hash (buffer, isize - sizeof (struct reiserfs_xattr_header)) != hash) { | 697 | |
694 | reiserfs_warning (inode->i_sb, "Invalid hash for xattr (%s) associated " | 698 | if (xattr_hash(buffer, isize - sizeof(struct reiserfs_xattr_header)) != |
695 | "with %k", name, INODE_PKEY (inode)); | 699 | hash) { |
696 | err = -EIO; | 700 | reiserfs_warning(inode->i_sb, |
697 | } | 701 | "Invalid hash for xattr (%s) associated " |
698 | 702 | "with %k", name, INODE_PKEY(inode)); | |
699 | out_dput: | 703 | err = -EIO; |
700 | fput(fp); | 704 | } |
701 | 705 | ||
702 | out: | 706 | out_dput: |
703 | return err; | 707 | fput(fp); |
708 | |||
709 | out: | ||
710 | return err; | ||
704 | } | 711 | } |
705 | 712 | ||
706 | static int | 713 | static int |
707 | __reiserfs_xattr_del (struct dentry *xadir, const char *name, int namelen) | 714 | __reiserfs_xattr_del(struct dentry *xadir, const char *name, int namelen) |
708 | { | 715 | { |
709 | struct dentry *dentry; | 716 | struct dentry *dentry; |
710 | struct inode *dir = xadir->d_inode; | 717 | struct inode *dir = xadir->d_inode; |
711 | int err = 0; | 718 | int err = 0; |
712 | 719 | ||
713 | dentry = lookup_one_len (name, xadir, namelen); | 720 | dentry = lookup_one_len(name, xadir, namelen); |
714 | if (IS_ERR (dentry)) { | 721 | if (IS_ERR(dentry)) { |
715 | err = PTR_ERR (dentry); | 722 | err = PTR_ERR(dentry); |
716 | goto out; | 723 | goto out; |
717 | } else if (!dentry->d_inode) { | 724 | } else if (!dentry->d_inode) { |
718 | err = -ENODATA; | 725 | err = -ENODATA; |
719 | goto out_file; | 726 | goto out_file; |
720 | } | 727 | } |
721 | 728 | ||
722 | /* Skip directories.. */ | 729 | /* Skip directories.. */ |
723 | if (S_ISDIR (dentry->d_inode->i_mode)) | 730 | if (S_ISDIR(dentry->d_inode->i_mode)) |
724 | goto out_file; | 731 | goto out_file; |
725 | 732 | ||
726 | if (!is_reiserfs_priv_object (dentry->d_inode)) { | 733 | if (!is_reiserfs_priv_object(dentry->d_inode)) { |
727 | reiserfs_warning (dir->i_sb, "OID %08x [%.*s/%.*s] doesn't have " | 734 | reiserfs_warning(dir->i_sb, "OID %08x [%.*s/%.*s] doesn't have " |
728 | "priv flag set [parent is %sset].", | 735 | "priv flag set [parent is %sset].", |
729 | le32_to_cpu (INODE_PKEY (dentry->d_inode)->k_objectid), | 736 | le32_to_cpu(INODE_PKEY(dentry->d_inode)-> |
730 | xadir->d_name.len, xadir->d_name.name, namelen, name, | 737 | k_objectid), xadir->d_name.len, |
731 | is_reiserfs_priv_object (xadir->d_inode) ? "" : "not "); | 738 | xadir->d_name.name, namelen, name, |
732 | dput (dentry); | 739 | is_reiserfs_priv_object(xadir-> |
733 | return -EIO; | 740 | d_inode) ? "" : |
734 | } | 741 | "not "); |
735 | 742 | dput(dentry); | |
736 | err = dir->i_op->unlink (dir, dentry); | 743 | return -EIO; |
737 | if (!err) | 744 | } |
738 | d_delete (dentry); | ||
739 | |||
740 | out_file: | ||
741 | dput (dentry); | ||
742 | |||
743 | out: | ||
744 | return err; | ||
745 | } | ||
746 | 745 | ||
746 | err = dir->i_op->unlink(dir, dentry); | ||
747 | if (!err) | ||
748 | d_delete(dentry); | ||
747 | 749 | ||
748 | int | 750 | out_file: |
749 | reiserfs_xattr_del (struct inode *inode, const char *name) | 751 | dput(dentry); |
752 | |||
753 | out: | ||
754 | return err; | ||
755 | } | ||
756 | |||
757 | int reiserfs_xattr_del(struct inode *inode, const char *name) | ||
750 | { | 758 | { |
751 | struct dentry *dir; | 759 | struct dentry *dir; |
752 | int err; | 760 | int err; |
753 | 761 | ||
754 | if (IS_RDONLY (inode)) | 762 | if (IS_RDONLY(inode)) |
755 | return -EROFS; | 763 | return -EROFS; |
756 | 764 | ||
757 | dir = open_xa_dir (inode, FL_READONLY); | 765 | dir = open_xa_dir(inode, FL_READONLY); |
758 | if (IS_ERR (dir)) { | 766 | if (IS_ERR(dir)) { |
759 | err = PTR_ERR (dir); | 767 | err = PTR_ERR(dir); |
760 | goto out; | 768 | goto out; |
761 | } | 769 | } |
762 | 770 | ||
763 | err = __reiserfs_xattr_del (dir, name, strlen (name)); | 771 | err = __reiserfs_xattr_del(dir, name, strlen(name)); |
764 | dput (dir); | 772 | dput(dir); |
765 | 773 | ||
766 | if (!err) { | 774 | if (!err) { |
767 | inode->i_ctime = CURRENT_TIME_SEC; | 775 | inode->i_ctime = CURRENT_TIME_SEC; |
768 | mark_inode_dirty (inode); | 776 | mark_inode_dirty(inode); |
769 | } | 777 | } |
770 | 778 | ||
771 | out: | 779 | out: |
772 | return err; | 780 | return err; |
773 | } | 781 | } |
774 | 782 | ||
775 | /* The following are side effects of other operations that aren't explicitly | 783 | /* The following are side effects of other operations that aren't explicitly |
@@ -777,167 +785,163 @@ out: | |||
777 | * or ownership changes, object deletions, etc. */ | 785 | * or ownership changes, object deletions, etc. */ |
778 | 786 | ||
779 | static int | 787 | static int |
780 | reiserfs_delete_xattrs_filler (void *buf, const char *name, int namelen, | 788 | reiserfs_delete_xattrs_filler(void *buf, const char *name, int namelen, |
781 | loff_t offset, ino_t ino, unsigned int d_type) | 789 | loff_t offset, ino_t ino, unsigned int d_type) |
782 | { | 790 | { |
783 | struct dentry *xadir = (struct dentry *)buf; | 791 | struct dentry *xadir = (struct dentry *)buf; |
784 | 792 | ||
785 | return __reiserfs_xattr_del (xadir, name, namelen); | 793 | return __reiserfs_xattr_del(xadir, name, namelen); |
786 | 794 | ||
787 | } | 795 | } |
788 | 796 | ||
789 | /* This is called w/ inode->i_sem downed */ | 797 | /* This is called w/ inode->i_sem downed */ |
790 | int | 798 | int reiserfs_delete_xattrs(struct inode *inode) |
791 | reiserfs_delete_xattrs (struct inode *inode) | ||
792 | { | 799 | { |
793 | struct file *fp; | 800 | struct file *fp; |
794 | struct dentry *dir, *root; | 801 | struct dentry *dir, *root; |
795 | int err = 0; | 802 | int err = 0; |
796 | 803 | ||
797 | /* Skip out, an xattr has no xattrs associated with it */ | 804 | /* Skip out, an xattr has no xattrs associated with it */ |
798 | if (is_reiserfs_priv_object (inode) || | 805 | if (is_reiserfs_priv_object(inode) || |
799 | get_inode_sd_version (inode) == STAT_DATA_V1 || | 806 | get_inode_sd_version(inode) == STAT_DATA_V1 || |
800 | !reiserfs_xattrs(inode->i_sb)) | 807 | !reiserfs_xattrs(inode->i_sb)) { |
801 | { | 808 | return 0; |
802 | return 0; | 809 | } |
803 | } | 810 | reiserfs_read_lock_xattrs(inode->i_sb); |
804 | reiserfs_read_lock_xattrs (inode->i_sb); | 811 | dir = open_xa_dir(inode, FL_READONLY); |
805 | dir = open_xa_dir (inode, FL_READONLY); | 812 | reiserfs_read_unlock_xattrs(inode->i_sb); |
806 | reiserfs_read_unlock_xattrs (inode->i_sb); | 813 | if (IS_ERR(dir)) { |
807 | if (IS_ERR (dir)) { | 814 | err = PTR_ERR(dir); |
808 | err = PTR_ERR (dir); | 815 | goto out; |
809 | goto out; | 816 | } else if (!dir->d_inode) { |
810 | } else if (!dir->d_inode) { | 817 | dput(dir); |
811 | dput (dir); | 818 | return 0; |
812 | return 0; | 819 | } |
813 | } | 820 | |
814 | 821 | fp = dentry_open(dir, NULL, O_RDWR); | |
815 | fp = dentry_open (dir, NULL, O_RDWR); | 822 | if (IS_ERR(fp)) { |
816 | if (IS_ERR (fp)) { | 823 | err = PTR_ERR(fp); |
817 | err = PTR_ERR (fp); | 824 | /* dentry_open dputs the dentry if it fails */ |
818 | /* dentry_open dputs the dentry if it fails */ | 825 | goto out; |
819 | goto out; | 826 | } |
820 | } | 827 | |
821 | 828 | lock_kernel(); | |
822 | lock_kernel (); | 829 | err = xattr_readdir(fp, reiserfs_delete_xattrs_filler, dir); |
823 | err = xattr_readdir (fp, reiserfs_delete_xattrs_filler, dir); | 830 | if (err) { |
824 | if (err) { | 831 | unlock_kernel(); |
825 | unlock_kernel (); | 832 | goto out_dir; |
826 | goto out_dir; | 833 | } |
827 | } | 834 | |
828 | 835 | /* Leftovers besides . and .. -- that's not good. */ | |
829 | /* Leftovers besides . and .. -- that's not good. */ | 836 | if (dir->d_inode->i_nlink <= 2) { |
830 | if (dir->d_inode->i_nlink <= 2) { | 837 | root = get_xa_root(inode->i_sb); |
831 | root = get_xa_root (inode->i_sb); | 838 | reiserfs_write_lock_xattrs(inode->i_sb); |
832 | reiserfs_write_lock_xattrs (inode->i_sb); | 839 | err = vfs_rmdir(root->d_inode, dir); |
833 | err = vfs_rmdir (root->d_inode, dir); | 840 | reiserfs_write_unlock_xattrs(inode->i_sb); |
834 | reiserfs_write_unlock_xattrs (inode->i_sb); | 841 | dput(root); |
835 | dput (root); | 842 | } else { |
836 | } else { | 843 | reiserfs_warning(inode->i_sb, |
837 | reiserfs_warning (inode->i_sb, | 844 | "Couldn't remove all entries in directory"); |
838 | "Couldn't remove all entries in directory"); | 845 | } |
839 | } | 846 | unlock_kernel(); |
840 | unlock_kernel (); | 847 | |
841 | 848 | out_dir: | |
842 | out_dir: | 849 | fput(fp); |
843 | fput(fp); | 850 | |
844 | 851 | out: | |
845 | out: | 852 | if (!err) |
846 | if (!err) | 853 | REISERFS_I(inode)->i_flags = |
847 | REISERFS_I(inode)->i_flags = REISERFS_I(inode)->i_flags & ~i_has_xattr_dir; | 854 | REISERFS_I(inode)->i_flags & ~i_has_xattr_dir; |
848 | return err; | 855 | return err; |
849 | } | 856 | } |
850 | 857 | ||
851 | struct reiserfs_chown_buf { | 858 | struct reiserfs_chown_buf { |
852 | struct inode *inode; | 859 | struct inode *inode; |
853 | struct dentry *xadir; | 860 | struct dentry *xadir; |
854 | struct iattr *attrs; | 861 | struct iattr *attrs; |
855 | }; | 862 | }; |
856 | 863 | ||
857 | /* XXX: If there is a better way to do this, I'd love to hear about it */ | 864 | /* XXX: If there is a better way to do this, I'd love to hear about it */ |
858 | static int | 865 | static int |
859 | reiserfs_chown_xattrs_filler (void *buf, const char *name, int namelen, | 866 | reiserfs_chown_xattrs_filler(void *buf, const char *name, int namelen, |
860 | loff_t offset, ino_t ino, unsigned int d_type) | 867 | loff_t offset, ino_t ino, unsigned int d_type) |
861 | { | 868 | { |
862 | struct reiserfs_chown_buf *chown_buf = (struct reiserfs_chown_buf *)buf; | 869 | struct reiserfs_chown_buf *chown_buf = (struct reiserfs_chown_buf *)buf; |
863 | struct dentry *xafile, *xadir = chown_buf->xadir; | 870 | struct dentry *xafile, *xadir = chown_buf->xadir; |
864 | struct iattr *attrs = chown_buf->attrs; | 871 | struct iattr *attrs = chown_buf->attrs; |
865 | int err = 0; | 872 | int err = 0; |
866 | 873 | ||
867 | xafile = lookup_one_len (name, xadir, namelen); | 874 | xafile = lookup_one_len(name, xadir, namelen); |
868 | if (IS_ERR (xafile)) | 875 | if (IS_ERR(xafile)) |
869 | return PTR_ERR (xafile); | 876 | return PTR_ERR(xafile); |
870 | else if (!xafile->d_inode) { | 877 | else if (!xafile->d_inode) { |
871 | dput (xafile); | 878 | dput(xafile); |
872 | return -ENODATA; | 879 | return -ENODATA; |
873 | } | 880 | } |
874 | 881 | ||
875 | if (!S_ISDIR (xafile->d_inode->i_mode)) | 882 | if (!S_ISDIR(xafile->d_inode->i_mode)) |
876 | err = notify_change (xafile, attrs); | 883 | err = notify_change(xafile, attrs); |
877 | dput (xafile); | 884 | dput(xafile); |
878 | 885 | ||
879 | return err; | 886 | return err; |
880 | } | 887 | } |
881 | 888 | ||
882 | int | 889 | int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs) |
883 | reiserfs_chown_xattrs (struct inode *inode, struct iattr *attrs) | ||
884 | { | 890 | { |
885 | struct file *fp; | 891 | struct file *fp; |
886 | struct dentry *dir; | 892 | struct dentry *dir; |
887 | int err = 0; | 893 | int err = 0; |
888 | struct reiserfs_chown_buf buf; | 894 | struct reiserfs_chown_buf buf; |
889 | unsigned int ia_valid = attrs->ia_valid; | 895 | unsigned int ia_valid = attrs->ia_valid; |
890 | 896 | ||
891 | /* Skip out, an xattr has no xattrs associated with it */ | 897 | /* Skip out, an xattr has no xattrs associated with it */ |
892 | if (is_reiserfs_priv_object (inode) || | 898 | if (is_reiserfs_priv_object(inode) || |
893 | get_inode_sd_version (inode) == STAT_DATA_V1 || | 899 | get_inode_sd_version(inode) == STAT_DATA_V1 || |
894 | !reiserfs_xattrs(inode->i_sb)) | 900 | !reiserfs_xattrs(inode->i_sb)) { |
895 | { | 901 | return 0; |
896 | return 0; | 902 | } |
897 | } | 903 | reiserfs_read_lock_xattrs(inode->i_sb); |
898 | reiserfs_read_lock_xattrs (inode->i_sb); | 904 | dir = open_xa_dir(inode, FL_READONLY); |
899 | dir = open_xa_dir (inode, FL_READONLY); | 905 | reiserfs_read_unlock_xattrs(inode->i_sb); |
900 | reiserfs_read_unlock_xattrs (inode->i_sb); | 906 | if (IS_ERR(dir)) { |
901 | if (IS_ERR (dir)) { | 907 | if (PTR_ERR(dir) != -ENODATA) |
902 | if (PTR_ERR (dir) != -ENODATA) | 908 | err = PTR_ERR(dir); |
903 | err = PTR_ERR (dir); | 909 | goto out; |
904 | goto out; | 910 | } else if (!dir->d_inode) { |
905 | } else if (!dir->d_inode) { | 911 | dput(dir); |
906 | dput (dir); | 912 | goto out; |
907 | goto out; | 913 | } |
908 | } | 914 | |
909 | 915 | fp = dentry_open(dir, NULL, O_RDWR); | |
910 | fp = dentry_open (dir, NULL, O_RDWR); | 916 | if (IS_ERR(fp)) { |
911 | if (IS_ERR (fp)) { | 917 | err = PTR_ERR(fp); |
912 | err = PTR_ERR (fp); | 918 | /* dentry_open dputs the dentry if it fails */ |
913 | /* dentry_open dputs the dentry if it fails */ | 919 | goto out; |
914 | goto out; | 920 | } |
915 | } | ||
916 | |||
917 | lock_kernel (); | ||
918 | |||
919 | attrs->ia_valid &= (ATTR_UID | ATTR_GID | ATTR_CTIME); | ||
920 | buf.xadir = dir; | ||
921 | buf.attrs = attrs; | ||
922 | buf.inode = inode; | ||
923 | |||
924 | err = xattr_readdir (fp, reiserfs_chown_xattrs_filler, &buf); | ||
925 | if (err) { | ||
926 | unlock_kernel (); | ||
927 | goto out_dir; | ||
928 | } | ||
929 | |||
930 | err = notify_change (dir, attrs); | ||
931 | unlock_kernel (); | ||
932 | |||
933 | out_dir: | ||
934 | fput(fp); | ||
935 | |||
936 | out: | ||
937 | attrs->ia_valid = ia_valid; | ||
938 | return err; | ||
939 | } | ||
940 | 921 | ||
922 | lock_kernel(); | ||
923 | |||
924 | attrs->ia_valid &= (ATTR_UID | ATTR_GID | ATTR_CTIME); | ||
925 | buf.xadir = dir; | ||
926 | buf.attrs = attrs; | ||
927 | buf.inode = inode; | ||
928 | |||
929 | err = xattr_readdir(fp, reiserfs_chown_xattrs_filler, &buf); | ||
930 | if (err) { | ||
931 | unlock_kernel(); | ||
932 | goto out_dir; | ||
933 | } | ||
934 | |||
935 | err = notify_change(dir, attrs); | ||
936 | unlock_kernel(); | ||
937 | |||
938 | out_dir: | ||
939 | fput(fp); | ||
940 | |||
941 | out: | ||
942 | attrs->ia_valid = ia_valid; | ||
943 | return err; | ||
944 | } | ||
941 | 945 | ||
942 | /* Actual operations that are exported to VFS-land */ | 946 | /* Actual operations that are exported to VFS-land */ |
943 | 947 | ||
@@ -946,61 +950,60 @@ out: | |||
946 | * Preliminary locking: we down dentry->d_inode->i_sem | 950 | * Preliminary locking: we down dentry->d_inode->i_sem |
947 | */ | 951 | */ |
948 | ssize_t | 952 | ssize_t |
949 | reiserfs_getxattr (struct dentry *dentry, const char *name, void *buffer, | 953 | reiserfs_getxattr(struct dentry * dentry, const char *name, void *buffer, |
950 | size_t size) | 954 | size_t size) |
951 | { | 955 | { |
952 | struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix (name); | 956 | struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix(name); |
953 | int err; | 957 | int err; |
954 | 958 | ||
955 | if (!xah || !reiserfs_xattrs(dentry->d_sb) || | 959 | if (!xah || !reiserfs_xattrs(dentry->d_sb) || |
956 | get_inode_sd_version (dentry->d_inode) == STAT_DATA_V1) | 960 | get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1) |
957 | return -EOPNOTSUPP; | 961 | return -EOPNOTSUPP; |
958 | 962 | ||
959 | reiserfs_read_lock_xattr_i (dentry->d_inode); | 963 | reiserfs_read_lock_xattr_i(dentry->d_inode); |
960 | reiserfs_read_lock_xattrs (dentry->d_sb); | 964 | reiserfs_read_lock_xattrs(dentry->d_sb); |
961 | err = xah->get (dentry->d_inode, name, buffer, size); | 965 | err = xah->get(dentry->d_inode, name, buffer, size); |
962 | reiserfs_read_unlock_xattrs (dentry->d_sb); | 966 | reiserfs_read_unlock_xattrs(dentry->d_sb); |
963 | reiserfs_read_unlock_xattr_i (dentry->d_inode); | 967 | reiserfs_read_unlock_xattr_i(dentry->d_inode); |
964 | return err; | 968 | return err; |
965 | } | 969 | } |
966 | 970 | ||
967 | |||
968 | /* | 971 | /* |
969 | * Inode operation setxattr() | 972 | * Inode operation setxattr() |
970 | * | 973 | * |
971 | * dentry->d_inode->i_sem down | 974 | * dentry->d_inode->i_sem down |
972 | */ | 975 | */ |
973 | int | 976 | int |
974 | reiserfs_setxattr (struct dentry *dentry, const char *name, const void *value, | 977 | reiserfs_setxattr(struct dentry *dentry, const char *name, const void *value, |
975 | size_t size, int flags) | 978 | size_t size, int flags) |
976 | { | 979 | { |
977 | struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix (name); | 980 | struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix(name); |
978 | int err; | 981 | int err; |
979 | int lock; | 982 | int lock; |
980 | 983 | ||
981 | if (!xah || !reiserfs_xattrs(dentry->d_sb) || | 984 | if (!xah || !reiserfs_xattrs(dentry->d_sb) || |
982 | get_inode_sd_version (dentry->d_inode) == STAT_DATA_V1) | 985 | get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1) |
983 | return -EOPNOTSUPP; | 986 | return -EOPNOTSUPP; |
984 | 987 | ||
985 | if (IS_RDONLY (dentry->d_inode)) | 988 | if (IS_RDONLY(dentry->d_inode)) |
986 | return -EROFS; | 989 | return -EROFS; |
987 | 990 | ||
988 | if (IS_IMMUTABLE (dentry->d_inode) || IS_APPEND (dentry->d_inode)) | 991 | if (IS_IMMUTABLE(dentry->d_inode) || IS_APPEND(dentry->d_inode)) |
989 | return -EROFS; | 992 | return -EROFS; |
990 | 993 | ||
991 | reiserfs_write_lock_xattr_i (dentry->d_inode); | 994 | reiserfs_write_lock_xattr_i(dentry->d_inode); |
992 | lock = !has_xattr_dir (dentry->d_inode); | 995 | lock = !has_xattr_dir(dentry->d_inode); |
993 | if (lock) | 996 | if (lock) |
994 | reiserfs_write_lock_xattrs (dentry->d_sb); | 997 | reiserfs_write_lock_xattrs(dentry->d_sb); |
995 | else | 998 | else |
996 | reiserfs_read_lock_xattrs (dentry->d_sb); | 999 | reiserfs_read_lock_xattrs(dentry->d_sb); |
997 | err = xah->set (dentry->d_inode, name, value, size, flags); | 1000 | err = xah->set(dentry->d_inode, name, value, size, flags); |
998 | if (lock) | 1001 | if (lock) |
999 | reiserfs_write_unlock_xattrs (dentry->d_sb); | 1002 | reiserfs_write_unlock_xattrs(dentry->d_sb); |
1000 | else | 1003 | else |
1001 | reiserfs_read_unlock_xattrs (dentry->d_sb); | 1004 | reiserfs_read_unlock_xattrs(dentry->d_sb); |
1002 | reiserfs_write_unlock_xattr_i (dentry->d_inode); | 1005 | reiserfs_write_unlock_xattr_i(dentry->d_inode); |
1003 | return err; | 1006 | return err; |
1004 | } | 1007 | } |
1005 | 1008 | ||
1006 | /* | 1009 | /* |
@@ -1008,344 +1011,343 @@ reiserfs_setxattr (struct dentry *dentry, const char *name, const void *value, | |||
1008 | * | 1011 | * |
1009 | * dentry->d_inode->i_sem down | 1012 | * dentry->d_inode->i_sem down |
1010 | */ | 1013 | */ |
1011 | int | 1014 | int reiserfs_removexattr(struct dentry *dentry, const char *name) |
1012 | reiserfs_removexattr (struct dentry *dentry, const char *name) | ||
1013 | { | 1015 | { |
1014 | int err; | 1016 | int err; |
1015 | struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix (name); | 1017 | struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix(name); |
1016 | 1018 | ||
1017 | if (!xah || !reiserfs_xattrs(dentry->d_sb) || | 1019 | if (!xah || !reiserfs_xattrs(dentry->d_sb) || |
1018 | get_inode_sd_version (dentry->d_inode) == STAT_DATA_V1) | 1020 | get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1) |
1019 | return -EOPNOTSUPP; | 1021 | return -EOPNOTSUPP; |
1020 | 1022 | ||
1021 | if (IS_RDONLY (dentry->d_inode)) | 1023 | if (IS_RDONLY(dentry->d_inode)) |
1022 | return -EROFS; | 1024 | return -EROFS; |
1023 | 1025 | ||
1024 | if (IS_IMMUTABLE (dentry->d_inode) || IS_APPEND (dentry->d_inode)) | 1026 | if (IS_IMMUTABLE(dentry->d_inode) || IS_APPEND(dentry->d_inode)) |
1025 | return -EPERM; | 1027 | return -EPERM; |
1026 | 1028 | ||
1027 | reiserfs_write_lock_xattr_i (dentry->d_inode); | 1029 | reiserfs_write_lock_xattr_i(dentry->d_inode); |
1028 | reiserfs_read_lock_xattrs (dentry->d_sb); | 1030 | reiserfs_read_lock_xattrs(dentry->d_sb); |
1029 | 1031 | ||
1030 | /* Deletion pre-operation */ | 1032 | /* Deletion pre-operation */ |
1031 | if (xah->del) { | 1033 | if (xah->del) { |
1032 | err = xah->del (dentry->d_inode, name); | 1034 | err = xah->del(dentry->d_inode, name); |
1033 | if (err) | 1035 | if (err) |
1034 | goto out; | 1036 | goto out; |
1035 | } | 1037 | } |
1036 | 1038 | ||
1037 | err = reiserfs_xattr_del (dentry->d_inode, name); | 1039 | err = reiserfs_xattr_del(dentry->d_inode, name); |
1038 | 1040 | ||
1039 | dentry->d_inode->i_ctime = CURRENT_TIME_SEC; | 1041 | dentry->d_inode->i_ctime = CURRENT_TIME_SEC; |
1040 | mark_inode_dirty (dentry->d_inode); | 1042 | mark_inode_dirty(dentry->d_inode); |
1041 | 1043 | ||
1042 | out: | 1044 | out: |
1043 | reiserfs_read_unlock_xattrs (dentry->d_sb); | 1045 | reiserfs_read_unlock_xattrs(dentry->d_sb); |
1044 | reiserfs_write_unlock_xattr_i (dentry->d_inode); | 1046 | reiserfs_write_unlock_xattr_i(dentry->d_inode); |
1045 | return err; | 1047 | return err; |
1046 | } | 1048 | } |
1047 | 1049 | ||
1048 | |||
1049 | /* This is what filldir will use: | 1050 | /* This is what filldir will use: |
1050 | * r_pos will always contain the amount of space required for the entire | 1051 | * r_pos will always contain the amount of space required for the entire |
1051 | * list. If r_pos becomes larger than r_size, we need more space and we | 1052 | * list. If r_pos becomes larger than r_size, we need more space and we |
1052 | * return an error indicating this. If r_pos is less than r_size, then we've | 1053 | * return an error indicating this. If r_pos is less than r_size, then we've |
1053 | * filled the buffer successfully and we return success */ | 1054 | * filled the buffer successfully and we return success */ |
1054 | struct reiserfs_listxattr_buf { | 1055 | struct reiserfs_listxattr_buf { |
1055 | int r_pos; | 1056 | int r_pos; |
1056 | int r_size; | 1057 | int r_size; |
1057 | char *r_buf; | 1058 | char *r_buf; |
1058 | struct inode *r_inode; | 1059 | struct inode *r_inode; |
1059 | }; | 1060 | }; |
1060 | 1061 | ||
1061 | static int | 1062 | static int |
1062 | reiserfs_listxattr_filler (void *buf, const char *name, int namelen, | 1063 | reiserfs_listxattr_filler(void *buf, const char *name, int namelen, |
1063 | loff_t offset, ino_t ino, unsigned int d_type) | 1064 | loff_t offset, ino_t ino, unsigned int d_type) |
1064 | { | 1065 | { |
1065 | struct reiserfs_listxattr_buf *b = (struct reiserfs_listxattr_buf *)buf; | 1066 | struct reiserfs_listxattr_buf *b = (struct reiserfs_listxattr_buf *)buf; |
1066 | int len = 0; | 1067 | int len = 0; |
1067 | if (name[0] != '.' || (namelen != 1 && (name[1] != '.' || namelen != 2))) { | 1068 | if (name[0] != '.' |
1068 | struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix (name); | 1069 | || (namelen != 1 && (name[1] != '.' || namelen != 2))) { |
1069 | if (!xah) return 0; /* Unsupported xattr name, skip it */ | 1070 | struct reiserfs_xattr_handler *xah = |
1070 | 1071 | find_xattr_handler_prefix(name); | |
1071 | /* We call ->list() twice because the operation isn't required to just | 1072 | if (!xah) |
1072 | * return the name back - we want to make sure we have enough space */ | 1073 | return 0; /* Unsupported xattr name, skip it */ |
1073 | len += xah->list (b->r_inode, name, namelen, NULL); | 1074 | |
1074 | 1075 | /* We call ->list() twice because the operation isn't required to just | |
1075 | if (len) { | 1076 | * return the name back - we want to make sure we have enough space */ |
1076 | if (b->r_pos + len + 1 <= b->r_size) { | 1077 | len += xah->list(b->r_inode, name, namelen, NULL); |
1077 | char *p = b->r_buf + b->r_pos; | 1078 | |
1078 | p += xah->list (b->r_inode, name, namelen, p); | 1079 | if (len) { |
1079 | *p++ = '\0'; | 1080 | if (b->r_pos + len + 1 <= b->r_size) { |
1080 | } | 1081 | char *p = b->r_buf + b->r_pos; |
1081 | b->r_pos += len + 1; | 1082 | p += xah->list(b->r_inode, name, namelen, p); |
1082 | } | 1083 | *p++ = '\0'; |
1083 | } | 1084 | } |
1084 | 1085 | b->r_pos += len + 1; | |
1085 | return 0; | 1086 | } |
1087 | } | ||
1088 | |||
1089 | return 0; | ||
1086 | } | 1090 | } |
1091 | |||
1087 | /* | 1092 | /* |
1088 | * Inode operation listxattr() | 1093 | * Inode operation listxattr() |
1089 | * | 1094 | * |
1090 | * Preliminary locking: we down dentry->d_inode->i_sem | 1095 | * Preliminary locking: we down dentry->d_inode->i_sem |
1091 | */ | 1096 | */ |
1092 | ssize_t | 1097 | ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size) |
1093 | reiserfs_listxattr (struct dentry *dentry, char *buffer, size_t size) | ||
1094 | { | 1098 | { |
1095 | struct file *fp; | 1099 | struct file *fp; |
1096 | struct dentry *dir; | 1100 | struct dentry *dir; |
1097 | int err = 0; | 1101 | int err = 0; |
1098 | struct reiserfs_listxattr_buf buf; | 1102 | struct reiserfs_listxattr_buf buf; |
1099 | 1103 | ||
1100 | if (!dentry->d_inode) | 1104 | if (!dentry->d_inode) |
1101 | return -EINVAL; | 1105 | return -EINVAL; |
1102 | 1106 | ||
1103 | if (!reiserfs_xattrs(dentry->d_sb) || | 1107 | if (!reiserfs_xattrs(dentry->d_sb) || |
1104 | get_inode_sd_version (dentry->d_inode) == STAT_DATA_V1) | 1108 | get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1) |
1105 | return -EOPNOTSUPP; | 1109 | return -EOPNOTSUPP; |
1106 | 1110 | ||
1107 | reiserfs_read_lock_xattr_i (dentry->d_inode); | 1111 | reiserfs_read_lock_xattr_i(dentry->d_inode); |
1108 | reiserfs_read_lock_xattrs (dentry->d_sb); | 1112 | reiserfs_read_lock_xattrs(dentry->d_sb); |
1109 | dir = open_xa_dir (dentry->d_inode, FL_READONLY); | 1113 | dir = open_xa_dir(dentry->d_inode, FL_READONLY); |
1110 | reiserfs_read_unlock_xattrs (dentry->d_sb); | 1114 | reiserfs_read_unlock_xattrs(dentry->d_sb); |
1111 | if (IS_ERR (dir)) { | 1115 | if (IS_ERR(dir)) { |
1112 | err = PTR_ERR (dir); | 1116 | err = PTR_ERR(dir); |
1113 | if (err == -ENODATA) | 1117 | if (err == -ENODATA) |
1114 | err = 0; /* Not an error if there aren't any xattrs */ | 1118 | err = 0; /* Not an error if there aren't any xattrs */ |
1115 | goto out; | 1119 | goto out; |
1116 | } | 1120 | } |
1117 | 1121 | ||
1118 | fp = dentry_open (dir, NULL, O_RDWR); | 1122 | fp = dentry_open(dir, NULL, O_RDWR); |
1119 | if (IS_ERR (fp)) { | 1123 | if (IS_ERR(fp)) { |
1120 | err = PTR_ERR (fp); | 1124 | err = PTR_ERR(fp); |
1121 | /* dentry_open dputs the dentry if it fails */ | 1125 | /* dentry_open dputs the dentry if it fails */ |
1122 | goto out; | 1126 | goto out; |
1123 | } | 1127 | } |
1124 | 1128 | ||
1125 | buf.r_buf = buffer; | 1129 | buf.r_buf = buffer; |
1126 | buf.r_size = buffer ? size : 0; | 1130 | buf.r_size = buffer ? size : 0; |
1127 | buf.r_pos = 0; | 1131 | buf.r_pos = 0; |
1128 | buf.r_inode = dentry->d_inode; | 1132 | buf.r_inode = dentry->d_inode; |
1129 | 1133 | ||
1130 | REISERFS_I(dentry->d_inode)->i_flags |= i_has_xattr_dir; | 1134 | REISERFS_I(dentry->d_inode)->i_flags |= i_has_xattr_dir; |
1131 | 1135 | ||
1132 | err = xattr_readdir (fp, reiserfs_listxattr_filler, &buf); | 1136 | err = xattr_readdir(fp, reiserfs_listxattr_filler, &buf); |
1133 | if (err) | 1137 | if (err) |
1134 | goto out_dir; | 1138 | goto out_dir; |
1135 | 1139 | ||
1136 | if (buf.r_pos > buf.r_size && buffer != NULL) | 1140 | if (buf.r_pos > buf.r_size && buffer != NULL) |
1137 | err = -ERANGE; | 1141 | err = -ERANGE; |
1138 | else | 1142 | else |
1139 | err = buf.r_pos; | 1143 | err = buf.r_pos; |
1140 | 1144 | ||
1141 | out_dir: | 1145 | out_dir: |
1142 | fput(fp); | 1146 | fput(fp); |
1143 | 1147 | ||
1144 | out: | 1148 | out: |
1145 | reiserfs_read_unlock_xattr_i (dentry->d_inode); | 1149 | reiserfs_read_unlock_xattr_i(dentry->d_inode); |
1146 | return err; | 1150 | return err; |
1147 | } | 1151 | } |
1148 | 1152 | ||
1149 | /* This is the implementation for the xattr plugin infrastructure */ | 1153 | /* This is the implementation for the xattr plugin infrastructure */ |
1150 | static struct list_head xattr_handlers = LIST_HEAD_INIT (xattr_handlers); | 1154 | static struct list_head xattr_handlers = LIST_HEAD_INIT(xattr_handlers); |
1151 | static DEFINE_RWLOCK(handler_lock); | 1155 | static DEFINE_RWLOCK(handler_lock); |
1152 | 1156 | ||
1153 | static struct reiserfs_xattr_handler * | 1157 | static struct reiserfs_xattr_handler *find_xattr_handler_prefix(const char |
1154 | find_xattr_handler_prefix (const char *prefix) | 1158 | *prefix) |
1155 | { | 1159 | { |
1156 | struct reiserfs_xattr_handler *xah = NULL; | 1160 | struct reiserfs_xattr_handler *xah = NULL; |
1157 | struct list_head *p; | 1161 | struct list_head *p; |
1158 | 1162 | ||
1159 | read_lock (&handler_lock); | 1163 | read_lock(&handler_lock); |
1160 | list_for_each (p, &xattr_handlers) { | 1164 | list_for_each(p, &xattr_handlers) { |
1161 | xah = list_entry (p, struct reiserfs_xattr_handler, handlers); | 1165 | xah = list_entry(p, struct reiserfs_xattr_handler, handlers); |
1162 | if (strncmp (xah->prefix, prefix, strlen (xah->prefix)) == 0) | 1166 | if (strncmp(xah->prefix, prefix, strlen(xah->prefix)) == 0) |
1163 | break; | 1167 | break; |
1164 | xah = NULL; | 1168 | xah = NULL; |
1165 | } | 1169 | } |
1166 | 1170 | ||
1167 | read_unlock (&handler_lock); | 1171 | read_unlock(&handler_lock); |
1168 | return xah; | 1172 | return xah; |
1169 | } | 1173 | } |
1170 | 1174 | ||
1171 | static void | 1175 | static void __unregister_handlers(void) |
1172 | __unregister_handlers (void) | ||
1173 | { | 1176 | { |
1174 | struct reiserfs_xattr_handler *xah; | 1177 | struct reiserfs_xattr_handler *xah; |
1175 | struct list_head *p, *tmp; | 1178 | struct list_head *p, *tmp; |
1176 | 1179 | ||
1177 | list_for_each_safe (p, tmp, &xattr_handlers) { | 1180 | list_for_each_safe(p, tmp, &xattr_handlers) { |
1178 | xah = list_entry (p, struct reiserfs_xattr_handler, handlers); | 1181 | xah = list_entry(p, struct reiserfs_xattr_handler, handlers); |
1179 | if (xah->exit) | 1182 | if (xah->exit) |
1180 | xah->exit(); | 1183 | xah->exit(); |
1181 | 1184 | ||
1182 | list_del_init (p); | 1185 | list_del_init(p); |
1183 | } | 1186 | } |
1184 | INIT_LIST_HEAD (&xattr_handlers); | 1187 | INIT_LIST_HEAD(&xattr_handlers); |
1185 | } | 1188 | } |
1186 | 1189 | ||
1187 | int __init | 1190 | int __init reiserfs_xattr_register_handlers(void) |
1188 | reiserfs_xattr_register_handlers (void) | ||
1189 | { | 1191 | { |
1190 | int err = 0; | 1192 | int err = 0; |
1191 | struct reiserfs_xattr_handler *xah; | 1193 | struct reiserfs_xattr_handler *xah; |
1192 | struct list_head *p; | 1194 | struct list_head *p; |
1193 | 1195 | ||
1194 | write_lock (&handler_lock); | 1196 | write_lock(&handler_lock); |
1195 | 1197 | ||
1196 | /* If we're already initialized, nothing to do */ | 1198 | /* If we're already initialized, nothing to do */ |
1197 | if (!list_empty (&xattr_handlers)) { | 1199 | if (!list_empty(&xattr_handlers)) { |
1198 | write_unlock (&handler_lock); | 1200 | write_unlock(&handler_lock); |
1199 | return 0; | 1201 | return 0; |
1200 | } | 1202 | } |
1201 | 1203 | ||
1202 | /* Add the handlers */ | 1204 | /* Add the handlers */ |
1203 | list_add_tail (&user_handler.handlers, &xattr_handlers); | 1205 | list_add_tail(&user_handler.handlers, &xattr_handlers); |
1204 | list_add_tail (&trusted_handler.handlers, &xattr_handlers); | 1206 | list_add_tail(&trusted_handler.handlers, &xattr_handlers); |
1205 | #ifdef CONFIG_REISERFS_FS_SECURITY | 1207 | #ifdef CONFIG_REISERFS_FS_SECURITY |
1206 | list_add_tail (&security_handler.handlers, &xattr_handlers); | 1208 | list_add_tail(&security_handler.handlers, &xattr_handlers); |
1207 | #endif | 1209 | #endif |
1208 | #ifdef CONFIG_REISERFS_FS_POSIX_ACL | 1210 | #ifdef CONFIG_REISERFS_FS_POSIX_ACL |
1209 | list_add_tail (&posix_acl_access_handler.handlers, &xattr_handlers); | 1211 | list_add_tail(&posix_acl_access_handler.handlers, &xattr_handlers); |
1210 | list_add_tail (&posix_acl_default_handler.handlers, &xattr_handlers); | 1212 | list_add_tail(&posix_acl_default_handler.handlers, &xattr_handlers); |
1211 | #endif | 1213 | #endif |
1212 | 1214 | ||
1213 | /* Run initializers, if available */ | 1215 | /* Run initializers, if available */ |
1214 | list_for_each (p, &xattr_handlers) { | 1216 | list_for_each(p, &xattr_handlers) { |
1215 | xah = list_entry (p, struct reiserfs_xattr_handler, handlers); | 1217 | xah = list_entry(p, struct reiserfs_xattr_handler, handlers); |
1216 | if (xah->init) { | 1218 | if (xah->init) { |
1217 | err = xah->init (); | 1219 | err = xah->init(); |
1218 | if (err) { | 1220 | if (err) { |
1219 | list_del_init (p); | 1221 | list_del_init(p); |
1220 | break; | 1222 | break; |
1221 | } | 1223 | } |
1222 | } | 1224 | } |
1223 | } | 1225 | } |
1224 | 1226 | ||
1225 | /* Clean up other handlers, if any failed */ | 1227 | /* Clean up other handlers, if any failed */ |
1226 | if (err) | 1228 | if (err) |
1227 | __unregister_handlers (); | 1229 | __unregister_handlers(); |
1228 | 1230 | ||
1229 | write_unlock (&handler_lock); | 1231 | write_unlock(&handler_lock); |
1230 | return err; | 1232 | return err; |
1231 | } | 1233 | } |
1232 | 1234 | ||
1233 | void | 1235 | void reiserfs_xattr_unregister_handlers(void) |
1234 | reiserfs_xattr_unregister_handlers (void) | ||
1235 | { | 1236 | { |
1236 | write_lock (&handler_lock); | 1237 | write_lock(&handler_lock); |
1237 | __unregister_handlers (); | 1238 | __unregister_handlers(); |
1238 | write_unlock (&handler_lock); | 1239 | write_unlock(&handler_lock); |
1239 | } | 1240 | } |
1240 | 1241 | ||
1241 | /* This will catch lookups from the fs root to .reiserfs_priv */ | 1242 | /* This will catch lookups from the fs root to .reiserfs_priv */ |
1242 | static int | 1243 | static int |
1243 | xattr_lookup_poison (struct dentry *dentry, struct qstr *q1, struct qstr *name) | 1244 | xattr_lookup_poison(struct dentry *dentry, struct qstr *q1, struct qstr *name) |
1244 | { | 1245 | { |
1245 | struct dentry *priv_root = REISERFS_SB(dentry->d_sb)->priv_root; | 1246 | struct dentry *priv_root = REISERFS_SB(dentry->d_sb)->priv_root; |
1246 | if (name->len == priv_root->d_name.len && | 1247 | if (name->len == priv_root->d_name.len && |
1247 | name->hash == priv_root->d_name.hash && | 1248 | name->hash == priv_root->d_name.hash && |
1248 | !memcmp (name->name, priv_root->d_name.name, name->len)) { | 1249 | !memcmp(name->name, priv_root->d_name.name, name->len)) { |
1249 | return -ENOENT; | 1250 | return -ENOENT; |
1250 | } else if (q1->len == name->len && | 1251 | } else if (q1->len == name->len && |
1251 | !memcmp(q1->name, name->name, name->len)) | 1252 | !memcmp(q1->name, name->name, name->len)) |
1252 | return 0; | 1253 | return 0; |
1253 | return 1; | 1254 | return 1; |
1254 | } | 1255 | } |
1255 | 1256 | ||
1256 | static struct dentry_operations xattr_lookup_poison_ops = { | 1257 | static struct dentry_operations xattr_lookup_poison_ops = { |
1257 | .d_compare = xattr_lookup_poison, | 1258 | .d_compare = xattr_lookup_poison, |
1258 | }; | 1259 | }; |
1259 | 1260 | ||
1260 | |||
1261 | /* We need to take a copy of the mount flags since things like | 1261 | /* We need to take a copy of the mount flags since things like |
1262 | * MS_RDONLY don't get set until *after* we're called. | 1262 | * MS_RDONLY don't get set until *after* we're called. |
1263 | * mount_flags != mount_options */ | 1263 | * mount_flags != mount_options */ |
1264 | int | 1264 | int reiserfs_xattr_init(struct super_block *s, int mount_flags) |
1265 | reiserfs_xattr_init (struct super_block *s, int mount_flags) | ||
1266 | { | 1265 | { |
1267 | int err = 0; | 1266 | int err = 0; |
1268 | 1267 | ||
1269 | /* We need generation numbers to ensure that the oid mapping is correct | 1268 | /* We need generation numbers to ensure that the oid mapping is correct |
1270 | * v3.5 filesystems don't have them. */ | 1269 | * v3.5 filesystems don't have them. */ |
1271 | if (!old_format_only (s)) { | 1270 | if (!old_format_only(s)) { |
1272 | set_bit (REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt)); | 1271 | set_bit(REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt)); |
1273 | } else if (reiserfs_xattrs_optional (s)) { | 1272 | } else if (reiserfs_xattrs_optional(s)) { |
1274 | /* Old format filesystem, but optional xattrs have been enabled | 1273 | /* Old format filesystem, but optional xattrs have been enabled |
1275 | * at mount time. Error out. */ | 1274 | * at mount time. Error out. */ |
1276 | reiserfs_warning (s, "xattrs/ACLs not supported on pre v3.6 " | 1275 | reiserfs_warning(s, "xattrs/ACLs not supported on pre v3.6 " |
1277 | "format filesystem. Failing mount."); | 1276 | "format filesystem. Failing mount."); |
1278 | err = -EOPNOTSUPP; | 1277 | err = -EOPNOTSUPP; |
1279 | goto error; | 1278 | goto error; |
1280 | } else { | 1279 | } else { |
1281 | /* Old format filesystem, but no optional xattrs have been enabled. This | 1280 | /* Old format filesystem, but no optional xattrs have been enabled. This |
1282 | * means we silently disable xattrs on the filesystem. */ | 1281 | * means we silently disable xattrs on the filesystem. */ |
1283 | clear_bit (REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt)); | 1282 | clear_bit(REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt)); |
1284 | } | 1283 | } |
1285 | 1284 | ||
1286 | /* If we don't have the privroot located yet - go find it */ | 1285 | /* If we don't have the privroot located yet - go find it */ |
1287 | if (reiserfs_xattrs (s) && !REISERFS_SB(s)->priv_root) { | 1286 | if (reiserfs_xattrs(s) && !REISERFS_SB(s)->priv_root) { |
1288 | struct dentry *dentry; | 1287 | struct dentry *dentry; |
1289 | dentry = lookup_one_len (PRIVROOT_NAME, s->s_root, | 1288 | dentry = lookup_one_len(PRIVROOT_NAME, s->s_root, |
1290 | strlen (PRIVROOT_NAME)); | 1289 | strlen(PRIVROOT_NAME)); |
1291 | if (!IS_ERR (dentry)) { | 1290 | if (!IS_ERR(dentry)) { |
1292 | if (!(mount_flags & MS_RDONLY) && !dentry->d_inode) { | 1291 | if (!(mount_flags & MS_RDONLY) && !dentry->d_inode) { |
1293 | struct inode *inode = dentry->d_parent->d_inode; | 1292 | struct inode *inode = dentry->d_parent->d_inode; |
1294 | down (&inode->i_sem); | 1293 | down(&inode->i_sem); |
1295 | err = inode->i_op->mkdir (inode, dentry, 0700); | 1294 | err = inode->i_op->mkdir(inode, dentry, 0700); |
1296 | up (&inode->i_sem); | 1295 | up(&inode->i_sem); |
1297 | if (err) { | 1296 | if (err) { |
1298 | dput (dentry); | 1297 | dput(dentry); |
1299 | dentry = NULL; | 1298 | dentry = NULL; |
1300 | } | 1299 | } |
1301 | 1300 | ||
1302 | if (dentry && dentry->d_inode) | 1301 | if (dentry && dentry->d_inode) |
1303 | reiserfs_warning (s, "Created %s on %s - reserved for " | 1302 | reiserfs_warning(s, |
1304 | "xattr storage.", PRIVROOT_NAME, | 1303 | "Created %s on %s - reserved for " |
1305 | reiserfs_bdevname (inode->i_sb)); | 1304 | "xattr storage.", |
1306 | } else if (!dentry->d_inode) { | 1305 | PRIVROOT_NAME, |
1307 | dput (dentry); | 1306 | reiserfs_bdevname |
1308 | dentry = NULL; | 1307 | (inode->i_sb)); |
1309 | } | 1308 | } else if (!dentry->d_inode) { |
1310 | } else | 1309 | dput(dentry); |
1311 | err = PTR_ERR (dentry); | 1310 | dentry = NULL; |
1312 | 1311 | } | |
1313 | if (!err && dentry) { | 1312 | } else |
1314 | s->s_root->d_op = &xattr_lookup_poison_ops; | 1313 | err = PTR_ERR(dentry); |
1315 | reiserfs_mark_inode_private (dentry->d_inode); | 1314 | |
1316 | REISERFS_SB(s)->priv_root = dentry; | 1315 | if (!err && dentry) { |
1317 | } else if (!(mount_flags & MS_RDONLY)) { /* xattrs are unavailable */ | 1316 | s->s_root->d_op = &xattr_lookup_poison_ops; |
1318 | /* If we're read-only it just means that the dir hasn't been | 1317 | reiserfs_mark_inode_private(dentry->d_inode); |
1319 | * created. Not an error -- just no xattrs on the fs. We'll | 1318 | REISERFS_SB(s)->priv_root = dentry; |
1320 | * check again if we go read-write */ | 1319 | } else if (!(mount_flags & MS_RDONLY)) { /* xattrs are unavailable */ |
1321 | reiserfs_warning (s, "xattrs/ACLs enabled and couldn't " | 1320 | /* If we're read-only it just means that the dir hasn't been |
1322 | "find/create .reiserfs_priv. Failing mount."); | 1321 | * created. Not an error -- just no xattrs on the fs. We'll |
1323 | err = -EOPNOTSUPP; | 1322 | * check again if we go read-write */ |
1324 | } | 1323 | reiserfs_warning(s, "xattrs/ACLs enabled and couldn't " |
1325 | } | 1324 | "find/create .reiserfs_priv. Failing mount."); |
1326 | 1325 | err = -EOPNOTSUPP; | |
1327 | error: | 1326 | } |
1328 | /* This is only nonzero if there was an error initializing the xattr | 1327 | } |
1329 | * directory or if there is a condition where we don't support them. */ | 1328 | |
1330 | if (err) { | 1329 | error: |
1331 | clear_bit (REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt)); | 1330 | /* This is only nonzero if there was an error initializing the xattr |
1332 | clear_bit (REISERFS_XATTRS_USER, &(REISERFS_SB(s)->s_mount_opt)); | 1331 | * directory or if there is a condition where we don't support them. */ |
1333 | clear_bit (REISERFS_POSIXACL, &(REISERFS_SB(s)->s_mount_opt)); | 1332 | if (err) { |
1334 | } | 1333 | clear_bit(REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt)); |
1335 | 1334 | clear_bit(REISERFS_XATTRS_USER, &(REISERFS_SB(s)->s_mount_opt)); | |
1336 | /* The super_block MS_POSIXACL must mirror the (no)acl mount option. */ | 1335 | clear_bit(REISERFS_POSIXACL, &(REISERFS_SB(s)->s_mount_opt)); |
1337 | s->s_flags = s->s_flags & ~MS_POSIXACL; | 1336 | } |
1338 | if (reiserfs_posixacl (s)) | 1337 | |
1339 | s->s_flags |= MS_POSIXACL; | 1338 | /* The super_block MS_POSIXACL must mirror the (no)acl mount option. */ |
1340 | 1339 | s->s_flags = s->s_flags & ~MS_POSIXACL; | |
1341 | return err; | 1340 | if (reiserfs_posixacl(s)) |
1341 | s->s_flags |= MS_POSIXACL; | ||
1342 | |||
1343 | return err; | ||
1342 | } | 1344 | } |
1343 | 1345 | ||
1344 | static int | 1346 | static int |
1345 | __reiserfs_permission (struct inode *inode, int mask, struct nameidata *nd, | 1347 | __reiserfs_permission(struct inode *inode, int mask, struct nameidata *nd, |
1346 | int need_lock) | 1348 | int need_lock) |
1347 | { | 1349 | { |
1348 | umode_t mode = inode->i_mode; | 1350 | umode_t mode = inode->i_mode; |
1349 | 1351 | ||
1350 | if (mask & MAY_WRITE) { | 1352 | if (mask & MAY_WRITE) { |
1351 | /* | 1353 | /* |
@@ -1363,50 +1365,50 @@ __reiserfs_permission (struct inode *inode, int mask, struct nameidata *nd, | |||
1363 | } | 1365 | } |
1364 | 1366 | ||
1365 | /* We don't do permission checks on the internal objects. | 1367 | /* We don't do permission checks on the internal objects. |
1366 | * Permissions are determined by the "owning" object. */ | 1368 | * Permissions are determined by the "owning" object. */ |
1367 | if (is_reiserfs_priv_object (inode)) | 1369 | if (is_reiserfs_priv_object(inode)) |
1368 | return 0; | 1370 | return 0; |
1369 | 1371 | ||
1370 | if (current->fsuid == inode->i_uid) { | 1372 | if (current->fsuid == inode->i_uid) { |
1371 | mode >>= 6; | 1373 | mode >>= 6; |
1372 | #ifdef CONFIG_REISERFS_FS_POSIX_ACL | 1374 | #ifdef CONFIG_REISERFS_FS_POSIX_ACL |
1373 | } else if (reiserfs_posixacl(inode->i_sb) && | 1375 | } else if (reiserfs_posixacl(inode->i_sb) && |
1374 | get_inode_sd_version (inode) != STAT_DATA_V1) { | 1376 | get_inode_sd_version(inode) != STAT_DATA_V1) { |
1375 | struct posix_acl *acl; | 1377 | struct posix_acl *acl; |
1376 | 1378 | ||
1377 | /* ACL can't contain additional permissions if | 1379 | /* ACL can't contain additional permissions if |
1378 | the ACL_MASK entry is 0 */ | 1380 | the ACL_MASK entry is 0 */ |
1379 | if (!(mode & S_IRWXG)) | 1381 | if (!(mode & S_IRWXG)) |
1380 | goto check_groups; | 1382 | goto check_groups; |
1381 | 1383 | ||
1382 | if (need_lock) { | 1384 | if (need_lock) { |
1383 | reiserfs_read_lock_xattr_i (inode); | 1385 | reiserfs_read_lock_xattr_i(inode); |
1384 | reiserfs_read_lock_xattrs (inode->i_sb); | 1386 | reiserfs_read_lock_xattrs(inode->i_sb); |
1387 | } | ||
1388 | acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS); | ||
1389 | if (need_lock) { | ||
1390 | reiserfs_read_unlock_xattrs(inode->i_sb); | ||
1391 | reiserfs_read_unlock_xattr_i(inode); | ||
1385 | } | 1392 | } |
1386 | acl = reiserfs_get_acl (inode, ACL_TYPE_ACCESS); | 1393 | if (IS_ERR(acl)) { |
1387 | if (need_lock) { | 1394 | if (PTR_ERR(acl) == -ENODATA) |
1388 | reiserfs_read_unlock_xattrs (inode->i_sb); | 1395 | goto check_groups; |
1389 | reiserfs_read_unlock_xattr_i (inode); | 1396 | return PTR_ERR(acl); |
1390 | } | 1397 | } |
1391 | if (IS_ERR (acl)) { | 1398 | |
1392 | if (PTR_ERR (acl) == -ENODATA) | 1399 | if (acl) { |
1393 | goto check_groups; | 1400 | int err = posix_acl_permission(inode, acl, mask); |
1394 | return PTR_ERR (acl); | 1401 | posix_acl_release(acl); |
1395 | } | 1402 | if (err == -EACCES) { |
1396 | 1403 | goto check_capabilities; | |
1397 | if (acl) { | 1404 | } |
1398 | int err = posix_acl_permission (inode, acl, mask); | 1405 | return err; |
1399 | posix_acl_release (acl); | ||
1400 | if (err == -EACCES) { | ||
1401 | goto check_capabilities; | ||
1402 | } | ||
1403 | return err; | ||
1404 | } else { | 1406 | } else { |
1405 | goto check_groups; | 1407 | goto check_groups; |
1406 | } | 1408 | } |
1407 | #endif | 1409 | #endif |
1408 | } else { | 1410 | } else { |
1409 | check_groups: | 1411 | check_groups: |
1410 | if (in_group_p(inode->i_gid)) | 1412 | if (in_group_p(inode->i_gid)) |
1411 | mode >>= 3; | 1413 | mode >>= 3; |
1412 | } | 1414 | } |
@@ -1414,10 +1416,10 @@ check_groups: | |||
1414 | /* | 1416 | /* |
1415 | * If the DACs are ok we don't need any capability check. | 1417 | * If the DACs are ok we don't need any capability check. |
1416 | */ | 1418 | */ |
1417 | if (((mode & mask & (MAY_READ|MAY_WRITE|MAY_EXEC)) == mask)) | 1419 | if (((mode & mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == mask)) |
1418 | return 0; | 1420 | return 0; |
1419 | 1421 | ||
1420 | check_capabilities: | 1422 | check_capabilities: |
1421 | /* | 1423 | /* |
1422 | * Read/write DACs are always overridable. | 1424 | * Read/write DACs are always overridable. |
1423 | * Executable DACs are overridable if at least one exec bit is set. | 1425 | * Executable DACs are overridable if at least one exec bit is set. |
@@ -1437,14 +1439,13 @@ check_capabilities: | |||
1437 | return -EACCES; | 1439 | return -EACCES; |
1438 | } | 1440 | } |
1439 | 1441 | ||
1440 | int | 1442 | int reiserfs_permission(struct inode *inode, int mask, struct nameidata *nd) |
1441 | reiserfs_permission (struct inode *inode, int mask, struct nameidata *nd) | ||
1442 | { | 1443 | { |
1443 | return __reiserfs_permission (inode, mask, nd, 1); | 1444 | return __reiserfs_permission(inode, mask, nd, 1); |
1444 | } | 1445 | } |
1445 | 1446 | ||
1446 | int | 1447 | int |
1447 | reiserfs_permission_locked (struct inode *inode, int mask, struct nameidata *nd) | 1448 | reiserfs_permission_locked(struct inode *inode, int mask, struct nameidata *nd) |
1448 | { | 1449 | { |
1449 | return __reiserfs_permission (inode, mask, nd, 0); | 1450 | return __reiserfs_permission(inode, mask, nd, 0); |
1450 | } | 1451 | } |