aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_iops.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_iops.c')
-rw-r--r--fs/xfs/xfs_iops.c89
1 files changed, 65 insertions, 24 deletions
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index 405a65cd9d6b..ebfc13350f9a 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -98,12 +98,27 @@ xfs_init_security(
98static void 98static void
99xfs_dentry_to_name( 99xfs_dentry_to_name(
100 struct xfs_name *namep, 100 struct xfs_name *namep,
101 struct dentry *dentry)
102{
103 namep->name = dentry->d_name.name;
104 namep->len = dentry->d_name.len;
105 namep->type = XFS_DIR3_FT_UNKNOWN;
106}
107
108static int
109xfs_dentry_mode_to_name(
110 struct xfs_name *namep,
101 struct dentry *dentry, 111 struct dentry *dentry,
102 int mode) 112 int mode)
103{ 113{
104 namep->name = dentry->d_name.name; 114 namep->name = dentry->d_name.name;
105 namep->len = dentry->d_name.len; 115 namep->len = dentry->d_name.len;
106 namep->type = xfs_mode_to_ftype[(mode & S_IFMT) >> S_SHIFT]; 116 namep->type = xfs_mode_to_ftype(mode);
117
118 if (unlikely(namep->type == XFS_DIR3_FT_UNKNOWN))
119 return -EFSCORRUPTED;
120
121 return 0;
107} 122}
108 123
109STATIC void 124STATIC void
@@ -119,7 +134,7 @@ xfs_cleanup_inode(
119 * xfs_init_security we must back out. 134 * xfs_init_security we must back out.
120 * ENOSPC can hit here, among other things. 135 * ENOSPC can hit here, among other things.
121 */ 136 */
122 xfs_dentry_to_name(&teardown, dentry, 0); 137 xfs_dentry_to_name(&teardown, dentry);
123 138
124 xfs_remove(XFS_I(dir), &teardown, XFS_I(inode)); 139 xfs_remove(XFS_I(dir), &teardown, XFS_I(inode));
125} 140}
@@ -154,8 +169,12 @@ xfs_generic_create(
154 if (error) 169 if (error)
155 return error; 170 return error;
156 171
172 /* Verify mode is valid also for tmpfile case */
173 error = xfs_dentry_mode_to_name(&name, dentry, mode);
174 if (unlikely(error))
175 goto out_free_acl;
176
157 if (!tmpfile) { 177 if (!tmpfile) {
158 xfs_dentry_to_name(&name, dentry, mode);
159 error = xfs_create(XFS_I(dir), &name, mode, rdev, &ip); 178 error = xfs_create(XFS_I(dir), &name, mode, rdev, &ip);
160 } else { 179 } else {
161 error = xfs_create_tmpfile(XFS_I(dir), dentry, mode, &ip); 180 error = xfs_create_tmpfile(XFS_I(dir), dentry, mode, &ip);
@@ -248,7 +267,7 @@ xfs_vn_lookup(
248 if (dentry->d_name.len >= MAXNAMELEN) 267 if (dentry->d_name.len >= MAXNAMELEN)
249 return ERR_PTR(-ENAMETOOLONG); 268 return ERR_PTR(-ENAMETOOLONG);
250 269
251 xfs_dentry_to_name(&name, dentry, 0); 270 xfs_dentry_to_name(&name, dentry);
252 error = xfs_lookup(XFS_I(dir), &name, &cip, NULL); 271 error = xfs_lookup(XFS_I(dir), &name, &cip, NULL);
253 if (unlikely(error)) { 272 if (unlikely(error)) {
254 if (unlikely(error != -ENOENT)) 273 if (unlikely(error != -ENOENT))
@@ -275,7 +294,7 @@ xfs_vn_ci_lookup(
275 if (dentry->d_name.len >= MAXNAMELEN) 294 if (dentry->d_name.len >= MAXNAMELEN)
276 return ERR_PTR(-ENAMETOOLONG); 295 return ERR_PTR(-ENAMETOOLONG);
277 296
278 xfs_dentry_to_name(&xname, dentry, 0); 297 xfs_dentry_to_name(&xname, dentry);
279 error = xfs_lookup(XFS_I(dir), &xname, &ip, &ci_name); 298 error = xfs_lookup(XFS_I(dir), &xname, &ip, &ci_name);
280 if (unlikely(error)) { 299 if (unlikely(error)) {
281 if (unlikely(error != -ENOENT)) 300 if (unlikely(error != -ENOENT))
@@ -310,7 +329,9 @@ xfs_vn_link(
310 struct xfs_name name; 329 struct xfs_name name;
311 int error; 330 int error;
312 331
313 xfs_dentry_to_name(&name, dentry, inode->i_mode); 332 error = xfs_dentry_mode_to_name(&name, dentry, inode->i_mode);
333 if (unlikely(error))
334 return error;
314 335
315 error = xfs_link(XFS_I(dir), XFS_I(inode), &name); 336 error = xfs_link(XFS_I(dir), XFS_I(inode), &name);
316 if (unlikely(error)) 337 if (unlikely(error))
@@ -329,7 +350,7 @@ xfs_vn_unlink(
329 struct xfs_name name; 350 struct xfs_name name;
330 int error; 351 int error;
331 352
332 xfs_dentry_to_name(&name, dentry, 0); 353 xfs_dentry_to_name(&name, dentry);
333 354
334 error = xfs_remove(XFS_I(dir), &name, XFS_I(d_inode(dentry))); 355 error = xfs_remove(XFS_I(dir), &name, XFS_I(d_inode(dentry)));
335 if (error) 356 if (error)
@@ -359,7 +380,9 @@ xfs_vn_symlink(
359 380
360 mode = S_IFLNK | 381 mode = S_IFLNK |
361 (irix_symlink_mode ? 0777 & ~current_umask() : S_IRWXUGO); 382 (irix_symlink_mode ? 0777 & ~current_umask() : S_IRWXUGO);
362 xfs_dentry_to_name(&name, dentry, mode); 383 error = xfs_dentry_mode_to_name(&name, dentry, mode);
384 if (unlikely(error))
385 goto out;
363 386
364 error = xfs_symlink(XFS_I(dir), &name, symname, mode, &cip); 387 error = xfs_symlink(XFS_I(dir), &name, symname, mode, &cip);
365 if (unlikely(error)) 388 if (unlikely(error))
@@ -395,6 +418,7 @@ xfs_vn_rename(
395{ 418{
396 struct inode *new_inode = d_inode(ndentry); 419 struct inode *new_inode = d_inode(ndentry);
397 int omode = 0; 420 int omode = 0;
421 int error;
398 struct xfs_name oname; 422 struct xfs_name oname;
399 struct xfs_name nname; 423 struct xfs_name nname;
400 424
@@ -405,8 +429,14 @@ xfs_vn_rename(
405 if (flags & RENAME_EXCHANGE) 429 if (flags & RENAME_EXCHANGE)
406 omode = d_inode(ndentry)->i_mode; 430 omode = d_inode(ndentry)->i_mode;
407 431
408 xfs_dentry_to_name(&oname, odentry, omode); 432 error = xfs_dentry_mode_to_name(&oname, odentry, omode);
409 xfs_dentry_to_name(&nname, ndentry, d_inode(odentry)->i_mode); 433 if (omode && unlikely(error))
434 return error;
435
436 error = xfs_dentry_mode_to_name(&nname, ndentry,
437 d_inode(odentry)->i_mode);
438 if (unlikely(error))
439 return error;
410 440
411 return xfs_rename(XFS_I(odir), &oname, XFS_I(d_inode(odentry)), 441 return xfs_rename(XFS_I(odir), &oname, XFS_I(d_inode(odentry)),
412 XFS_I(ndir), &nname, 442 XFS_I(ndir), &nname,
@@ -459,11 +489,12 @@ xfs_vn_get_link_inline(
459 489
460STATIC int 490STATIC int
461xfs_vn_getattr( 491xfs_vn_getattr(
462 struct vfsmount *mnt, 492 const struct path *path,
463 struct dentry *dentry, 493 struct kstat *stat,
464 struct kstat *stat) 494 u32 request_mask,
495 unsigned int query_flags)
465{ 496{
466 struct inode *inode = d_inode(dentry); 497 struct inode *inode = d_inode(path->dentry);
467 struct xfs_inode *ip = XFS_I(inode); 498 struct xfs_inode *ip = XFS_I(inode);
468 struct xfs_mount *mp = ip->i_mount; 499 struct xfs_mount *mp = ip->i_mount;
469 500
@@ -485,6 +516,20 @@ xfs_vn_getattr(
485 stat->blocks = 516 stat->blocks =
486 XFS_FSB_TO_BB(mp, ip->i_d.di_nblocks + ip->i_delayed_blks); 517 XFS_FSB_TO_BB(mp, ip->i_d.di_nblocks + ip->i_delayed_blks);
487 518
519 if (ip->i_d.di_version == 3) {
520 if (request_mask & STATX_BTIME) {
521 stat->result_mask |= STATX_BTIME;
522 stat->btime.tv_sec = ip->i_d.di_crtime.t_sec;
523 stat->btime.tv_nsec = ip->i_d.di_crtime.t_nsec;
524 }
525 }
526
527 if (ip->i_d.di_flags & XFS_DIFLAG_IMMUTABLE)
528 stat->attributes |= STATX_ATTR_IMMUTABLE;
529 if (ip->i_d.di_flags & XFS_DIFLAG_APPEND)
530 stat->attributes |= STATX_ATTR_APPEND;
531 if (ip->i_d.di_flags & XFS_DIFLAG_NODUMP)
532 stat->attributes |= STATX_ATTR_NODUMP;
488 533
489 switch (inode->i_mode & S_IFMT) { 534 switch (inode->i_mode & S_IFMT) {
490 case S_IFBLK: 535 case S_IFBLK:
@@ -983,15 +1028,13 @@ xfs_vn_setattr(
983 struct xfs_inode *ip = XFS_I(d_inode(dentry)); 1028 struct xfs_inode *ip = XFS_I(d_inode(dentry));
984 uint iolock = XFS_IOLOCK_EXCL; 1029 uint iolock = XFS_IOLOCK_EXCL;
985 1030
986 xfs_ilock(ip, iolock); 1031 error = xfs_break_layouts(d_inode(dentry), &iolock);
987 error = xfs_break_layouts(d_inode(dentry), &iolock, true); 1032 if (error)
988 if (!error) { 1033 return error;
989 xfs_ilock(ip, XFS_MMAPLOCK_EXCL);
990 iolock |= XFS_MMAPLOCK_EXCL;
991 1034
992 error = xfs_vn_setattr_size(dentry, iattr); 1035 xfs_ilock(ip, XFS_MMAPLOCK_EXCL);
993 } 1036 error = xfs_vn_setattr_size(dentry, iattr);
994 xfs_iunlock(ip, iolock); 1037 xfs_iunlock(ip, XFS_MMAPLOCK_EXCL);
995 } else { 1038 } else {
996 error = xfs_vn_setattr_nonsize(dentry, iattr); 1039 error = xfs_vn_setattr_nonsize(dentry, iattr);
997 } 1040 }
@@ -1122,7 +1165,6 @@ static const struct inode_operations xfs_dir_ci_inode_operations = {
1122}; 1165};
1123 1166
1124static const struct inode_operations xfs_symlink_inode_operations = { 1167static const struct inode_operations xfs_symlink_inode_operations = {
1125 .readlink = generic_readlink,
1126 .get_link = xfs_vn_get_link, 1168 .get_link = xfs_vn_get_link,
1127 .getattr = xfs_vn_getattr, 1169 .getattr = xfs_vn_getattr,
1128 .setattr = xfs_vn_setattr, 1170 .setattr = xfs_vn_setattr,
@@ -1131,7 +1173,6 @@ static const struct inode_operations xfs_symlink_inode_operations = {
1131}; 1173};
1132 1174
1133static const struct inode_operations xfs_inline_symlink_inode_operations = { 1175static const struct inode_operations xfs_inline_symlink_inode_operations = {
1134 .readlink = generic_readlink,
1135 .get_link = xfs_vn_get_link_inline, 1176 .get_link = xfs_vn_get_link_inline,
1136 .getattr = xfs_vn_getattr, 1177 .getattr = xfs_vn_getattr,
1137 .setattr = xfs_vn_setattr, 1178 .setattr = xfs_vn_setattr,