aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/linux-2.6/xfs_iops.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_iops.c')
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.c230
1 files changed, 125 insertions, 105 deletions
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index cc4abd3daa49..a1237dad6430 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -62,12 +62,11 @@ void
62xfs_synchronize_atime( 62xfs_synchronize_atime(
63 xfs_inode_t *ip) 63 xfs_inode_t *ip)
64{ 64{
65 bhv_vnode_t *vp; 65 struct inode *inode = ip->i_vnode;
66 66
67 vp = XFS_ITOV_NULL(ip); 67 if (inode) {
68 if (vp) { 68 ip->i_d.di_atime.t_sec = (__int32_t)inode->i_atime.tv_sec;
69 ip->i_d.di_atime.t_sec = (__int32_t)vp->i_atime.tv_sec; 69 ip->i_d.di_atime.t_nsec = (__int32_t)inode->i_atime.tv_nsec;
70 ip->i_d.di_atime.t_nsec = (__int32_t)vp->i_atime.tv_nsec;
71 } 70 }
72} 71}
73 72
@@ -80,11 +79,10 @@ void
80xfs_mark_inode_dirty_sync( 79xfs_mark_inode_dirty_sync(
81 xfs_inode_t *ip) 80 xfs_inode_t *ip)
82{ 81{
83 bhv_vnode_t *vp; 82 struct inode *inode = ip->i_vnode;
84 83
85 vp = XFS_ITOV_NULL(ip); 84 if (inode)
86 if (vp) 85 mark_inode_dirty_sync(inode);
87 mark_inode_dirty_sync(vn_to_inode(vp));
88} 86}
89 87
90/* 88/*
@@ -157,13 +155,6 @@ xfs_ichgtime_fast(
157 */ 155 */
158 ASSERT((flags & XFS_ICHGTIME_ACC) == 0); 156 ASSERT((flags & XFS_ICHGTIME_ACC) == 0);
159 157
160 /*
161 * We're not supposed to change timestamps in readonly-mounted
162 * filesystems. Throw it away if anyone asks us.
163 */
164 if (unlikely(IS_RDONLY(inode)))
165 return;
166
167 if (flags & XFS_ICHGTIME_MOD) { 158 if (flags & XFS_ICHGTIME_MOD) {
168 tvp = &inode->i_mtime; 159 tvp = &inode->i_mtime;
169 ip->i_d.di_mtime.t_sec = (__int32_t)tvp->tv_sec; 160 ip->i_d.di_mtime.t_sec = (__int32_t)tvp->tv_sec;
@@ -215,66 +206,62 @@ xfs_validate_fields(
215 */ 206 */
216STATIC int 207STATIC int
217xfs_init_security( 208xfs_init_security(
218 bhv_vnode_t *vp, 209 struct inode *inode,
219 struct inode *dir) 210 struct inode *dir)
220{ 211{
221 struct inode *ip = vn_to_inode(vp); 212 struct xfs_inode *ip = XFS_I(inode);
222 size_t length; 213 size_t length;
223 void *value; 214 void *value;
224 char *name; 215 char *name;
225 int error; 216 int error;
226 217
227 error = security_inode_init_security(ip, dir, &name, &value, &length); 218 error = security_inode_init_security(inode, dir, &name,
219 &value, &length);
228 if (error) { 220 if (error) {
229 if (error == -EOPNOTSUPP) 221 if (error == -EOPNOTSUPP)
230 return 0; 222 return 0;
231 return -error; 223 return -error;
232 } 224 }
233 225
234 error = xfs_attr_set(XFS_I(ip), name, value, 226 error = xfs_attr_set(ip, name, value, length, ATTR_SECURE);
235 length, ATTR_SECURE);
236 if (!error) 227 if (!error)
237 xfs_iflags_set(XFS_I(ip), XFS_IMODIFIED); 228 xfs_iflags_set(ip, XFS_IMODIFIED);
238 229
239 kfree(name); 230 kfree(name);
240 kfree(value); 231 kfree(value);
241 return error; 232 return error;
242} 233}
243 234
244/* 235static void
245 * Determine whether a process has a valid fs_struct (kernel daemons 236xfs_dentry_to_name(
246 * like knfsd don't have an fs_struct). 237 struct xfs_name *namep,
247 * 238 struct dentry *dentry)
248 * XXX(hch): nfsd is broken, better fix it instead.
249 */
250STATIC_INLINE int
251xfs_has_fs_struct(struct task_struct *task)
252{ 239{
253 return (task->fs != init_task.fs); 240 namep->name = dentry->d_name.name;
241 namep->len = dentry->d_name.len;
254} 242}
255 243
256STATIC void 244STATIC void
257xfs_cleanup_inode( 245xfs_cleanup_inode(
258 struct inode *dir, 246 struct inode *dir,
259 bhv_vnode_t *vp, 247 struct inode *inode,
260 struct dentry *dentry, 248 struct dentry *dentry,
261 int mode) 249 int mode)
262{ 250{
263 struct dentry teardown = {}; 251 struct xfs_name teardown;
264 252
265 /* Oh, the horror. 253 /* Oh, the horror.
266 * If we can't add the ACL or we fail in 254 * If we can't add the ACL or we fail in
267 * xfs_init_security we must back out. 255 * xfs_init_security we must back out.
268 * ENOSPC can hit here, among other things. 256 * ENOSPC can hit here, among other things.
269 */ 257 */
270 teardown.d_inode = vn_to_inode(vp); 258 xfs_dentry_to_name(&teardown, dentry);
271 teardown.d_name = dentry->d_name;
272 259
273 if (S_ISDIR(mode)) 260 if (S_ISDIR(mode))
274 xfs_rmdir(XFS_I(dir), &teardown); 261 xfs_rmdir(XFS_I(dir), &teardown, XFS_I(inode));
275 else 262 else
276 xfs_remove(XFS_I(dir), &teardown); 263 xfs_remove(XFS_I(dir), &teardown, XFS_I(inode));
277 VN_RELE(vp); 264 iput(inode);
278} 265}
279 266
280STATIC int 267STATIC int
@@ -284,9 +271,10 @@ xfs_vn_mknod(
284 int mode, 271 int mode,
285 dev_t rdev) 272 dev_t rdev)
286{ 273{
287 struct inode *ip; 274 struct inode *inode;
288 bhv_vnode_t *vp = NULL, *dvp = vn_from_inode(dir); 275 struct xfs_inode *ip = NULL;
289 xfs_acl_t *default_acl = NULL; 276 xfs_acl_t *default_acl = NULL;
277 struct xfs_name name;
290 attrexists_t test_default_acl = _ACL_DEFAULT_EXISTS; 278 attrexists_t test_default_acl = _ACL_DEFAULT_EXISTS;
291 int error; 279 int error;
292 280
@@ -297,59 +285,67 @@ xfs_vn_mknod(
297 if (unlikely(!sysv_valid_dev(rdev) || MAJOR(rdev) & ~0x1ff)) 285 if (unlikely(!sysv_valid_dev(rdev) || MAJOR(rdev) & ~0x1ff))
298 return -EINVAL; 286 return -EINVAL;
299 287
300 if (unlikely(test_default_acl && test_default_acl(dvp))) { 288 if (test_default_acl && test_default_acl(dir)) {
301 if (!_ACL_ALLOC(default_acl)) { 289 if (!_ACL_ALLOC(default_acl)) {
302 return -ENOMEM; 290 return -ENOMEM;
303 } 291 }
304 if (!_ACL_GET_DEFAULT(dvp, default_acl)) { 292 if (!_ACL_GET_DEFAULT(dir, default_acl)) {
305 _ACL_FREE(default_acl); 293 _ACL_FREE(default_acl);
306 default_acl = NULL; 294 default_acl = NULL;
307 } 295 }
308 } 296 }
309 297
310 if (IS_POSIXACL(dir) && !default_acl && xfs_has_fs_struct(current)) 298 xfs_dentry_to_name(&name, dentry);
299
300 if (IS_POSIXACL(dir) && !default_acl)
311 mode &= ~current->fs->umask; 301 mode &= ~current->fs->umask;
312 302
313 switch (mode & S_IFMT) { 303 switch (mode & S_IFMT) {
314 case S_IFCHR: case S_IFBLK: case S_IFIFO: case S_IFSOCK: 304 case S_IFCHR:
305 case S_IFBLK:
306 case S_IFIFO:
307 case S_IFSOCK:
315 rdev = sysv_encode_dev(rdev); 308 rdev = sysv_encode_dev(rdev);
316 case S_IFREG: 309 case S_IFREG:
317 error = xfs_create(XFS_I(dir), dentry, mode, rdev, &vp, NULL); 310 error = xfs_create(XFS_I(dir), &name, mode, rdev, &ip, NULL);
318 break; 311 break;
319 case S_IFDIR: 312 case S_IFDIR:
320 error = xfs_mkdir(XFS_I(dir), dentry, mode, &vp, NULL); 313 error = xfs_mkdir(XFS_I(dir), &name, mode, &ip, NULL);
321 break; 314 break;
322 default: 315 default:
323 error = EINVAL; 316 error = EINVAL;
324 break; 317 break;
325 } 318 }
326 319
327 if (unlikely(!error)) { 320 if (unlikely(error))
328 error = xfs_init_security(vp, dir); 321 goto out_free_acl;
329 if (error)
330 xfs_cleanup_inode(dir, vp, dentry, mode);
331 }
332 322
333 if (unlikely(default_acl)) { 323 inode = ip->i_vnode;
334 if (!error) { 324
335 error = _ACL_INHERIT(vp, mode, default_acl); 325 error = xfs_init_security(inode, dir);
336 if (!error) 326 if (unlikely(error))
337 xfs_iflags_set(XFS_I(vp), XFS_IMODIFIED); 327 goto out_cleanup_inode;
338 else 328
339 xfs_cleanup_inode(dir, vp, dentry, mode); 329 if (default_acl) {
340 } 330 error = _ACL_INHERIT(inode, mode, default_acl);
331 if (unlikely(error))
332 goto out_cleanup_inode;
333 xfs_iflags_set(ip, XFS_IMODIFIED);
341 _ACL_FREE(default_acl); 334 _ACL_FREE(default_acl);
342 } 335 }
343 336
344 if (likely(!error)) {
345 ASSERT(vp);
346 ip = vn_to_inode(vp);
347 337
348 if (S_ISDIR(mode)) 338 if (S_ISDIR(mode))
349 xfs_validate_fields(ip); 339 xfs_validate_fields(inode);
350 d_instantiate(dentry, ip); 340 d_instantiate(dentry, inode);
351 xfs_validate_fields(dir); 341 xfs_validate_fields(dir);
352 } 342 return -error;
343
344 out_cleanup_inode:
345 xfs_cleanup_inode(dir, inode, dentry, mode);
346 out_free_acl:
347 if (default_acl)
348 _ACL_FREE(default_acl);
353 return -error; 349 return -error;
354} 350}
355 351
@@ -378,13 +374,15 @@ xfs_vn_lookup(
378 struct dentry *dentry, 374 struct dentry *dentry,
379 struct nameidata *nd) 375 struct nameidata *nd)
380{ 376{
381 bhv_vnode_t *cvp; 377 struct xfs_inode *cip;
378 struct xfs_name name;
382 int error; 379 int error;
383 380
384 if (dentry->d_name.len >= MAXNAMELEN) 381 if (dentry->d_name.len >= MAXNAMELEN)
385 return ERR_PTR(-ENAMETOOLONG); 382 return ERR_PTR(-ENAMETOOLONG);
386 383
387 error = xfs_lookup(XFS_I(dir), dentry, &cvp); 384 xfs_dentry_to_name(&name, dentry);
385 error = xfs_lookup(XFS_I(dir), &name, &cip);
388 if (unlikely(error)) { 386 if (unlikely(error)) {
389 if (unlikely(error != ENOENT)) 387 if (unlikely(error != ENOENT))
390 return ERR_PTR(-error); 388 return ERR_PTR(-error);
@@ -392,7 +390,7 @@ xfs_vn_lookup(
392 return NULL; 390 return NULL;
393 } 391 }
394 392
395 return d_splice_alias(vn_to_inode(cvp), dentry); 393 return d_splice_alias(cip->i_vnode, dentry);
396} 394}
397 395
398STATIC int 396STATIC int
@@ -401,23 +399,24 @@ xfs_vn_link(
401 struct inode *dir, 399 struct inode *dir,
402 struct dentry *dentry) 400 struct dentry *dentry)
403{ 401{
404 struct inode *ip; /* inode of guy being linked to */ 402 struct inode *inode; /* inode of guy being linked to */
405 bhv_vnode_t *vp; /* vp of name being linked */ 403 struct xfs_name name;
406 int error; 404 int error;
407 405
408 ip = old_dentry->d_inode; /* inode being linked to */ 406 inode = old_dentry->d_inode;
409 vp = vn_from_inode(ip); 407 xfs_dentry_to_name(&name, dentry);
410 408
411 VN_HOLD(vp); 409 igrab(inode);
412 error = xfs_link(XFS_I(dir), vp, dentry); 410 error = xfs_link(XFS_I(dir), XFS_I(inode), &name);
413 if (unlikely(error)) { 411 if (unlikely(error)) {
414 VN_RELE(vp); 412 iput(inode);
415 } else { 413 return -error;
416 xfs_iflags_set(XFS_I(dir), XFS_IMODIFIED);
417 xfs_validate_fields(ip);
418 d_instantiate(dentry, ip);
419 } 414 }
420 return -error; 415
416 xfs_iflags_set(XFS_I(dir), XFS_IMODIFIED);
417 xfs_validate_fields(inode);
418 d_instantiate(dentry, inode);
419 return 0;
421} 420}
422 421
423STATIC int 422STATIC int
@@ -426,11 +425,13 @@ xfs_vn_unlink(
426 struct dentry *dentry) 425 struct dentry *dentry)
427{ 426{
428 struct inode *inode; 427 struct inode *inode;
428 struct xfs_name name;
429 int error; 429 int error;
430 430
431 inode = dentry->d_inode; 431 inode = dentry->d_inode;
432 xfs_dentry_to_name(&name, dentry);
432 433
433 error = xfs_remove(XFS_I(dir), dentry); 434 error = xfs_remove(XFS_I(dir), &name, XFS_I(inode));
434 if (likely(!error)) { 435 if (likely(!error)) {
435 xfs_validate_fields(dir); /* size needs update */ 436 xfs_validate_fields(dir); /* size needs update */
436 xfs_validate_fields(inode); 437 xfs_validate_fields(inode);
@@ -444,29 +445,34 @@ xfs_vn_symlink(
444 struct dentry *dentry, 445 struct dentry *dentry,
445 const char *symname) 446 const char *symname)
446{ 447{
447 struct inode *ip; 448 struct inode *inode;
448 bhv_vnode_t *cvp; /* used to lookup symlink to put in dentry */ 449 struct xfs_inode *cip = NULL;
450 struct xfs_name name;
449 int error; 451 int error;
450 mode_t mode; 452 mode_t mode;
451 453
452 cvp = NULL;
453
454 mode = S_IFLNK | 454 mode = S_IFLNK |
455 (irix_symlink_mode ? 0777 & ~current->fs->umask : S_IRWXUGO); 455 (irix_symlink_mode ? 0777 & ~current->fs->umask : S_IRWXUGO);
456 xfs_dentry_to_name(&name, dentry);
456 457
457 error = xfs_symlink(XFS_I(dir), dentry, (char *)symname, mode, 458 error = xfs_symlink(XFS_I(dir), &name, symname, mode, &cip, NULL);
458 &cvp, NULL); 459 if (unlikely(error))
459 if (likely(!error && cvp)) { 460 goto out;
460 error = xfs_init_security(cvp, dir); 461
461 if (likely(!error)) { 462 inode = cip->i_vnode;
462 ip = vn_to_inode(cvp); 463
463 d_instantiate(dentry, ip); 464 error = xfs_init_security(inode, dir);
464 xfs_validate_fields(dir); 465 if (unlikely(error))
465 xfs_validate_fields(ip); 466 goto out_cleanup_inode;
466 } else { 467
467 xfs_cleanup_inode(dir, cvp, dentry, 0); 468 d_instantiate(dentry, inode);
468 } 469 xfs_validate_fields(dir);
469 } 470 xfs_validate_fields(inode);
471 return 0;
472
473 out_cleanup_inode:
474 xfs_cleanup_inode(dir, inode, dentry, 0);
475 out:
470 return -error; 476 return -error;
471} 477}
472 478
@@ -476,9 +482,12 @@ xfs_vn_rmdir(
476 struct dentry *dentry) 482 struct dentry *dentry)
477{ 483{
478 struct inode *inode = dentry->d_inode; 484 struct inode *inode = dentry->d_inode;
485 struct xfs_name name;
479 int error; 486 int error;
480 487
481 error = xfs_rmdir(XFS_I(dir), dentry); 488 xfs_dentry_to_name(&name, dentry);
489
490 error = xfs_rmdir(XFS_I(dir), &name, XFS_I(inode));
482 if (likely(!error)) { 491 if (likely(!error)) {
483 xfs_validate_fields(inode); 492 xfs_validate_fields(inode);
484 xfs_validate_fields(dir); 493 xfs_validate_fields(dir);
@@ -494,12 +503,15 @@ xfs_vn_rename(
494 struct dentry *ndentry) 503 struct dentry *ndentry)
495{ 504{
496 struct inode *new_inode = ndentry->d_inode; 505 struct inode *new_inode = ndentry->d_inode;
497 bhv_vnode_t *tvp; /* target directory */ 506 struct xfs_name oname;
507 struct xfs_name nname;
498 int error; 508 int error;
499 509
500 tvp = vn_from_inode(ndir); 510 xfs_dentry_to_name(&oname, odentry);
511 xfs_dentry_to_name(&nname, ndentry);
501 512
502 error = xfs_rename(XFS_I(odir), odentry, tvp, ndentry); 513 error = xfs_rename(XFS_I(odir), &oname, XFS_I(odentry->d_inode),
514 XFS_I(ndir), &nname);
503 if (likely(!error)) { 515 if (likely(!error)) {
504 if (new_inode) 516 if (new_inode)
505 xfs_validate_fields(new_inode); 517 xfs_validate_fields(new_inode);
@@ -700,11 +712,19 @@ xfs_vn_setattr(
700 return -error; 712 return -error;
701} 713}
702 714
715/*
716 * block_truncate_page can return an error, but we can't propagate it
717 * at all here. Leave a complaint + stack trace in the syslog because
718 * this could be bad. If it is bad, we need to propagate the error further.
719 */
703STATIC void 720STATIC void
704xfs_vn_truncate( 721xfs_vn_truncate(
705 struct inode *inode) 722 struct inode *inode)
706{ 723{
707 block_truncate_page(inode->i_mapping, inode->i_size, xfs_get_blocks); 724 int error;
725 error = block_truncate_page(inode->i_mapping, inode->i_size,
726 xfs_get_blocks);
727 WARN_ON(error);
708} 728}
709 729
710STATIC int 730STATIC int