diff options
author | James Morris <jmorris@namei.org> | 2009-02-05 19:01:45 -0500 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2009-02-05 19:01:45 -0500 |
commit | cb5629b10d64a8006622ce3a52bc887d91057d69 (patch) | |
tree | 7c06d8f30783115e3384721046258ce615b129c5 /fs/ocfs2/namei.c | |
parent | 8920d5ad6ba74ae8ab020e90cc4d976980e68701 (diff) | |
parent | f01d1d546abb2f4028b5299092f529eefb01253a (diff) |
Merge branch 'master' into next
Conflicts:
fs/namei.c
Manually merged per:
diff --cc fs/namei.c
index 734f2b5,bbc15c2..0000000
--- a/fs/namei.c
+++ b/fs/namei.c
@@@ -860,9 -848,8 +849,10 @@@ static int __link_path_walk(const char
nd->flags |= LOOKUP_CONTINUE;
err = exec_permission_lite(inode);
if (err == -EAGAIN)
- err = vfs_permission(nd, MAY_EXEC);
+ err = inode_permission(nd->path.dentry->d_inode,
+ MAY_EXEC);
+ if (!err)
+ err = ima_path_check(&nd->path, MAY_EXEC);
if (err)
break;
@@@ -1525,14 -1506,9 +1509,14 @@@ int may_open(struct path *path, int acc
flag &= ~O_TRUNC;
}
- error = vfs_permission(nd, acc_mode);
+ error = inode_permission(inode, acc_mode);
if (error)
return error;
+
- error = ima_path_check(&nd->path,
++ error = ima_path_check(path,
+ acc_mode & (MAY_READ | MAY_WRITE | MAY_EXEC));
+ if (error)
+ return error;
/*
* An append-only file must be opened in append mode for writing.
*/
Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'fs/ocfs2/namei.c')
-rw-r--r-- | fs/ocfs2/namei.c | 318 |
1 files changed, 227 insertions, 91 deletions
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 2545e7402efe..084aba86c3b2 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/types.h> | 40 | #include <linux/types.h> |
41 | #include <linux/slab.h> | 41 | #include <linux/slab.h> |
42 | #include <linux/highmem.h> | 42 | #include <linux/highmem.h> |
43 | #include <linux/quotaops.h> | ||
43 | 44 | ||
44 | #define MLOG_MASK_PREFIX ML_NAMEI | 45 | #define MLOG_MASK_PREFIX ML_NAMEI |
45 | #include <cluster/masklog.h> | 46 | #include <cluster/masklog.h> |
@@ -61,17 +62,18 @@ | |||
61 | #include "sysfile.h" | 62 | #include "sysfile.h" |
62 | #include "uptodate.h" | 63 | #include "uptodate.h" |
63 | #include "xattr.h" | 64 | #include "xattr.h" |
65 | #include "acl.h" | ||
64 | 66 | ||
65 | #include "buffer_head_io.h" | 67 | #include "buffer_head_io.h" |
66 | 68 | ||
67 | static int ocfs2_mknod_locked(struct ocfs2_super *osb, | 69 | static int ocfs2_mknod_locked(struct ocfs2_super *osb, |
68 | struct inode *dir, | 70 | struct inode *dir, |
69 | struct dentry *dentry, int mode, | 71 | struct inode *inode, |
72 | struct dentry *dentry, | ||
70 | dev_t dev, | 73 | dev_t dev, |
71 | struct buffer_head **new_fe_bh, | 74 | struct buffer_head **new_fe_bh, |
72 | struct buffer_head *parent_fe_bh, | 75 | struct buffer_head *parent_fe_bh, |
73 | handle_t *handle, | 76 | handle_t *handle, |
74 | struct inode **ret_inode, | ||
75 | struct ocfs2_alloc_context *inode_ac); | 77 | struct ocfs2_alloc_context *inode_ac); |
76 | 78 | ||
77 | static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb, | 79 | static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb, |
@@ -186,6 +188,35 @@ bail: | |||
186 | return ret; | 188 | return ret; |
187 | } | 189 | } |
188 | 190 | ||
191 | static struct inode *ocfs2_get_init_inode(struct inode *dir, int mode) | ||
192 | { | ||
193 | struct inode *inode; | ||
194 | |||
195 | inode = new_inode(dir->i_sb); | ||
196 | if (!inode) { | ||
197 | mlog(ML_ERROR, "new_inode failed!\n"); | ||
198 | return NULL; | ||
199 | } | ||
200 | |||
201 | /* populate as many fields early on as possible - many of | ||
202 | * these are used by the support functions here and in | ||
203 | * callers. */ | ||
204 | if (S_ISDIR(mode)) | ||
205 | inode->i_nlink = 2; | ||
206 | else | ||
207 | inode->i_nlink = 1; | ||
208 | inode->i_uid = current_fsuid(); | ||
209 | if (dir->i_mode & S_ISGID) { | ||
210 | inode->i_gid = dir->i_gid; | ||
211 | if (S_ISDIR(mode)) | ||
212 | mode |= S_ISGID; | ||
213 | } else | ||
214 | inode->i_gid = current_fsgid(); | ||
215 | inode->i_mode = mode; | ||
216 | vfs_dq_init(inode); | ||
217 | return inode; | ||
218 | } | ||
219 | |||
189 | static int ocfs2_mknod(struct inode *dir, | 220 | static int ocfs2_mknod(struct inode *dir, |
190 | struct dentry *dentry, | 221 | struct dentry *dentry, |
191 | int mode, | 222 | int mode, |
@@ -201,6 +232,13 @@ static int ocfs2_mknod(struct inode *dir, | |||
201 | struct inode *inode = NULL; | 232 | struct inode *inode = NULL; |
202 | struct ocfs2_alloc_context *inode_ac = NULL; | 233 | struct ocfs2_alloc_context *inode_ac = NULL; |
203 | struct ocfs2_alloc_context *data_ac = NULL; | 234 | struct ocfs2_alloc_context *data_ac = NULL; |
235 | struct ocfs2_alloc_context *xattr_ac = NULL; | ||
236 | int want_clusters = 0; | ||
237 | int xattr_credits = 0; | ||
238 | struct ocfs2_security_xattr_info si = { | ||
239 | .enable = 1, | ||
240 | }; | ||
241 | int did_quota_inode = 0; | ||
204 | 242 | ||
205 | mlog_entry("(0x%p, 0x%p, %d, %lu, '%.*s')\n", dir, dentry, mode, | 243 | mlog_entry("(0x%p, 0x%p, %d, %lu, '%.*s')\n", dir, dentry, mode, |
206 | (unsigned long)dev, dentry->d_name.len, | 244 | (unsigned long)dev, dentry->d_name.len, |
@@ -250,17 +288,46 @@ static int ocfs2_mknod(struct inode *dir, | |||
250 | goto leave; | 288 | goto leave; |
251 | } | 289 | } |
252 | 290 | ||
253 | /* Reserve a cluster if creating an extent based directory. */ | 291 | inode = ocfs2_get_init_inode(dir, mode); |
254 | if (S_ISDIR(mode) && !ocfs2_supports_inline_data(osb)) { | 292 | if (!inode) { |
255 | status = ocfs2_reserve_clusters(osb, 1, &data_ac); | 293 | status = -ENOMEM; |
256 | if (status < 0) { | 294 | mlog_errno(status); |
257 | if (status != -ENOSPC) | 295 | goto leave; |
258 | mlog_errno(status); | 296 | } |
297 | |||
298 | /* get security xattr */ | ||
299 | status = ocfs2_init_security_get(inode, dir, &si); | ||
300 | if (status) { | ||
301 | if (status == -EOPNOTSUPP) | ||
302 | si.enable = 0; | ||
303 | else { | ||
304 | mlog_errno(status); | ||
259 | goto leave; | 305 | goto leave; |
260 | } | 306 | } |
261 | } | 307 | } |
262 | 308 | ||
263 | handle = ocfs2_start_trans(osb, OCFS2_MKNOD_CREDITS); | 309 | /* calculate meta data/clusters for setting security and acl xattr */ |
310 | status = ocfs2_calc_xattr_init(dir, parent_fe_bh, mode, | ||
311 | &si, &want_clusters, | ||
312 | &xattr_credits, &xattr_ac); | ||
313 | if (status < 0) { | ||
314 | mlog_errno(status); | ||
315 | goto leave; | ||
316 | } | ||
317 | |||
318 | /* Reserve a cluster if creating an extent based directory. */ | ||
319 | if (S_ISDIR(mode) && !ocfs2_supports_inline_data(osb)) | ||
320 | want_clusters += 1; | ||
321 | |||
322 | status = ocfs2_reserve_clusters(osb, want_clusters, &data_ac); | ||
323 | if (status < 0) { | ||
324 | if (status != -ENOSPC) | ||
325 | mlog_errno(status); | ||
326 | goto leave; | ||
327 | } | ||
328 | |||
329 | handle = ocfs2_start_trans(osb, ocfs2_mknod_credits(osb->sb) + | ||
330 | xattr_credits); | ||
264 | if (IS_ERR(handle)) { | 331 | if (IS_ERR(handle)) { |
265 | status = PTR_ERR(handle); | 332 | status = PTR_ERR(handle); |
266 | handle = NULL; | 333 | handle = NULL; |
@@ -268,10 +335,19 @@ static int ocfs2_mknod(struct inode *dir, | |||
268 | goto leave; | 335 | goto leave; |
269 | } | 336 | } |
270 | 337 | ||
338 | /* We don't use standard VFS wrapper because we don't want vfs_dq_init | ||
339 | * to be called. */ | ||
340 | if (sb_any_quota_active(osb->sb) && | ||
341 | osb->sb->dq_op->alloc_inode(inode, 1) == NO_QUOTA) { | ||
342 | status = -EDQUOT; | ||
343 | goto leave; | ||
344 | } | ||
345 | did_quota_inode = 1; | ||
346 | |||
271 | /* do the real work now. */ | 347 | /* do the real work now. */ |
272 | status = ocfs2_mknod_locked(osb, dir, dentry, mode, dev, | 348 | status = ocfs2_mknod_locked(osb, dir, inode, dentry, dev, |
273 | &new_fe_bh, parent_fe_bh, handle, | 349 | &new_fe_bh, parent_fe_bh, handle, |
274 | &inode, inode_ac); | 350 | inode_ac); |
275 | if (status < 0) { | 351 | if (status < 0) { |
276 | mlog_errno(status); | 352 | mlog_errno(status); |
277 | goto leave; | 353 | goto leave; |
@@ -285,8 +361,8 @@ static int ocfs2_mknod(struct inode *dir, | |||
285 | goto leave; | 361 | goto leave; |
286 | } | 362 | } |
287 | 363 | ||
288 | status = ocfs2_journal_access(handle, dir, parent_fe_bh, | 364 | status = ocfs2_journal_access_di(handle, dir, parent_fe_bh, |
289 | OCFS2_JOURNAL_ACCESS_WRITE); | 365 | OCFS2_JOURNAL_ACCESS_WRITE); |
290 | if (status < 0) { | 366 | if (status < 0) { |
291 | mlog_errno(status); | 367 | mlog_errno(status); |
292 | goto leave; | 368 | goto leave; |
@@ -300,6 +376,22 @@ static int ocfs2_mknod(struct inode *dir, | |||
300 | inc_nlink(dir); | 376 | inc_nlink(dir); |
301 | } | 377 | } |
302 | 378 | ||
379 | status = ocfs2_init_acl(handle, inode, dir, new_fe_bh, parent_fe_bh, | ||
380 | xattr_ac, data_ac); | ||
381 | if (status < 0) { | ||
382 | mlog_errno(status); | ||
383 | goto leave; | ||
384 | } | ||
385 | |||
386 | if (si.enable) { | ||
387 | status = ocfs2_init_security_set(handle, inode, new_fe_bh, &si, | ||
388 | xattr_ac, data_ac); | ||
389 | if (status < 0) { | ||
390 | mlog_errno(status); | ||
391 | goto leave; | ||
392 | } | ||
393 | } | ||
394 | |||
303 | status = ocfs2_add_entry(handle, dentry, inode, | 395 | status = ocfs2_add_entry(handle, dentry, inode, |
304 | OCFS2_I(inode)->ip_blkno, parent_fe_bh, | 396 | OCFS2_I(inode)->ip_blkno, parent_fe_bh, |
305 | de_bh); | 397 | de_bh); |
@@ -320,6 +412,8 @@ static int ocfs2_mknod(struct inode *dir, | |||
320 | d_instantiate(dentry, inode); | 412 | d_instantiate(dentry, inode); |
321 | status = 0; | 413 | status = 0; |
322 | leave: | 414 | leave: |
415 | if (status < 0 && did_quota_inode) | ||
416 | vfs_dq_free_inode(inode); | ||
323 | if (handle) | 417 | if (handle) |
324 | ocfs2_commit_trans(osb, handle); | 418 | ocfs2_commit_trans(osb, handle); |
325 | 419 | ||
@@ -331,9 +425,13 @@ leave: | |||
331 | brelse(new_fe_bh); | 425 | brelse(new_fe_bh); |
332 | brelse(de_bh); | 426 | brelse(de_bh); |
333 | brelse(parent_fe_bh); | 427 | brelse(parent_fe_bh); |
428 | kfree(si.name); | ||
429 | kfree(si.value); | ||
334 | 430 | ||
335 | if ((status < 0) && inode) | 431 | if ((status < 0) && inode) { |
432 | clear_nlink(inode); | ||
336 | iput(inode); | 433 | iput(inode); |
434 | } | ||
337 | 435 | ||
338 | if (inode_ac) | 436 | if (inode_ac) |
339 | ocfs2_free_alloc_context(inode_ac); | 437 | ocfs2_free_alloc_context(inode_ac); |
@@ -341,6 +439,9 @@ leave: | |||
341 | if (data_ac) | 439 | if (data_ac) |
342 | ocfs2_free_alloc_context(data_ac); | 440 | ocfs2_free_alloc_context(data_ac); |
343 | 441 | ||
442 | if (xattr_ac) | ||
443 | ocfs2_free_alloc_context(xattr_ac); | ||
444 | |||
344 | mlog_exit(status); | 445 | mlog_exit(status); |
345 | 446 | ||
346 | return status; | 447 | return status; |
@@ -348,12 +449,12 @@ leave: | |||
348 | 449 | ||
349 | static int ocfs2_mknod_locked(struct ocfs2_super *osb, | 450 | static int ocfs2_mknod_locked(struct ocfs2_super *osb, |
350 | struct inode *dir, | 451 | struct inode *dir, |
351 | struct dentry *dentry, int mode, | 452 | struct inode *inode, |
453 | struct dentry *dentry, | ||
352 | dev_t dev, | 454 | dev_t dev, |
353 | struct buffer_head **new_fe_bh, | 455 | struct buffer_head **new_fe_bh, |
354 | struct buffer_head *parent_fe_bh, | 456 | struct buffer_head *parent_fe_bh, |
355 | handle_t *handle, | 457 | handle_t *handle, |
356 | struct inode **ret_inode, | ||
357 | struct ocfs2_alloc_context *inode_ac) | 458 | struct ocfs2_alloc_context *inode_ac) |
358 | { | 459 | { |
359 | int status = 0; | 460 | int status = 0; |
@@ -361,14 +462,12 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb, | |||
361 | struct ocfs2_extent_list *fel; | 462 | struct ocfs2_extent_list *fel; |
362 | u64 fe_blkno = 0; | 463 | u64 fe_blkno = 0; |
363 | u16 suballoc_bit; | 464 | u16 suballoc_bit; |
364 | struct inode *inode = NULL; | ||
365 | 465 | ||
366 | mlog_entry("(0x%p, 0x%p, %d, %lu, '%.*s')\n", dir, dentry, mode, | 466 | mlog_entry("(0x%p, 0x%p, %d, %lu, '%.*s')\n", dir, dentry, |
367 | (unsigned long)dev, dentry->d_name.len, | 467 | inode->i_mode, (unsigned long)dev, dentry->d_name.len, |
368 | dentry->d_name.name); | 468 | dentry->d_name.name); |
369 | 469 | ||
370 | *new_fe_bh = NULL; | 470 | *new_fe_bh = NULL; |
371 | *ret_inode = NULL; | ||
372 | 471 | ||
373 | status = ocfs2_claim_new_inode(osb, handle, inode_ac, &suballoc_bit, | 472 | status = ocfs2_claim_new_inode(osb, handle, inode_ac, &suballoc_bit, |
374 | &fe_blkno); | 473 | &fe_blkno); |
@@ -377,23 +476,11 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb, | |||
377 | goto leave; | 476 | goto leave; |
378 | } | 477 | } |
379 | 478 | ||
380 | inode = new_inode(dir->i_sb); | ||
381 | if (!inode) { | ||
382 | status = -ENOMEM; | ||
383 | mlog(ML_ERROR, "new_inode failed!\n"); | ||
384 | goto leave; | ||
385 | } | ||
386 | |||
387 | /* populate as many fields early on as possible - many of | 479 | /* populate as many fields early on as possible - many of |
388 | * these are used by the support functions here and in | 480 | * these are used by the support functions here and in |
389 | * callers. */ | 481 | * callers. */ |
390 | inode->i_ino = ino_from_blkno(osb->sb, fe_blkno); | 482 | inode->i_ino = ino_from_blkno(osb->sb, fe_blkno); |
391 | OCFS2_I(inode)->ip_blkno = fe_blkno; | 483 | OCFS2_I(inode)->ip_blkno = fe_blkno; |
392 | if (S_ISDIR(mode)) | ||
393 | inode->i_nlink = 2; | ||
394 | else | ||
395 | inode->i_nlink = 1; | ||
396 | inode->i_mode = mode; | ||
397 | spin_lock(&osb->osb_lock); | 484 | spin_lock(&osb->osb_lock); |
398 | inode->i_generation = osb->s_next_generation++; | 485 | inode->i_generation = osb->s_next_generation++; |
399 | spin_unlock(&osb->osb_lock); | 486 | spin_unlock(&osb->osb_lock); |
@@ -406,8 +493,8 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb, | |||
406 | } | 493 | } |
407 | ocfs2_set_new_buffer_uptodate(inode, *new_fe_bh); | 494 | ocfs2_set_new_buffer_uptodate(inode, *new_fe_bh); |
408 | 495 | ||
409 | status = ocfs2_journal_access(handle, inode, *new_fe_bh, | 496 | status = ocfs2_journal_access_di(handle, inode, *new_fe_bh, |
410 | OCFS2_JOURNAL_ACCESS_CREATE); | 497 | OCFS2_JOURNAL_ACCESS_CREATE); |
411 | if (status < 0) { | 498 | if (status < 0) { |
412 | mlog_errno(status); | 499 | mlog_errno(status); |
413 | goto leave; | 500 | goto leave; |
@@ -421,17 +508,11 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb, | |||
421 | fe->i_blkno = cpu_to_le64(fe_blkno); | 508 | fe->i_blkno = cpu_to_le64(fe_blkno); |
422 | fe->i_suballoc_bit = cpu_to_le16(suballoc_bit); | 509 | fe->i_suballoc_bit = cpu_to_le16(suballoc_bit); |
423 | fe->i_suballoc_slot = cpu_to_le16(inode_ac->ac_alloc_slot); | 510 | fe->i_suballoc_slot = cpu_to_le16(inode_ac->ac_alloc_slot); |
424 | fe->i_uid = cpu_to_le32(current_fsuid()); | 511 | fe->i_uid = cpu_to_le32(inode->i_uid); |
425 | if (dir->i_mode & S_ISGID) { | 512 | fe->i_gid = cpu_to_le32(inode->i_gid); |
426 | fe->i_gid = cpu_to_le32(dir->i_gid); | 513 | fe->i_mode = cpu_to_le16(inode->i_mode); |
427 | if (S_ISDIR(mode)) | 514 | if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) |
428 | mode |= S_ISGID; | ||
429 | } else | ||
430 | fe->i_gid = cpu_to_le32(current_fsgid()); | ||
431 | fe->i_mode = cpu_to_le16(mode); | ||
432 | if (S_ISCHR(mode) || S_ISBLK(mode)) | ||
433 | fe->id1.dev1.i_rdev = cpu_to_le64(huge_encode_dev(dev)); | 515 | fe->id1.dev1.i_rdev = cpu_to_le64(huge_encode_dev(dev)); |
434 | |||
435 | fe->i_links_count = cpu_to_le16(inode->i_nlink); | 516 | fe->i_links_count = cpu_to_le16(inode->i_nlink); |
436 | 517 | ||
437 | fe->i_last_eb_blk = 0; | 518 | fe->i_last_eb_blk = 0; |
@@ -446,7 +527,7 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb, | |||
446 | /* | 527 | /* |
447 | * If supported, directories start with inline data. | 528 | * If supported, directories start with inline data. |
448 | */ | 529 | */ |
449 | if (S_ISDIR(mode) && ocfs2_supports_inline_data(osb)) { | 530 | if (S_ISDIR(inode->i_mode) && ocfs2_supports_inline_data(osb)) { |
450 | u16 feat = le16_to_cpu(fe->i_dyn_features); | 531 | u16 feat = le16_to_cpu(fe->i_dyn_features); |
451 | 532 | ||
452 | fe->i_dyn_features = cpu_to_le16(feat | OCFS2_INLINE_DATA_FL); | 533 | fe->i_dyn_features = cpu_to_le16(feat | OCFS2_INLINE_DATA_FL); |
@@ -465,15 +546,7 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb, | |||
465 | goto leave; | 546 | goto leave; |
466 | } | 547 | } |
467 | 548 | ||
468 | if (ocfs2_populate_inode(inode, fe, 1) < 0) { | 549 | ocfs2_populate_inode(inode, fe, 1); |
469 | mlog(ML_ERROR, "populate inode failed! bh->b_blocknr=%llu, " | ||
470 | "i_blkno=%llu, i_ino=%lu\n", | ||
471 | (unsigned long long)(*new_fe_bh)->b_blocknr, | ||
472 | (unsigned long long)le64_to_cpu(fe->i_blkno), | ||
473 | inode->i_ino); | ||
474 | BUG(); | ||
475 | } | ||
476 | |||
477 | ocfs2_inode_set_new(osb, inode); | 550 | ocfs2_inode_set_new(osb, inode); |
478 | if (!ocfs2_mount_local(osb)) { | 551 | if (!ocfs2_mount_local(osb)) { |
479 | status = ocfs2_create_new_inode_locks(inode); | 552 | status = ocfs2_create_new_inode_locks(inode); |
@@ -484,17 +557,12 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb, | |||
484 | status = 0; /* error in ocfs2_create_new_inode_locks is not | 557 | status = 0; /* error in ocfs2_create_new_inode_locks is not |
485 | * critical */ | 558 | * critical */ |
486 | 559 | ||
487 | *ret_inode = inode; | ||
488 | leave: | 560 | leave: |
489 | if (status < 0) { | 561 | if (status < 0) { |
490 | if (*new_fe_bh) { | 562 | if (*new_fe_bh) { |
491 | brelse(*new_fe_bh); | 563 | brelse(*new_fe_bh); |
492 | *new_fe_bh = NULL; | 564 | *new_fe_bh = NULL; |
493 | } | 565 | } |
494 | if (inode) { | ||
495 | clear_nlink(inode); | ||
496 | iput(inode); | ||
497 | } | ||
498 | } | 566 | } |
499 | 567 | ||
500 | mlog_exit(status); | 568 | mlog_exit(status); |
@@ -588,7 +656,7 @@ static int ocfs2_link(struct dentry *old_dentry, | |||
588 | goto out_unlock_inode; | 656 | goto out_unlock_inode; |
589 | } | 657 | } |
590 | 658 | ||
591 | handle = ocfs2_start_trans(osb, OCFS2_LINK_CREDITS); | 659 | handle = ocfs2_start_trans(osb, ocfs2_link_credits(osb->sb)); |
592 | if (IS_ERR(handle)) { | 660 | if (IS_ERR(handle)) { |
593 | err = PTR_ERR(handle); | 661 | err = PTR_ERR(handle); |
594 | handle = NULL; | 662 | handle = NULL; |
@@ -596,8 +664,8 @@ static int ocfs2_link(struct dentry *old_dentry, | |||
596 | goto out_unlock_inode; | 664 | goto out_unlock_inode; |
597 | } | 665 | } |
598 | 666 | ||
599 | err = ocfs2_journal_access(handle, inode, fe_bh, | 667 | err = ocfs2_journal_access_di(handle, inode, fe_bh, |
600 | OCFS2_JOURNAL_ACCESS_WRITE); | 668 | OCFS2_JOURNAL_ACCESS_WRITE); |
601 | if (err < 0) { | 669 | if (err < 0) { |
602 | mlog_errno(err); | 670 | mlog_errno(err); |
603 | goto out_commit; | 671 | goto out_commit; |
@@ -775,7 +843,7 @@ static int ocfs2_unlink(struct inode *dir, | |||
775 | } | 843 | } |
776 | } | 844 | } |
777 | 845 | ||
778 | handle = ocfs2_start_trans(osb, OCFS2_UNLINK_CREDITS); | 846 | handle = ocfs2_start_trans(osb, ocfs2_unlink_credits(osb->sb)); |
779 | if (IS_ERR(handle)) { | 847 | if (IS_ERR(handle)) { |
780 | status = PTR_ERR(handle); | 848 | status = PTR_ERR(handle); |
781 | handle = NULL; | 849 | handle = NULL; |
@@ -783,8 +851,8 @@ static int ocfs2_unlink(struct inode *dir, | |||
783 | goto leave; | 851 | goto leave; |
784 | } | 852 | } |
785 | 853 | ||
786 | status = ocfs2_journal_access(handle, inode, fe_bh, | 854 | status = ocfs2_journal_access_di(handle, inode, fe_bh, |
787 | OCFS2_JOURNAL_ACCESS_WRITE); | 855 | OCFS2_JOURNAL_ACCESS_WRITE); |
788 | if (status < 0) { | 856 | if (status < 0) { |
789 | mlog_errno(status); | 857 | mlog_errno(status); |
790 | goto leave; | 858 | goto leave; |
@@ -1181,7 +1249,7 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1181 | } | 1249 | } |
1182 | } | 1250 | } |
1183 | 1251 | ||
1184 | handle = ocfs2_start_trans(osb, OCFS2_RENAME_CREDITS); | 1252 | handle = ocfs2_start_trans(osb, ocfs2_rename_credits(osb->sb)); |
1185 | if (IS_ERR(handle)) { | 1253 | if (IS_ERR(handle)) { |
1186 | status = PTR_ERR(handle); | 1254 | status = PTR_ERR(handle); |
1187 | handle = NULL; | 1255 | handle = NULL; |
@@ -1197,8 +1265,8 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1197 | goto bail; | 1265 | goto bail; |
1198 | } | 1266 | } |
1199 | } | 1267 | } |
1200 | status = ocfs2_journal_access(handle, new_inode, newfe_bh, | 1268 | status = ocfs2_journal_access_di(handle, new_inode, newfe_bh, |
1201 | OCFS2_JOURNAL_ACCESS_WRITE); | 1269 | OCFS2_JOURNAL_ACCESS_WRITE); |
1202 | if (status < 0) { | 1270 | if (status < 0) { |
1203 | mlog_errno(status); | 1271 | mlog_errno(status); |
1204 | goto bail; | 1272 | goto bail; |
@@ -1244,8 +1312,8 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1244 | old_inode->i_ctime = CURRENT_TIME; | 1312 | old_inode->i_ctime = CURRENT_TIME; |
1245 | mark_inode_dirty(old_inode); | 1313 | mark_inode_dirty(old_inode); |
1246 | 1314 | ||
1247 | status = ocfs2_journal_access(handle, old_inode, old_inode_bh, | 1315 | status = ocfs2_journal_access_di(handle, old_inode, old_inode_bh, |
1248 | OCFS2_JOURNAL_ACCESS_WRITE); | 1316 | OCFS2_JOURNAL_ACCESS_WRITE); |
1249 | if (status >= 0) { | 1317 | if (status >= 0) { |
1250 | old_di = (struct ocfs2_dinode *) old_inode_bh->b_data; | 1318 | old_di = (struct ocfs2_dinode *) old_inode_bh->b_data; |
1251 | 1319 | ||
@@ -1321,9 +1389,9 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1321 | (int)old_dir_nlink, old_dir->i_nlink); | 1389 | (int)old_dir_nlink, old_dir->i_nlink); |
1322 | } else { | 1390 | } else { |
1323 | struct ocfs2_dinode *fe; | 1391 | struct ocfs2_dinode *fe; |
1324 | status = ocfs2_journal_access(handle, old_dir, | 1392 | status = ocfs2_journal_access_di(handle, old_dir, |
1325 | old_dir_bh, | 1393 | old_dir_bh, |
1326 | OCFS2_JOURNAL_ACCESS_WRITE); | 1394 | OCFS2_JOURNAL_ACCESS_WRITE); |
1327 | fe = (struct ocfs2_dinode *) old_dir_bh->b_data; | 1395 | fe = (struct ocfs2_dinode *) old_dir_bh->b_data; |
1328 | fe->i_links_count = cpu_to_le16(old_dir->i_nlink); | 1396 | fe->i_links_count = cpu_to_le16(old_dir->i_nlink); |
1329 | status = ocfs2_journal_dirty(handle, old_dir_bh); | 1397 | status = ocfs2_journal_dirty(handle, old_dir_bh); |
@@ -1496,6 +1564,13 @@ static int ocfs2_symlink(struct inode *dir, | |||
1496 | handle_t *handle = NULL; | 1564 | handle_t *handle = NULL; |
1497 | struct ocfs2_alloc_context *inode_ac = NULL; | 1565 | struct ocfs2_alloc_context *inode_ac = NULL; |
1498 | struct ocfs2_alloc_context *data_ac = NULL; | 1566 | struct ocfs2_alloc_context *data_ac = NULL; |
1567 | struct ocfs2_alloc_context *xattr_ac = NULL; | ||
1568 | int want_clusters = 0; | ||
1569 | int xattr_credits = 0; | ||
1570 | struct ocfs2_security_xattr_info si = { | ||
1571 | .enable = 1, | ||
1572 | }; | ||
1573 | int did_quota = 0, did_quota_inode = 0; | ||
1499 | 1574 | ||
1500 | mlog_entry("(0x%p, 0x%p, symname='%s' actual='%.*s')\n", dir, | 1575 | mlog_entry("(0x%p, 0x%p, symname='%s' actual='%.*s')\n", dir, |
1501 | dentry, symname, dentry->d_name.len, dentry->d_name.name); | 1576 | dentry, symname, dentry->d_name.len, dentry->d_name.name); |
@@ -1542,17 +1617,46 @@ static int ocfs2_symlink(struct inode *dir, | |||
1542 | goto bail; | 1617 | goto bail; |
1543 | } | 1618 | } |
1544 | 1619 | ||
1545 | /* don't reserve bitmap space for fast symlinks. */ | 1620 | inode = ocfs2_get_init_inode(dir, S_IFLNK | S_IRWXUGO); |
1546 | if (l > ocfs2_fast_symlink_chars(sb)) { | 1621 | if (!inode) { |
1547 | status = ocfs2_reserve_clusters(osb, 1, &data_ac); | 1622 | status = -ENOMEM; |
1623 | mlog_errno(status); | ||
1624 | goto bail; | ||
1625 | } | ||
1626 | |||
1627 | /* get security xattr */ | ||
1628 | status = ocfs2_init_security_get(inode, dir, &si); | ||
1629 | if (status) { | ||
1630 | if (status == -EOPNOTSUPP) | ||
1631 | si.enable = 0; | ||
1632 | else { | ||
1633 | mlog_errno(status); | ||
1634 | goto bail; | ||
1635 | } | ||
1636 | } | ||
1637 | |||
1638 | /* calculate meta data/clusters for setting security xattr */ | ||
1639 | if (si.enable) { | ||
1640 | status = ocfs2_calc_security_init(dir, &si, &want_clusters, | ||
1641 | &xattr_credits, &xattr_ac); | ||
1548 | if (status < 0) { | 1642 | if (status < 0) { |
1549 | if (status != -ENOSPC) | 1643 | mlog_errno(status); |
1550 | mlog_errno(status); | ||
1551 | goto bail; | 1644 | goto bail; |
1552 | } | 1645 | } |
1553 | } | 1646 | } |
1554 | 1647 | ||
1555 | handle = ocfs2_start_trans(osb, credits); | 1648 | /* don't reserve bitmap space for fast symlinks. */ |
1649 | if (l > ocfs2_fast_symlink_chars(sb)) | ||
1650 | want_clusters += 1; | ||
1651 | |||
1652 | status = ocfs2_reserve_clusters(osb, want_clusters, &data_ac); | ||
1653 | if (status < 0) { | ||
1654 | if (status != -ENOSPC) | ||
1655 | mlog_errno(status); | ||
1656 | goto bail; | ||
1657 | } | ||
1658 | |||
1659 | handle = ocfs2_start_trans(osb, credits + xattr_credits); | ||
1556 | if (IS_ERR(handle)) { | 1660 | if (IS_ERR(handle)) { |
1557 | status = PTR_ERR(handle); | 1661 | status = PTR_ERR(handle); |
1558 | handle = NULL; | 1662 | handle = NULL; |
@@ -1560,10 +1664,18 @@ static int ocfs2_symlink(struct inode *dir, | |||
1560 | goto bail; | 1664 | goto bail; |
1561 | } | 1665 | } |
1562 | 1666 | ||
1563 | status = ocfs2_mknod_locked(osb, dir, dentry, | 1667 | /* We don't use standard VFS wrapper because we don't want vfs_dq_init |
1564 | S_IFLNK | S_IRWXUGO, 0, | 1668 | * to be called. */ |
1565 | &new_fe_bh, parent_fe_bh, handle, | 1669 | if (sb_any_quota_active(osb->sb) && |
1566 | &inode, inode_ac); | 1670 | osb->sb->dq_op->alloc_inode(inode, 1) == NO_QUOTA) { |
1671 | status = -EDQUOT; | ||
1672 | goto bail; | ||
1673 | } | ||
1674 | did_quota_inode = 1; | ||
1675 | |||
1676 | status = ocfs2_mknod_locked(osb, dir, inode, dentry, | ||
1677 | 0, &new_fe_bh, parent_fe_bh, handle, | ||
1678 | inode_ac); | ||
1567 | if (status < 0) { | 1679 | if (status < 0) { |
1568 | mlog_errno(status); | 1680 | mlog_errno(status); |
1569 | goto bail; | 1681 | goto bail; |
@@ -1576,6 +1688,12 @@ static int ocfs2_symlink(struct inode *dir, | |||
1576 | u32 offset = 0; | 1688 | u32 offset = 0; |
1577 | 1689 | ||
1578 | inode->i_op = &ocfs2_symlink_inode_operations; | 1690 | inode->i_op = &ocfs2_symlink_inode_operations; |
1691 | if (vfs_dq_alloc_space_nodirty(inode, | ||
1692 | ocfs2_clusters_to_bytes(osb->sb, 1))) { | ||
1693 | status = -EDQUOT; | ||
1694 | goto bail; | ||
1695 | } | ||
1696 | did_quota = 1; | ||
1579 | status = ocfs2_add_inode_data(osb, inode, &offset, 1, 0, | 1697 | status = ocfs2_add_inode_data(osb, inode, &offset, 1, 0, |
1580 | new_fe_bh, | 1698 | new_fe_bh, |
1581 | handle, data_ac, NULL, | 1699 | handle, data_ac, NULL, |
@@ -1614,6 +1732,15 @@ static int ocfs2_symlink(struct inode *dir, | |||
1614 | } | 1732 | } |
1615 | } | 1733 | } |
1616 | 1734 | ||
1735 | if (si.enable) { | ||
1736 | status = ocfs2_init_security_set(handle, inode, new_fe_bh, &si, | ||
1737 | xattr_ac, data_ac); | ||
1738 | if (status < 0) { | ||
1739 | mlog_errno(status); | ||
1740 | goto bail; | ||
1741 | } | ||
1742 | } | ||
1743 | |||
1617 | status = ocfs2_add_entry(handle, dentry, inode, | 1744 | status = ocfs2_add_entry(handle, dentry, inode, |
1618 | le64_to_cpu(fe->i_blkno), parent_fe_bh, | 1745 | le64_to_cpu(fe->i_blkno), parent_fe_bh, |
1619 | de_bh); | 1746 | de_bh); |
@@ -1632,6 +1759,11 @@ static int ocfs2_symlink(struct inode *dir, | |||
1632 | dentry->d_op = &ocfs2_dentry_ops; | 1759 | dentry->d_op = &ocfs2_dentry_ops; |
1633 | d_instantiate(dentry, inode); | 1760 | d_instantiate(dentry, inode); |
1634 | bail: | 1761 | bail: |
1762 | if (status < 0 && did_quota) | ||
1763 | vfs_dq_free_space_nodirty(inode, | ||
1764 | ocfs2_clusters_to_bytes(osb->sb, 1)); | ||
1765 | if (status < 0 && did_quota_inode) | ||
1766 | vfs_dq_free_inode(inode); | ||
1635 | if (handle) | 1767 | if (handle) |
1636 | ocfs2_commit_trans(osb, handle); | 1768 | ocfs2_commit_trans(osb, handle); |
1637 | 1769 | ||
@@ -1640,12 +1772,18 @@ bail: | |||
1640 | brelse(new_fe_bh); | 1772 | brelse(new_fe_bh); |
1641 | brelse(parent_fe_bh); | 1773 | brelse(parent_fe_bh); |
1642 | brelse(de_bh); | 1774 | brelse(de_bh); |
1775 | kfree(si.name); | ||
1776 | kfree(si.value); | ||
1643 | if (inode_ac) | 1777 | if (inode_ac) |
1644 | ocfs2_free_alloc_context(inode_ac); | 1778 | ocfs2_free_alloc_context(inode_ac); |
1645 | if (data_ac) | 1779 | if (data_ac) |
1646 | ocfs2_free_alloc_context(data_ac); | 1780 | ocfs2_free_alloc_context(data_ac); |
1647 | if ((status < 0) && inode) | 1781 | if (xattr_ac) |
1782 | ocfs2_free_alloc_context(xattr_ac); | ||
1783 | if ((status < 0) && inode) { | ||
1784 | clear_nlink(inode); | ||
1648 | iput(inode); | 1785 | iput(inode); |
1786 | } | ||
1649 | 1787 | ||
1650 | mlog_exit(status); | 1788 | mlog_exit(status); |
1651 | 1789 | ||
@@ -1754,16 +1892,14 @@ static int ocfs2_orphan_add(struct ocfs2_super *osb, | |||
1754 | 1892 | ||
1755 | mlog_entry("(inode->i_ino = %lu)\n", inode->i_ino); | 1893 | mlog_entry("(inode->i_ino = %lu)\n", inode->i_ino); |
1756 | 1894 | ||
1757 | status = ocfs2_read_block(orphan_dir_inode, | 1895 | status = ocfs2_read_inode_block(orphan_dir_inode, &orphan_dir_bh); |
1758 | OCFS2_I(orphan_dir_inode)->ip_blkno, | ||
1759 | &orphan_dir_bh); | ||
1760 | if (status < 0) { | 1896 | if (status < 0) { |
1761 | mlog_errno(status); | 1897 | mlog_errno(status); |
1762 | goto leave; | 1898 | goto leave; |
1763 | } | 1899 | } |
1764 | 1900 | ||
1765 | status = ocfs2_journal_access(handle, orphan_dir_inode, orphan_dir_bh, | 1901 | status = ocfs2_journal_access_di(handle, orphan_dir_inode, orphan_dir_bh, |
1766 | OCFS2_JOURNAL_ACCESS_WRITE); | 1902 | OCFS2_JOURNAL_ACCESS_WRITE); |
1767 | if (status < 0) { | 1903 | if (status < 0) { |
1768 | mlog_errno(status); | 1904 | mlog_errno(status); |
1769 | goto leave; | 1905 | goto leave; |
@@ -1850,8 +1986,8 @@ int ocfs2_orphan_del(struct ocfs2_super *osb, | |||
1850 | goto leave; | 1986 | goto leave; |
1851 | } | 1987 | } |
1852 | 1988 | ||
1853 | status = ocfs2_journal_access(handle,orphan_dir_inode, orphan_dir_bh, | 1989 | status = ocfs2_journal_access_di(handle,orphan_dir_inode, orphan_dir_bh, |
1854 | OCFS2_JOURNAL_ACCESS_WRITE); | 1990 | OCFS2_JOURNAL_ACCESS_WRITE); |
1855 | if (status < 0) { | 1991 | if (status < 0) { |
1856 | mlog_errno(status); | 1992 | mlog_errno(status); |
1857 | goto leave; | 1993 | goto leave; |