1c59d87c4SChristoph Hellwig /* 2c59d87c4SChristoph Hellwig * Copyright (c) 2000-2005 Silicon Graphics, Inc. 3c59d87c4SChristoph Hellwig * All Rights Reserved. 4c59d87c4SChristoph Hellwig * 5c59d87c4SChristoph Hellwig * This program is free software; you can redistribute it and/or 6c59d87c4SChristoph Hellwig * modify it under the terms of the GNU General Public License as 7c59d87c4SChristoph Hellwig * published by the Free Software Foundation. 8c59d87c4SChristoph Hellwig * 9c59d87c4SChristoph Hellwig * This program is distributed in the hope that it would be useful, 10c59d87c4SChristoph Hellwig * but WITHOUT ANY WARRANTY; without even the implied warranty of 11c59d87c4SChristoph Hellwig * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12c59d87c4SChristoph Hellwig * GNU General Public License for more details. 13c59d87c4SChristoph Hellwig * 14c59d87c4SChristoph Hellwig * You should have received a copy of the GNU General Public License 15c59d87c4SChristoph Hellwig * along with this program; if not, write the Free Software Foundation, 16c59d87c4SChristoph Hellwig * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17c59d87c4SChristoph Hellwig */ 18c59d87c4SChristoph Hellwig #include "xfs.h" 19c59d87c4SChristoph Hellwig #include "xfs_fs.h" 2070a9883cSDave Chinner #include "xfs_shared.h" 21239880efSDave Chinner #include "xfs_format.h" 22239880efSDave Chinner #include "xfs_log_format.h" 23239880efSDave Chinner #include "xfs_trans_resv.h" 24c59d87c4SChristoph Hellwig #include "xfs_sb.h" 25c59d87c4SChristoph Hellwig #include "xfs_ag.h" 26c59d87c4SChristoph Hellwig #include "xfs_mount.h" 2757062787SDave Chinner #include "xfs_da_format.h" 28c59d87c4SChristoph Hellwig #include "xfs_inode.h" 29c59d87c4SChristoph Hellwig #include "xfs_bmap.h" 3068988114SDave Chinner #include "xfs_bmap_util.h" 31239880efSDave Chinner #include "xfs_acl.h" 32239880efSDave Chinner #include "xfs_quota.h" 33c59d87c4SChristoph Hellwig #include "xfs_error.h" 34c59d87c4SChristoph Hellwig #include "xfs_attr.h" 35239880efSDave Chinner #include "xfs_trans.h" 36c59d87c4SChristoph Hellwig #include "xfs_trace.h" 3727b52867SBrian Foster #include "xfs_icache.h" 38c24b5dfaSDave Chinner #include "xfs_symlink.h" 390cb97766SDave Chinner #include "xfs_da_btree.h" 400cb97766SDave Chinner #include "xfs_dir2_priv.h" 41a4fbe6abSDave Chinner #include "xfs_dinode.h" 4299b6436bSZhi Yong Wu #include "xfs_trans_space.h" 43c59d87c4SChristoph Hellwig 44c59d87c4SChristoph Hellwig #include <linux/capability.h> 45c59d87c4SChristoph Hellwig #include <linux/xattr.h> 46c59d87c4SChristoph Hellwig #include <linux/namei.h> 47c59d87c4SChristoph Hellwig #include <linux/posix_acl.h> 48c59d87c4SChristoph Hellwig #include <linux/security.h> 49c59d87c4SChristoph Hellwig #include <linux/fiemap.h> 50c59d87c4SChristoph Hellwig #include <linux/slab.h> 51c59d87c4SChristoph Hellwig 5293a8614eSDave Chinner /* 5393a8614eSDave Chinner * Directories have different lock order w.r.t. mmap_sem compared to regular 5493a8614eSDave Chinner * files. This is due to readdir potentially triggering page faults on a user 5593a8614eSDave Chinner * buffer inside filldir(), and this happens with the ilock on the directory 5693a8614eSDave Chinner * held. For regular files, the lock order is the other way around - the 5793a8614eSDave Chinner * mmap_sem is taken during the page fault, and then we lock the ilock to do 5893a8614eSDave Chinner * block mapping. Hence we need a different class for the directory ilock so 5993a8614eSDave Chinner * that lockdep can tell them apart. 6093a8614eSDave Chinner */ 6193a8614eSDave Chinner static struct lock_class_key xfs_nondir_ilock_class; 6293a8614eSDave Chinner static struct lock_class_key xfs_dir_ilock_class; 6393a8614eSDave Chinner 648d2a5e6eSDave Chinner static int 658d2a5e6eSDave Chinner xfs_initxattrs( 668d2a5e6eSDave Chinner struct inode *inode, 678d2a5e6eSDave Chinner const struct xattr *xattr_array, 6836b8d186SLinus Torvalds void *fs_info) 6936b8d186SLinus Torvalds { 7036b8d186SLinus Torvalds const struct xattr *xattr; 7136b8d186SLinus Torvalds struct xfs_inode *ip = XFS_I(inode); 7236b8d186SLinus Torvalds int error = 0; 7336b8d186SLinus Torvalds 7436b8d186SLinus Torvalds for (xattr = xattr_array; xattr->name != NULL; xattr++) { 7536b8d186SLinus Torvalds error = xfs_attr_set(ip, xattr->name, xattr->value, 7636b8d186SLinus Torvalds xattr->value_len, ATTR_SECURE); 7736b8d186SLinus Torvalds if (error < 0) 7836b8d186SLinus Torvalds break; 7936b8d186SLinus Torvalds } 8036b8d186SLinus Torvalds return error; 8136b8d186SLinus Torvalds } 8236b8d186SLinus Torvalds 83c59d87c4SChristoph Hellwig /* 84c59d87c4SChristoph Hellwig * Hook in SELinux. This is not quite correct yet, what we really need 85c59d87c4SChristoph Hellwig * here (as we do for default ACLs) is a mechanism by which creation of 86c59d87c4SChristoph Hellwig * these attrs can be journalled at inode creation time (along with the 87c59d87c4SChristoph Hellwig * inode, of course, such that log replay can't cause these to be lost). 88c59d87c4SChristoph Hellwig */ 8936b8d186SLinus Torvalds 90c59d87c4SChristoph Hellwig STATIC int 91c59d87c4SChristoph Hellwig xfs_init_security( 92c59d87c4SChristoph Hellwig struct inode *inode, 93c59d87c4SChristoph Hellwig struct inode *dir, 94c59d87c4SChristoph Hellwig const struct qstr *qstr) 95c59d87c4SChristoph Hellwig { 9636b8d186SLinus Torvalds return security_inode_init_security(inode, dir, qstr, 9736b8d186SLinus Torvalds &xfs_initxattrs, NULL); 98c59d87c4SChristoph Hellwig } 99c59d87c4SChristoph Hellwig 100c59d87c4SChristoph Hellwig static void 101c59d87c4SChristoph Hellwig xfs_dentry_to_name( 102c59d87c4SChristoph Hellwig struct xfs_name *namep, 1030cb97766SDave Chinner struct dentry *dentry, 1040cb97766SDave Chinner int mode) 105c59d87c4SChristoph Hellwig { 106c59d87c4SChristoph Hellwig namep->name = dentry->d_name.name; 107c59d87c4SChristoph Hellwig namep->len = dentry->d_name.len; 1080cb97766SDave Chinner namep->type = xfs_mode_to_ftype[(mode & S_IFMT) >> S_SHIFT]; 109c59d87c4SChristoph Hellwig } 110c59d87c4SChristoph Hellwig 111c59d87c4SChristoph Hellwig STATIC void 112c59d87c4SChristoph Hellwig xfs_cleanup_inode( 113c59d87c4SChristoph Hellwig struct inode *dir, 114c59d87c4SChristoph Hellwig struct inode *inode, 115c59d87c4SChristoph Hellwig struct dentry *dentry) 116c59d87c4SChristoph Hellwig { 117c59d87c4SChristoph Hellwig struct xfs_name teardown; 118c59d87c4SChristoph Hellwig 119c59d87c4SChristoph Hellwig /* Oh, the horror. 120c59d87c4SChristoph Hellwig * If we can't add the ACL or we fail in 121c59d87c4SChristoph Hellwig * xfs_init_security we must back out. 122c59d87c4SChristoph Hellwig * ENOSPC can hit here, among other things. 123c59d87c4SChristoph Hellwig */ 1240cb97766SDave Chinner xfs_dentry_to_name(&teardown, dentry, 0); 125c59d87c4SChristoph Hellwig 126c59d87c4SChristoph Hellwig xfs_remove(XFS_I(dir), &teardown, XFS_I(inode)); 127c59d87c4SChristoph Hellwig } 128c59d87c4SChristoph Hellwig 129c59d87c4SChristoph Hellwig STATIC int 130*d540e43bSBrian Foster xfs_generic_create( 131c59d87c4SChristoph Hellwig struct inode *dir, 132c59d87c4SChristoph Hellwig struct dentry *dentry, 1331a67aafbSAl Viro umode_t mode, 134*d540e43bSBrian Foster dev_t rdev, 135*d540e43bSBrian Foster bool tmpfile) /* unnamed file */ 136c59d87c4SChristoph Hellwig { 137c59d87c4SChristoph Hellwig struct inode *inode; 138c59d87c4SChristoph Hellwig struct xfs_inode *ip = NULL; 1392401dc29SChristoph Hellwig struct posix_acl *default_acl, *acl; 140c59d87c4SChristoph Hellwig struct xfs_name name; 141c59d87c4SChristoph Hellwig int error; 142c59d87c4SChristoph Hellwig 143c59d87c4SChristoph Hellwig /* 144c59d87c4SChristoph Hellwig * Irix uses Missed'em'V split, but doesn't want to see 145c59d87c4SChristoph Hellwig * the upper 5 bits of (14bit) major. 146c59d87c4SChristoph Hellwig */ 147c59d87c4SChristoph Hellwig if (S_ISCHR(mode) || S_ISBLK(mode)) { 148c59d87c4SChristoph Hellwig if (unlikely(!sysv_valid_dev(rdev) || MAJOR(rdev) & ~0x1ff)) 149c59d87c4SChristoph Hellwig return -EINVAL; 150c59d87c4SChristoph Hellwig rdev = sysv_encode_dev(rdev); 151c59d87c4SChristoph Hellwig } else { 152c59d87c4SChristoph Hellwig rdev = 0; 153c59d87c4SChristoph Hellwig } 154c59d87c4SChristoph Hellwig 1552401dc29SChristoph Hellwig error = posix_acl_create(dir, &mode, &default_acl, &acl); 1562401dc29SChristoph Hellwig if (error) 1572401dc29SChristoph Hellwig return error; 158c59d87c4SChristoph Hellwig 159*d540e43bSBrian Foster if (!tmpfile) { 1600cb97766SDave Chinner xfs_dentry_to_name(&name, dentry, mode); 161c59d87c4SChristoph Hellwig error = xfs_create(XFS_I(dir), &name, mode, rdev, &ip); 162*d540e43bSBrian Foster } else { 163*d540e43bSBrian Foster error = xfs_create_tmpfile(XFS_I(dir), dentry, mode, &ip); 164*d540e43bSBrian Foster } 165c59d87c4SChristoph Hellwig if (unlikely(error)) 166c59d87c4SChristoph Hellwig goto out_free_acl; 167c59d87c4SChristoph Hellwig 168c59d87c4SChristoph Hellwig inode = VFS_I(ip); 169c59d87c4SChristoph Hellwig 170c59d87c4SChristoph Hellwig error = xfs_init_security(inode, dir, &dentry->d_name); 171c59d87c4SChristoph Hellwig if (unlikely(error)) 172c59d87c4SChristoph Hellwig goto out_cleanup_inode; 173c59d87c4SChristoph Hellwig 1742401dc29SChristoph Hellwig #ifdef CONFIG_XFS_POSIX_ACL 175c59d87c4SChristoph Hellwig if (default_acl) { 1762401dc29SChristoph Hellwig error = xfs_set_acl(inode, default_acl, ACL_TYPE_DEFAULT); 1772401dc29SChristoph Hellwig if (error) 178c59d87c4SChristoph Hellwig goto out_cleanup_inode; 179c59d87c4SChristoph Hellwig } 1802401dc29SChristoph Hellwig if (acl) { 1812401dc29SChristoph Hellwig error = xfs_set_acl(inode, acl, ACL_TYPE_ACCESS); 1822401dc29SChristoph Hellwig if (error) 1832401dc29SChristoph Hellwig goto out_cleanup_inode; 1842401dc29SChristoph Hellwig } 1852401dc29SChristoph Hellwig #endif 186c59d87c4SChristoph Hellwig 187*d540e43bSBrian Foster if (tmpfile) 188*d540e43bSBrian Foster d_tmpfile(dentry, inode); 189*d540e43bSBrian Foster else 190c59d87c4SChristoph Hellwig d_instantiate(dentry, inode); 191*d540e43bSBrian Foster 1922401dc29SChristoph Hellwig out_free_acl: 1932401dc29SChristoph Hellwig if (default_acl) 1942401dc29SChristoph Hellwig posix_acl_release(default_acl); 1952401dc29SChristoph Hellwig if (acl) 1962401dc29SChristoph Hellwig posix_acl_release(acl); 197c59d87c4SChristoph Hellwig return -error; 198c59d87c4SChristoph Hellwig 199c59d87c4SChristoph Hellwig out_cleanup_inode: 200*d540e43bSBrian Foster if (!tmpfile) 201c59d87c4SChristoph Hellwig xfs_cleanup_inode(dir, inode, dentry); 202*d540e43bSBrian Foster iput(inode); 2032401dc29SChristoph Hellwig goto out_free_acl; 204c59d87c4SChristoph Hellwig } 205c59d87c4SChristoph Hellwig 206c59d87c4SChristoph Hellwig STATIC int 207*d540e43bSBrian Foster xfs_vn_mknod( 208*d540e43bSBrian Foster struct inode *dir, 209*d540e43bSBrian Foster struct dentry *dentry, 210*d540e43bSBrian Foster umode_t mode, 211*d540e43bSBrian Foster dev_t rdev) 212*d540e43bSBrian Foster { 213*d540e43bSBrian Foster return xfs_generic_create(dir, dentry, mode, rdev, false); 214*d540e43bSBrian Foster } 215*d540e43bSBrian Foster 216*d540e43bSBrian Foster STATIC int 217c59d87c4SChristoph Hellwig xfs_vn_create( 218c59d87c4SChristoph Hellwig struct inode *dir, 219c59d87c4SChristoph Hellwig struct dentry *dentry, 2204acdaf27SAl Viro umode_t mode, 221ebfc3b49SAl Viro bool flags) 222c59d87c4SChristoph Hellwig { 223c59d87c4SChristoph Hellwig return xfs_vn_mknod(dir, dentry, mode, 0); 224c59d87c4SChristoph Hellwig } 225c59d87c4SChristoph Hellwig 226c59d87c4SChristoph Hellwig STATIC int 227c59d87c4SChristoph Hellwig xfs_vn_mkdir( 228c59d87c4SChristoph Hellwig struct inode *dir, 229c59d87c4SChristoph Hellwig struct dentry *dentry, 23018bb1db3SAl Viro umode_t mode) 231c59d87c4SChristoph Hellwig { 232c59d87c4SChristoph Hellwig return xfs_vn_mknod(dir, dentry, mode|S_IFDIR, 0); 233c59d87c4SChristoph Hellwig } 234c59d87c4SChristoph Hellwig 235c59d87c4SChristoph Hellwig STATIC struct dentry * 236c59d87c4SChristoph Hellwig xfs_vn_lookup( 237c59d87c4SChristoph Hellwig struct inode *dir, 238c59d87c4SChristoph Hellwig struct dentry *dentry, 23900cd8dd3SAl Viro unsigned int flags) 240c59d87c4SChristoph Hellwig { 241c59d87c4SChristoph Hellwig struct xfs_inode *cip; 242c59d87c4SChristoph Hellwig struct xfs_name name; 243c59d87c4SChristoph Hellwig int error; 244c59d87c4SChristoph Hellwig 245c59d87c4SChristoph Hellwig if (dentry->d_name.len >= MAXNAMELEN) 246c59d87c4SChristoph Hellwig return ERR_PTR(-ENAMETOOLONG); 247c59d87c4SChristoph Hellwig 2480cb97766SDave Chinner xfs_dentry_to_name(&name, dentry, 0); 249c59d87c4SChristoph Hellwig error = xfs_lookup(XFS_I(dir), &name, &cip, NULL); 250c59d87c4SChristoph Hellwig if (unlikely(error)) { 251c59d87c4SChristoph Hellwig if (unlikely(error != ENOENT)) 252c59d87c4SChristoph Hellwig return ERR_PTR(-error); 253c59d87c4SChristoph Hellwig d_add(dentry, NULL); 254c59d87c4SChristoph Hellwig return NULL; 255c59d87c4SChristoph Hellwig } 256c59d87c4SChristoph Hellwig 257c59d87c4SChristoph Hellwig return d_splice_alias(VFS_I(cip), dentry); 258c59d87c4SChristoph Hellwig } 259c59d87c4SChristoph Hellwig 260c59d87c4SChristoph Hellwig STATIC struct dentry * 261c59d87c4SChristoph Hellwig xfs_vn_ci_lookup( 262c59d87c4SChristoph Hellwig struct inode *dir, 263c59d87c4SChristoph Hellwig struct dentry *dentry, 26400cd8dd3SAl Viro unsigned int flags) 265c59d87c4SChristoph Hellwig { 266c59d87c4SChristoph Hellwig struct xfs_inode *ip; 267c59d87c4SChristoph Hellwig struct xfs_name xname; 268c59d87c4SChristoph Hellwig struct xfs_name ci_name; 269c59d87c4SChristoph Hellwig struct qstr dname; 270c59d87c4SChristoph Hellwig int error; 271c59d87c4SChristoph Hellwig 272c59d87c4SChristoph Hellwig if (dentry->d_name.len >= MAXNAMELEN) 273c59d87c4SChristoph Hellwig return ERR_PTR(-ENAMETOOLONG); 274c59d87c4SChristoph Hellwig 2750cb97766SDave Chinner xfs_dentry_to_name(&xname, dentry, 0); 276c59d87c4SChristoph Hellwig error = xfs_lookup(XFS_I(dir), &xname, &ip, &ci_name); 277c59d87c4SChristoph Hellwig if (unlikely(error)) { 278c59d87c4SChristoph Hellwig if (unlikely(error != ENOENT)) 279c59d87c4SChristoph Hellwig return ERR_PTR(-error); 280c59d87c4SChristoph Hellwig /* 281c59d87c4SChristoph Hellwig * call d_add(dentry, NULL) here when d_drop_negative_children 282c59d87c4SChristoph Hellwig * is called in xfs_vn_mknod (ie. allow negative dentries 283c59d87c4SChristoph Hellwig * with CI filesystems). 284c59d87c4SChristoph Hellwig */ 285c59d87c4SChristoph Hellwig return NULL; 286c59d87c4SChristoph Hellwig } 287c59d87c4SChristoph Hellwig 288c59d87c4SChristoph Hellwig /* if exact match, just splice and exit */ 289c59d87c4SChristoph Hellwig if (!ci_name.name) 290c59d87c4SChristoph Hellwig return d_splice_alias(VFS_I(ip), dentry); 291c59d87c4SChristoph Hellwig 292c59d87c4SChristoph Hellwig /* else case-insensitive match... */ 293c59d87c4SChristoph Hellwig dname.name = ci_name.name; 294c59d87c4SChristoph Hellwig dname.len = ci_name.len; 295c59d87c4SChristoph Hellwig dentry = d_add_ci(dentry, VFS_I(ip), &dname); 296c59d87c4SChristoph Hellwig kmem_free(ci_name.name); 297c59d87c4SChristoph Hellwig return dentry; 298c59d87c4SChristoph Hellwig } 299c59d87c4SChristoph Hellwig 300c59d87c4SChristoph Hellwig STATIC int 301c59d87c4SChristoph Hellwig xfs_vn_link( 302c59d87c4SChristoph Hellwig struct dentry *old_dentry, 303c59d87c4SChristoph Hellwig struct inode *dir, 304c59d87c4SChristoph Hellwig struct dentry *dentry) 305c59d87c4SChristoph Hellwig { 306c59d87c4SChristoph Hellwig struct inode *inode = old_dentry->d_inode; 307c59d87c4SChristoph Hellwig struct xfs_name name; 308c59d87c4SChristoph Hellwig int error; 309c59d87c4SChristoph Hellwig 3100cb97766SDave Chinner xfs_dentry_to_name(&name, dentry, inode->i_mode); 311c59d87c4SChristoph Hellwig 312c59d87c4SChristoph Hellwig error = xfs_link(XFS_I(dir), XFS_I(inode), &name); 313c59d87c4SChristoph Hellwig if (unlikely(error)) 314c59d87c4SChristoph Hellwig return -error; 315c59d87c4SChristoph Hellwig 316c59d87c4SChristoph Hellwig ihold(inode); 317c59d87c4SChristoph Hellwig d_instantiate(dentry, inode); 318c59d87c4SChristoph Hellwig return 0; 319c59d87c4SChristoph Hellwig } 320c59d87c4SChristoph Hellwig 321c59d87c4SChristoph Hellwig STATIC int 322c59d87c4SChristoph Hellwig xfs_vn_unlink( 323c59d87c4SChristoph Hellwig struct inode *dir, 324c59d87c4SChristoph Hellwig struct dentry *dentry) 325c59d87c4SChristoph Hellwig { 326c59d87c4SChristoph Hellwig struct xfs_name name; 327c59d87c4SChristoph Hellwig int error; 328c59d87c4SChristoph Hellwig 3290cb97766SDave Chinner xfs_dentry_to_name(&name, dentry, 0); 330c59d87c4SChristoph Hellwig 331c59d87c4SChristoph Hellwig error = -xfs_remove(XFS_I(dir), &name, XFS_I(dentry->d_inode)); 332c59d87c4SChristoph Hellwig if (error) 333c59d87c4SChristoph Hellwig return error; 334c59d87c4SChristoph Hellwig 335c59d87c4SChristoph Hellwig /* 336c59d87c4SChristoph Hellwig * With unlink, the VFS makes the dentry "negative": no inode, 337c59d87c4SChristoph Hellwig * but still hashed. This is incompatible with case-insensitive 338c59d87c4SChristoph Hellwig * mode, so invalidate (unhash) the dentry in CI-mode. 339c59d87c4SChristoph Hellwig */ 340c59d87c4SChristoph Hellwig if (xfs_sb_version_hasasciici(&XFS_M(dir->i_sb)->m_sb)) 341c59d87c4SChristoph Hellwig d_invalidate(dentry); 342c59d87c4SChristoph Hellwig return 0; 343c59d87c4SChristoph Hellwig } 344c59d87c4SChristoph Hellwig 345c59d87c4SChristoph Hellwig STATIC int 346c59d87c4SChristoph Hellwig xfs_vn_symlink( 347c59d87c4SChristoph Hellwig struct inode *dir, 348c59d87c4SChristoph Hellwig struct dentry *dentry, 349c59d87c4SChristoph Hellwig const char *symname) 350c59d87c4SChristoph Hellwig { 351c59d87c4SChristoph Hellwig struct inode *inode; 352c59d87c4SChristoph Hellwig struct xfs_inode *cip = NULL; 353c59d87c4SChristoph Hellwig struct xfs_name name; 354c59d87c4SChristoph Hellwig int error; 355576b1d67SAl Viro umode_t mode; 356c59d87c4SChristoph Hellwig 357c59d87c4SChristoph Hellwig mode = S_IFLNK | 358c59d87c4SChristoph Hellwig (irix_symlink_mode ? 0777 & ~current_umask() : S_IRWXUGO); 3590cb97766SDave Chinner xfs_dentry_to_name(&name, dentry, mode); 360c59d87c4SChristoph Hellwig 361c59d87c4SChristoph Hellwig error = xfs_symlink(XFS_I(dir), &name, symname, mode, &cip); 362c59d87c4SChristoph Hellwig if (unlikely(error)) 363c59d87c4SChristoph Hellwig goto out; 364c59d87c4SChristoph Hellwig 365c59d87c4SChristoph Hellwig inode = VFS_I(cip); 366c59d87c4SChristoph Hellwig 367c59d87c4SChristoph Hellwig error = xfs_init_security(inode, dir, &dentry->d_name); 368c59d87c4SChristoph Hellwig if (unlikely(error)) 369c59d87c4SChristoph Hellwig goto out_cleanup_inode; 370c59d87c4SChristoph Hellwig 371c59d87c4SChristoph Hellwig d_instantiate(dentry, inode); 372c59d87c4SChristoph Hellwig return 0; 373c59d87c4SChristoph Hellwig 374c59d87c4SChristoph Hellwig out_cleanup_inode: 375c59d87c4SChristoph Hellwig xfs_cleanup_inode(dir, inode, dentry); 376*d540e43bSBrian Foster iput(inode); 377c59d87c4SChristoph Hellwig out: 378c59d87c4SChristoph Hellwig return -error; 379c59d87c4SChristoph Hellwig } 380c59d87c4SChristoph Hellwig 381c59d87c4SChristoph Hellwig STATIC int 382c59d87c4SChristoph Hellwig xfs_vn_rename( 383c59d87c4SChristoph Hellwig struct inode *odir, 384c59d87c4SChristoph Hellwig struct dentry *odentry, 385c59d87c4SChristoph Hellwig struct inode *ndir, 386c59d87c4SChristoph Hellwig struct dentry *ndentry) 387c59d87c4SChristoph Hellwig { 388c59d87c4SChristoph Hellwig struct inode *new_inode = ndentry->d_inode; 389c59d87c4SChristoph Hellwig struct xfs_name oname; 390c59d87c4SChristoph Hellwig struct xfs_name nname; 391c59d87c4SChristoph Hellwig 3920cb97766SDave Chinner xfs_dentry_to_name(&oname, odentry, 0); 3930cb97766SDave Chinner xfs_dentry_to_name(&nname, ndentry, odentry->d_inode->i_mode); 394c59d87c4SChristoph Hellwig 395c59d87c4SChristoph Hellwig return -xfs_rename(XFS_I(odir), &oname, XFS_I(odentry->d_inode), 396c59d87c4SChristoph Hellwig XFS_I(ndir), &nname, new_inode ? 397c59d87c4SChristoph Hellwig XFS_I(new_inode) : NULL); 398c59d87c4SChristoph Hellwig } 399c59d87c4SChristoph Hellwig 400c59d87c4SChristoph Hellwig /* 401c59d87c4SChristoph Hellwig * careful here - this function can get called recursively, so 402c59d87c4SChristoph Hellwig * we need to be very careful about how much stack we use. 403c59d87c4SChristoph Hellwig * uio is kmalloced for this reason... 404c59d87c4SChristoph Hellwig */ 405c59d87c4SChristoph Hellwig STATIC void * 406c59d87c4SChristoph Hellwig xfs_vn_follow_link( 407c59d87c4SChristoph Hellwig struct dentry *dentry, 408c59d87c4SChristoph Hellwig struct nameidata *nd) 409c59d87c4SChristoph Hellwig { 410c59d87c4SChristoph Hellwig char *link; 411c59d87c4SChristoph Hellwig int error = -ENOMEM; 412c59d87c4SChristoph Hellwig 413c59d87c4SChristoph Hellwig link = kmalloc(MAXPATHLEN+1, GFP_KERNEL); 414c59d87c4SChristoph Hellwig if (!link) 415c59d87c4SChristoph Hellwig goto out_err; 416c59d87c4SChristoph Hellwig 417c59d87c4SChristoph Hellwig error = -xfs_readlink(XFS_I(dentry->d_inode), link); 418c59d87c4SChristoph Hellwig if (unlikely(error)) 419c59d87c4SChristoph Hellwig goto out_kfree; 420c59d87c4SChristoph Hellwig 421c59d87c4SChristoph Hellwig nd_set_link(nd, link); 422c59d87c4SChristoph Hellwig return NULL; 423c59d87c4SChristoph Hellwig 424c59d87c4SChristoph Hellwig out_kfree: 425c59d87c4SChristoph Hellwig kfree(link); 426c59d87c4SChristoph Hellwig out_err: 427c59d87c4SChristoph Hellwig nd_set_link(nd, ERR_PTR(error)); 428c59d87c4SChristoph Hellwig return NULL; 429c59d87c4SChristoph Hellwig } 430c59d87c4SChristoph Hellwig 431c59d87c4SChristoph Hellwig STATIC int 432c59d87c4SChristoph Hellwig xfs_vn_getattr( 433c59d87c4SChristoph Hellwig struct vfsmount *mnt, 434c59d87c4SChristoph Hellwig struct dentry *dentry, 435c59d87c4SChristoph Hellwig struct kstat *stat) 436c59d87c4SChristoph Hellwig { 437c59d87c4SChristoph Hellwig struct inode *inode = dentry->d_inode; 438c59d87c4SChristoph Hellwig struct xfs_inode *ip = XFS_I(inode); 439c59d87c4SChristoph Hellwig struct xfs_mount *mp = ip->i_mount; 440c59d87c4SChristoph Hellwig 441c59d87c4SChristoph Hellwig trace_xfs_getattr(ip); 442c59d87c4SChristoph Hellwig 443c59d87c4SChristoph Hellwig if (XFS_FORCED_SHUTDOWN(mp)) 444ed32201eSMitsuo Hayasaka return -XFS_ERROR(EIO); 445c59d87c4SChristoph Hellwig 446c59d87c4SChristoph Hellwig stat->size = XFS_ISIZE(ip); 447c59d87c4SChristoph Hellwig stat->dev = inode->i_sb->s_dev; 448c59d87c4SChristoph Hellwig stat->mode = ip->i_d.di_mode; 449c59d87c4SChristoph Hellwig stat->nlink = ip->i_d.di_nlink; 4507aab1b28SDwight Engen stat->uid = inode->i_uid; 4517aab1b28SDwight Engen stat->gid = inode->i_gid; 452c59d87c4SChristoph Hellwig stat->ino = ip->i_ino; 453c59d87c4SChristoph Hellwig stat->atime = inode->i_atime; 454c59d87c4SChristoph Hellwig stat->mtime = inode->i_mtime; 455c59d87c4SChristoph Hellwig stat->ctime = inode->i_ctime; 456c59d87c4SChristoph Hellwig stat->blocks = 457c59d87c4SChristoph Hellwig XFS_FSB_TO_BB(mp, ip->i_d.di_nblocks + ip->i_delayed_blks); 458c59d87c4SChristoph Hellwig 459c59d87c4SChristoph Hellwig 460c59d87c4SChristoph Hellwig switch (inode->i_mode & S_IFMT) { 461c59d87c4SChristoph Hellwig case S_IFBLK: 462c59d87c4SChristoph Hellwig case S_IFCHR: 463c59d87c4SChristoph Hellwig stat->blksize = BLKDEV_IOSIZE; 464c59d87c4SChristoph Hellwig stat->rdev = MKDEV(sysv_major(ip->i_df.if_u2.if_rdev) & 0x1ff, 465c59d87c4SChristoph Hellwig sysv_minor(ip->i_df.if_u2.if_rdev)); 466c59d87c4SChristoph Hellwig break; 467c59d87c4SChristoph Hellwig default: 468c59d87c4SChristoph Hellwig if (XFS_IS_REALTIME_INODE(ip)) { 469c59d87c4SChristoph Hellwig /* 470c59d87c4SChristoph Hellwig * If the file blocks are being allocated from a 471c59d87c4SChristoph Hellwig * realtime volume, then return the inode's realtime 472c59d87c4SChristoph Hellwig * extent size or the realtime volume's extent size. 473c59d87c4SChristoph Hellwig */ 474c59d87c4SChristoph Hellwig stat->blksize = 475c59d87c4SChristoph Hellwig xfs_get_extsz_hint(ip) << mp->m_sb.sb_blocklog; 476c59d87c4SChristoph Hellwig } else 477c59d87c4SChristoph Hellwig stat->blksize = xfs_preferred_iosize(mp); 478c59d87c4SChristoph Hellwig stat->rdev = 0; 479c59d87c4SChristoph Hellwig break; 480c59d87c4SChristoph Hellwig } 481c59d87c4SChristoph Hellwig 482c59d87c4SChristoph Hellwig return 0; 483c59d87c4SChristoph Hellwig } 484c59d87c4SChristoph Hellwig 48556c19e89SDave Chinner static void 48656c19e89SDave Chinner xfs_setattr_mode( 48756c19e89SDave Chinner struct xfs_inode *ip, 48856c19e89SDave Chinner struct iattr *iattr) 48956c19e89SDave Chinner { 49056c19e89SDave Chinner struct inode *inode = VFS_I(ip); 49156c19e89SDave Chinner umode_t mode = iattr->ia_mode; 49256c19e89SDave Chinner 49356c19e89SDave Chinner ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); 49456c19e89SDave Chinner 49556c19e89SDave Chinner ip->i_d.di_mode &= S_IFMT; 49656c19e89SDave Chinner ip->i_d.di_mode |= mode & ~S_IFMT; 49756c19e89SDave Chinner 49856c19e89SDave Chinner inode->i_mode &= S_IFMT; 49956c19e89SDave Chinner inode->i_mode |= mode & ~S_IFMT; 50056c19e89SDave Chinner } 50156c19e89SDave Chinner 502c91c46c1SChristoph Hellwig static void 503c91c46c1SChristoph Hellwig xfs_setattr_time( 504c91c46c1SChristoph Hellwig struct xfs_inode *ip, 505c91c46c1SChristoph Hellwig struct iattr *iattr) 506c91c46c1SChristoph Hellwig { 507c91c46c1SChristoph Hellwig struct inode *inode = VFS_I(ip); 508c91c46c1SChristoph Hellwig 509c91c46c1SChristoph Hellwig ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); 510c91c46c1SChristoph Hellwig 511c91c46c1SChristoph Hellwig if (iattr->ia_valid & ATTR_ATIME) { 512c91c46c1SChristoph Hellwig inode->i_atime = iattr->ia_atime; 513c91c46c1SChristoph Hellwig ip->i_d.di_atime.t_sec = iattr->ia_atime.tv_sec; 514c91c46c1SChristoph Hellwig ip->i_d.di_atime.t_nsec = iattr->ia_atime.tv_nsec; 515c91c46c1SChristoph Hellwig } 516c91c46c1SChristoph Hellwig if (iattr->ia_valid & ATTR_CTIME) { 517c91c46c1SChristoph Hellwig inode->i_ctime = iattr->ia_ctime; 518c91c46c1SChristoph Hellwig ip->i_d.di_ctime.t_sec = iattr->ia_ctime.tv_sec; 519c91c46c1SChristoph Hellwig ip->i_d.di_ctime.t_nsec = iattr->ia_ctime.tv_nsec; 520c91c46c1SChristoph Hellwig } 521c91c46c1SChristoph Hellwig if (iattr->ia_valid & ATTR_MTIME) { 522c91c46c1SChristoph Hellwig inode->i_mtime = iattr->ia_mtime; 523c91c46c1SChristoph Hellwig ip->i_d.di_mtime.t_sec = iattr->ia_mtime.tv_sec; 524c91c46c1SChristoph Hellwig ip->i_d.di_mtime.t_nsec = iattr->ia_mtime.tv_nsec; 525c91c46c1SChristoph Hellwig } 526c91c46c1SChristoph Hellwig } 527c91c46c1SChristoph Hellwig 528c59d87c4SChristoph Hellwig int 529c59d87c4SChristoph Hellwig xfs_setattr_nonsize( 530c59d87c4SChristoph Hellwig struct xfs_inode *ip, 531c59d87c4SChristoph Hellwig struct iattr *iattr, 532c59d87c4SChristoph Hellwig int flags) 533c59d87c4SChristoph Hellwig { 534c59d87c4SChristoph Hellwig xfs_mount_t *mp = ip->i_mount; 535c59d87c4SChristoph Hellwig struct inode *inode = VFS_I(ip); 536c59d87c4SChristoph Hellwig int mask = iattr->ia_valid; 537c59d87c4SChristoph Hellwig xfs_trans_t *tp; 538c59d87c4SChristoph Hellwig int error; 5397aab1b28SDwight Engen kuid_t uid = GLOBAL_ROOT_UID, iuid = GLOBAL_ROOT_UID; 5407aab1b28SDwight Engen kgid_t gid = GLOBAL_ROOT_GID, igid = GLOBAL_ROOT_GID; 541c59d87c4SChristoph Hellwig struct xfs_dquot *udqp = NULL, *gdqp = NULL; 542c59d87c4SChristoph Hellwig struct xfs_dquot *olddquot1 = NULL, *olddquot2 = NULL; 543c59d87c4SChristoph Hellwig 544c59d87c4SChristoph Hellwig trace_xfs_setattr(ip); 545c59d87c4SChristoph Hellwig 54642c49d7fSCarlos Maiolino /* If acls are being inherited, we already have this checked */ 54742c49d7fSCarlos Maiolino if (!(flags & XFS_ATTR_NOACL)) { 548c59d87c4SChristoph Hellwig if (mp->m_flags & XFS_MOUNT_RDONLY) 549c59d87c4SChristoph Hellwig return XFS_ERROR(EROFS); 550c59d87c4SChristoph Hellwig 551c59d87c4SChristoph Hellwig if (XFS_FORCED_SHUTDOWN(mp)) 552c59d87c4SChristoph Hellwig return XFS_ERROR(EIO); 553c59d87c4SChristoph Hellwig 554c59d87c4SChristoph Hellwig error = -inode_change_ok(inode, iattr); 555c59d87c4SChristoph Hellwig if (error) 556c59d87c4SChristoph Hellwig return XFS_ERROR(error); 55742c49d7fSCarlos Maiolino } 558c59d87c4SChristoph Hellwig 559c59d87c4SChristoph Hellwig ASSERT((mask & ATTR_SIZE) == 0); 560c59d87c4SChristoph Hellwig 561c59d87c4SChristoph Hellwig /* 562c59d87c4SChristoph Hellwig * If disk quotas is on, we make sure that the dquots do exist on disk, 563c59d87c4SChristoph Hellwig * before we start any other transactions. Trying to do this later 564c59d87c4SChristoph Hellwig * is messy. We don't care to take a readlock to look at the ids 565c59d87c4SChristoph Hellwig * in inode here, because we can't hold it across the trans_reserve. 566c59d87c4SChristoph Hellwig * If the IDs do change before we take the ilock, we're covered 567c59d87c4SChristoph Hellwig * because the i_*dquot fields will get updated anyway. 568c59d87c4SChristoph Hellwig */ 569c59d87c4SChristoph Hellwig if (XFS_IS_QUOTA_ON(mp) && (mask & (ATTR_UID|ATTR_GID))) { 570c59d87c4SChristoph Hellwig uint qflags = 0; 571c59d87c4SChristoph Hellwig 572c59d87c4SChristoph Hellwig if ((mask & ATTR_UID) && XFS_IS_UQUOTA_ON(mp)) { 573c59d87c4SChristoph Hellwig uid = iattr->ia_uid; 574c59d87c4SChristoph Hellwig qflags |= XFS_QMOPT_UQUOTA; 575c59d87c4SChristoph Hellwig } else { 5767aab1b28SDwight Engen uid = inode->i_uid; 577c59d87c4SChristoph Hellwig } 578c59d87c4SChristoph Hellwig if ((mask & ATTR_GID) && XFS_IS_GQUOTA_ON(mp)) { 579c59d87c4SChristoph Hellwig gid = iattr->ia_gid; 580c59d87c4SChristoph Hellwig qflags |= XFS_QMOPT_GQUOTA; 581c59d87c4SChristoph Hellwig } else { 5827aab1b28SDwight Engen gid = inode->i_gid; 583c59d87c4SChristoph Hellwig } 584c59d87c4SChristoph Hellwig 585c59d87c4SChristoph Hellwig /* 586c59d87c4SChristoph Hellwig * We take a reference when we initialize udqp and gdqp, 587c59d87c4SChristoph Hellwig * so it is important that we never blindly double trip on 588c59d87c4SChristoph Hellwig * the same variable. See xfs_create() for an example. 589c59d87c4SChristoph Hellwig */ 590c59d87c4SChristoph Hellwig ASSERT(udqp == NULL); 591c59d87c4SChristoph Hellwig ASSERT(gdqp == NULL); 5927aab1b28SDwight Engen error = xfs_qm_vop_dqalloc(ip, xfs_kuid_to_uid(uid), 5937aab1b28SDwight Engen xfs_kgid_to_gid(gid), 5947aab1b28SDwight Engen xfs_get_projid(ip), 59592f8ff73SChandra Seetharaman qflags, &udqp, &gdqp, NULL); 596c59d87c4SChristoph Hellwig if (error) 597c59d87c4SChristoph Hellwig return error; 598c59d87c4SChristoph Hellwig } 599c59d87c4SChristoph Hellwig 600c59d87c4SChristoph Hellwig tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_NOT_SIZE); 6013d3c8b52SJie Liu error = xfs_trans_reserve(tp, &M_RES(mp)->tr_ichange, 0, 0); 602c59d87c4SChristoph Hellwig if (error) 603c59d87c4SChristoph Hellwig goto out_dqrele; 604c59d87c4SChristoph Hellwig 605c59d87c4SChristoph Hellwig xfs_ilock(ip, XFS_ILOCK_EXCL); 606c59d87c4SChristoph Hellwig 607c59d87c4SChristoph Hellwig /* 608c59d87c4SChristoph Hellwig * Change file ownership. Must be the owner or privileged. 609c59d87c4SChristoph Hellwig */ 610c59d87c4SChristoph Hellwig if (mask & (ATTR_UID|ATTR_GID)) { 611c59d87c4SChristoph Hellwig /* 612c59d87c4SChristoph Hellwig * These IDs could have changed since we last looked at them. 613c59d87c4SChristoph Hellwig * But, we're assured that if the ownership did change 614c59d87c4SChristoph Hellwig * while we didn't have the inode locked, inode's dquot(s) 615c59d87c4SChristoph Hellwig * would have changed also. 616c59d87c4SChristoph Hellwig */ 6177aab1b28SDwight Engen iuid = inode->i_uid; 6187aab1b28SDwight Engen igid = inode->i_gid; 619c59d87c4SChristoph Hellwig gid = (mask & ATTR_GID) ? iattr->ia_gid : igid; 620c59d87c4SChristoph Hellwig uid = (mask & ATTR_UID) ? iattr->ia_uid : iuid; 621c59d87c4SChristoph Hellwig 622c59d87c4SChristoph Hellwig /* 623c59d87c4SChristoph Hellwig * Do a quota reservation only if uid/gid is actually 624c59d87c4SChristoph Hellwig * going to change. 625c59d87c4SChristoph Hellwig */ 626c59d87c4SChristoph Hellwig if (XFS_IS_QUOTA_RUNNING(mp) && 6277aab1b28SDwight Engen ((XFS_IS_UQUOTA_ON(mp) && !uid_eq(iuid, uid)) || 6287aab1b28SDwight Engen (XFS_IS_GQUOTA_ON(mp) && !gid_eq(igid, gid)))) { 629c59d87c4SChristoph Hellwig ASSERT(tp); 630c59d87c4SChristoph Hellwig error = xfs_qm_vop_chown_reserve(tp, ip, udqp, gdqp, 63192f8ff73SChandra Seetharaman NULL, capable(CAP_FOWNER) ? 632c59d87c4SChristoph Hellwig XFS_QMOPT_FORCE_RES : 0); 633c59d87c4SChristoph Hellwig if (error) /* out of quota */ 634c59d87c4SChristoph Hellwig goto out_trans_cancel; 635c59d87c4SChristoph Hellwig } 636c59d87c4SChristoph Hellwig } 637c59d87c4SChristoph Hellwig 638ddc3415aSChristoph Hellwig xfs_trans_ijoin(tp, ip, 0); 639c59d87c4SChristoph Hellwig 640c59d87c4SChristoph Hellwig /* 641c59d87c4SChristoph Hellwig * Change file ownership. Must be the owner or privileged. 642c59d87c4SChristoph Hellwig */ 643c59d87c4SChristoph Hellwig if (mask & (ATTR_UID|ATTR_GID)) { 644c59d87c4SChristoph Hellwig /* 645c59d87c4SChristoph Hellwig * CAP_FSETID overrides the following restrictions: 646c59d87c4SChristoph Hellwig * 647c59d87c4SChristoph Hellwig * The set-user-ID and set-group-ID bits of a file will be 648c59d87c4SChristoph Hellwig * cleared upon successful return from chown() 649c59d87c4SChristoph Hellwig */ 650c59d87c4SChristoph Hellwig if ((ip->i_d.di_mode & (S_ISUID|S_ISGID)) && 651c59d87c4SChristoph Hellwig !capable(CAP_FSETID)) 652c59d87c4SChristoph Hellwig ip->i_d.di_mode &= ~(S_ISUID|S_ISGID); 653c59d87c4SChristoph Hellwig 654c59d87c4SChristoph Hellwig /* 655c59d87c4SChristoph Hellwig * Change the ownerships and register quota modifications 656c59d87c4SChristoph Hellwig * in the transaction. 657c59d87c4SChristoph Hellwig */ 6587aab1b28SDwight Engen if (!uid_eq(iuid, uid)) { 659c59d87c4SChristoph Hellwig if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_UQUOTA_ON(mp)) { 660c59d87c4SChristoph Hellwig ASSERT(mask & ATTR_UID); 661c59d87c4SChristoph Hellwig ASSERT(udqp); 662c59d87c4SChristoph Hellwig olddquot1 = xfs_qm_vop_chown(tp, ip, 663c59d87c4SChristoph Hellwig &ip->i_udquot, udqp); 664c59d87c4SChristoph Hellwig } 6657aab1b28SDwight Engen ip->i_d.di_uid = xfs_kuid_to_uid(uid); 666c59d87c4SChristoph Hellwig inode->i_uid = uid; 667c59d87c4SChristoph Hellwig } 6687aab1b28SDwight Engen if (!gid_eq(igid, gid)) { 669c59d87c4SChristoph Hellwig if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_GQUOTA_ON(mp)) { 6705a01dd54SJie Liu ASSERT(xfs_sb_version_has_pquotino(&mp->m_sb) || 6715a01dd54SJie Liu !XFS_IS_PQUOTA_ON(mp)); 672c59d87c4SChristoph Hellwig ASSERT(mask & ATTR_GID); 673c59d87c4SChristoph Hellwig ASSERT(gdqp); 674c59d87c4SChristoph Hellwig olddquot2 = xfs_qm_vop_chown(tp, ip, 675c59d87c4SChristoph Hellwig &ip->i_gdquot, gdqp); 676c59d87c4SChristoph Hellwig } 6777aab1b28SDwight Engen ip->i_d.di_gid = xfs_kgid_to_gid(gid); 678c59d87c4SChristoph Hellwig inode->i_gid = gid; 679c59d87c4SChristoph Hellwig } 680c59d87c4SChristoph Hellwig } 681c59d87c4SChristoph Hellwig 68256c19e89SDave Chinner if (mask & ATTR_MODE) 6830c3d88dfSChristoph Hellwig xfs_setattr_mode(ip, iattr); 684c91c46c1SChristoph Hellwig if (mask & (ATTR_ATIME|ATTR_CTIME|ATTR_MTIME)) 685c91c46c1SChristoph Hellwig xfs_setattr_time(ip, iattr); 686c59d87c4SChristoph Hellwig 687c59d87c4SChristoph Hellwig xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 688c59d87c4SChristoph Hellwig 689c59d87c4SChristoph Hellwig XFS_STATS_INC(xs_ig_attrchg); 690c59d87c4SChristoph Hellwig 691c59d87c4SChristoph Hellwig if (mp->m_flags & XFS_MOUNT_WSYNC) 692c59d87c4SChristoph Hellwig xfs_trans_set_sync(tp); 693c59d87c4SChristoph Hellwig error = xfs_trans_commit(tp, 0); 694c59d87c4SChristoph Hellwig 695c59d87c4SChristoph Hellwig xfs_iunlock(ip, XFS_ILOCK_EXCL); 696c59d87c4SChristoph Hellwig 697c59d87c4SChristoph Hellwig /* 698c59d87c4SChristoph Hellwig * Release any dquot(s) the inode had kept before chown. 699c59d87c4SChristoph Hellwig */ 700c59d87c4SChristoph Hellwig xfs_qm_dqrele(olddquot1); 701c59d87c4SChristoph Hellwig xfs_qm_dqrele(olddquot2); 702c59d87c4SChristoph Hellwig xfs_qm_dqrele(udqp); 703c59d87c4SChristoph Hellwig xfs_qm_dqrele(gdqp); 704c59d87c4SChristoph Hellwig 705c59d87c4SChristoph Hellwig if (error) 706c59d87c4SChristoph Hellwig return XFS_ERROR(error); 707c59d87c4SChristoph Hellwig 708c59d87c4SChristoph Hellwig /* 709c59d87c4SChristoph Hellwig * XXX(hch): Updating the ACL entries is not atomic vs the i_mode 710c59d87c4SChristoph Hellwig * update. We could avoid this with linked transactions 711c59d87c4SChristoph Hellwig * and passing down the transaction pointer all the way 712c59d87c4SChristoph Hellwig * to attr_set. No previous user of the generic 713c59d87c4SChristoph Hellwig * Posix ACL code seems to care about this issue either. 714c59d87c4SChristoph Hellwig */ 715c59d87c4SChristoph Hellwig if ((mask & ATTR_MODE) && !(flags & XFS_ATTR_NOACL)) { 7162401dc29SChristoph Hellwig error = -posix_acl_chmod(inode, inode->i_mode); 717c59d87c4SChristoph Hellwig if (error) 718c59d87c4SChristoph Hellwig return XFS_ERROR(error); 719c59d87c4SChristoph Hellwig } 720c59d87c4SChristoph Hellwig 721c59d87c4SChristoph Hellwig return 0; 722c59d87c4SChristoph Hellwig 723c59d87c4SChristoph Hellwig out_trans_cancel: 724c59d87c4SChristoph Hellwig xfs_trans_cancel(tp, 0); 725c59d87c4SChristoph Hellwig xfs_iunlock(ip, XFS_ILOCK_EXCL); 726c59d87c4SChristoph Hellwig out_dqrele: 727c59d87c4SChristoph Hellwig xfs_qm_dqrele(udqp); 728c59d87c4SChristoph Hellwig xfs_qm_dqrele(gdqp); 729c59d87c4SChristoph Hellwig return error; 730c59d87c4SChristoph Hellwig } 731c59d87c4SChristoph Hellwig 732c59d87c4SChristoph Hellwig /* 733c59d87c4SChristoph Hellwig * Truncate file. Must have write permission and not be a directory. 734c59d87c4SChristoph Hellwig */ 735c59d87c4SChristoph Hellwig int 736c59d87c4SChristoph Hellwig xfs_setattr_size( 737c59d87c4SChristoph Hellwig struct xfs_inode *ip, 73876ca4c23SChristoph Hellwig struct iattr *iattr) 739c59d87c4SChristoph Hellwig { 740c59d87c4SChristoph Hellwig struct xfs_mount *mp = ip->i_mount; 741c59d87c4SChristoph Hellwig struct inode *inode = VFS_I(ip); 742673e8e59SChristoph Hellwig xfs_off_t oldsize, newsize; 743c59d87c4SChristoph Hellwig struct xfs_trans *tp; 744c59d87c4SChristoph Hellwig int error; 745f38996f5SChristoph Hellwig uint lock_flags = 0; 746c59d87c4SChristoph Hellwig uint commit_flags = 0; 747c59d87c4SChristoph Hellwig 748c59d87c4SChristoph Hellwig trace_xfs_setattr(ip); 749c59d87c4SChristoph Hellwig 750c59d87c4SChristoph Hellwig if (mp->m_flags & XFS_MOUNT_RDONLY) 751c59d87c4SChristoph Hellwig return XFS_ERROR(EROFS); 752c59d87c4SChristoph Hellwig 753c59d87c4SChristoph Hellwig if (XFS_FORCED_SHUTDOWN(mp)) 754c59d87c4SChristoph Hellwig return XFS_ERROR(EIO); 755c59d87c4SChristoph Hellwig 756c59d87c4SChristoph Hellwig error = -inode_change_ok(inode, iattr); 757c59d87c4SChristoph Hellwig if (error) 758c59d87c4SChristoph Hellwig return XFS_ERROR(error); 759c59d87c4SChristoph Hellwig 76076ca4c23SChristoph Hellwig ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL)); 761c59d87c4SChristoph Hellwig ASSERT(S_ISREG(ip->i_d.di_mode)); 762fe60a8a0SChristoph Hellwig ASSERT((iattr->ia_valid & (ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_ATIME_SET| 76356c19e89SDave Chinner ATTR_MTIME_SET|ATTR_KILL_PRIV|ATTR_TIMES_SET)) == 0); 764c59d87c4SChristoph Hellwig 765ce7ae151SChristoph Hellwig oldsize = inode->i_size; 766673e8e59SChristoph Hellwig newsize = iattr->ia_size; 767673e8e59SChristoph Hellwig 768c59d87c4SChristoph Hellwig /* 769c59d87c4SChristoph Hellwig * Short circuit the truncate case for zero length files. 770c59d87c4SChristoph Hellwig */ 771673e8e59SChristoph Hellwig if (newsize == 0 && oldsize == 0 && ip->i_d.di_nextents == 0) { 772fe60a8a0SChristoph Hellwig if (!(iattr->ia_valid & (ATTR_CTIME|ATTR_MTIME))) 77376ca4c23SChristoph Hellwig return 0; 774c59d87c4SChristoph Hellwig 775c59d87c4SChristoph Hellwig /* 776c59d87c4SChristoph Hellwig * Use the regular setattr path to update the timestamps. 777c59d87c4SChristoph Hellwig */ 778c59d87c4SChristoph Hellwig iattr->ia_valid &= ~ATTR_SIZE; 779c59d87c4SChristoph Hellwig return xfs_setattr_nonsize(ip, iattr, 0); 780c59d87c4SChristoph Hellwig } 781c59d87c4SChristoph Hellwig 782c59d87c4SChristoph Hellwig /* 783c59d87c4SChristoph Hellwig * Make sure that the dquots are attached to the inode. 784c59d87c4SChristoph Hellwig */ 785f38996f5SChristoph Hellwig error = xfs_qm_dqattach(ip, 0); 786c59d87c4SChristoph Hellwig if (error) 78776ca4c23SChristoph Hellwig return error; 788c59d87c4SChristoph Hellwig 789c59d87c4SChristoph Hellwig /* 790c59d87c4SChristoph Hellwig * Now we can make the changes. Before we join the inode to the 791c59d87c4SChristoph Hellwig * transaction, take care of the part of the truncation that must be 792c59d87c4SChristoph Hellwig * done without the inode lock. This needs to be done before joining 793c59d87c4SChristoph Hellwig * the inode to the transaction, because the inode cannot be unlocked 794c59d87c4SChristoph Hellwig * once it is a part of the transaction. 795c59d87c4SChristoph Hellwig */ 796673e8e59SChristoph Hellwig if (newsize > oldsize) { 797c59d87c4SChristoph Hellwig /* 798c59d87c4SChristoph Hellwig * Do the first part of growing a file: zero any data in the 799c59d87c4SChristoph Hellwig * last block that is beyond the old EOF. We need to do this 800c59d87c4SChristoph Hellwig * before the inode is joined to the transaction to modify 801c59d87c4SChristoph Hellwig * i_size. 802c59d87c4SChristoph Hellwig */ 803673e8e59SChristoph Hellwig error = xfs_zero_eof(ip, newsize, oldsize); 804c59d87c4SChristoph Hellwig if (error) 80576ca4c23SChristoph Hellwig return error; 806c59d87c4SChristoph Hellwig } 807c59d87c4SChristoph Hellwig 808c59d87c4SChristoph Hellwig /* 809c59d87c4SChristoph Hellwig * We are going to log the inode size change in this transaction so 810c59d87c4SChristoph Hellwig * any previous writes that are beyond the on disk EOF and the new 811c59d87c4SChristoph Hellwig * EOF that have not been written out need to be written here. If we 812c59d87c4SChristoph Hellwig * do not write the data out, we expose ourselves to the null files 813c59d87c4SChristoph Hellwig * problem. 814c59d87c4SChristoph Hellwig * 815c59d87c4SChristoph Hellwig * Only flush from the on disk size to the smaller of the in memory 816c59d87c4SChristoph Hellwig * file size or the new size as that's the range we really care about 817c59d87c4SChristoph Hellwig * here and prevents waiting for other data not within the range we 818c59d87c4SChristoph Hellwig * care about here. 819c59d87c4SChristoph Hellwig */ 820673e8e59SChristoph Hellwig if (oldsize != ip->i_d.di_size && newsize > ip->i_d.di_size) { 8214bc1ea6bSDave Chinner error = -filemap_write_and_wait_range(VFS_I(ip)->i_mapping, 8224bc1ea6bSDave Chinner ip->i_d.di_size, newsize); 823c59d87c4SChristoph Hellwig if (error) 82476ca4c23SChristoph Hellwig return error; 825c59d87c4SChristoph Hellwig } 826c59d87c4SChristoph Hellwig 827c59d87c4SChristoph Hellwig /* 8284a06fd26SChristoph Hellwig * Wait for all direct I/O to complete. 829c59d87c4SChristoph Hellwig */ 8304a06fd26SChristoph Hellwig inode_dio_wait(inode); 831c59d87c4SChristoph Hellwig 832673e8e59SChristoph Hellwig error = -block_truncate_page(inode->i_mapping, newsize, xfs_get_blocks); 833c59d87c4SChristoph Hellwig if (error) 83476ca4c23SChristoph Hellwig return error; 835c59d87c4SChristoph Hellwig 836c59d87c4SChristoph Hellwig tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_SIZE); 8373d3c8b52SJie Liu error = xfs_trans_reserve(tp, &M_RES(mp)->tr_itruncate, 0, 0); 838c59d87c4SChristoph Hellwig if (error) 839c59d87c4SChristoph Hellwig goto out_trans_cancel; 840c59d87c4SChristoph Hellwig 841673e8e59SChristoph Hellwig truncate_setsize(inode, newsize); 842c59d87c4SChristoph Hellwig 843c59d87c4SChristoph Hellwig commit_flags = XFS_TRANS_RELEASE_LOG_RES; 844c59d87c4SChristoph Hellwig lock_flags |= XFS_ILOCK_EXCL; 845c59d87c4SChristoph Hellwig 846c59d87c4SChristoph Hellwig xfs_ilock(ip, XFS_ILOCK_EXCL); 847c59d87c4SChristoph Hellwig 848ddc3415aSChristoph Hellwig xfs_trans_ijoin(tp, ip, 0); 849c59d87c4SChristoph Hellwig 850c59d87c4SChristoph Hellwig /* 851c59d87c4SChristoph Hellwig * Only change the c/mtime if we are changing the size or we are 852c59d87c4SChristoph Hellwig * explicitly asked to change it. This handles the semantic difference 853c59d87c4SChristoph Hellwig * between truncate() and ftruncate() as implemented in the VFS. 854c59d87c4SChristoph Hellwig * 855c59d87c4SChristoph Hellwig * The regular truncate() case without ATTR_CTIME and ATTR_MTIME is a 856c59d87c4SChristoph Hellwig * special case where we need to update the times despite not having 857c59d87c4SChristoph Hellwig * these flags set. For all other operations the VFS set these flags 858c59d87c4SChristoph Hellwig * explicitly if it wants a timestamp update. 859c59d87c4SChristoph Hellwig */ 860fe60a8a0SChristoph Hellwig if (newsize != oldsize && 861fe60a8a0SChristoph Hellwig !(iattr->ia_valid & (ATTR_CTIME | ATTR_MTIME))) { 862c59d87c4SChristoph Hellwig iattr->ia_ctime = iattr->ia_mtime = 863c59d87c4SChristoph Hellwig current_fs_time(inode->i_sb); 864fe60a8a0SChristoph Hellwig iattr->ia_valid |= ATTR_CTIME | ATTR_MTIME; 865c59d87c4SChristoph Hellwig } 866c59d87c4SChristoph Hellwig 867673e8e59SChristoph Hellwig /* 868673e8e59SChristoph Hellwig * The first thing we do is set the size to new_size permanently on 869673e8e59SChristoph Hellwig * disk. This way we don't have to worry about anyone ever being able 870673e8e59SChristoph Hellwig * to look at the data being freed even in the face of a crash. 871673e8e59SChristoph Hellwig * What we're getting around here is the case where we free a block, it 872673e8e59SChristoph Hellwig * is allocated to another file, it is written to, and then we crash. 873673e8e59SChristoph Hellwig * If the new data gets written to the file but the log buffers 874673e8e59SChristoph Hellwig * containing the free and reallocation don't, then we'd end up with 875673e8e59SChristoph Hellwig * garbage in the blocks being freed. As long as we make the new size 876673e8e59SChristoph Hellwig * permanent before actually freeing any blocks it doesn't matter if 877673e8e59SChristoph Hellwig * they get written to. 878673e8e59SChristoph Hellwig */ 879673e8e59SChristoph Hellwig ip->i_d.di_size = newsize; 880673e8e59SChristoph Hellwig xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 881673e8e59SChristoph Hellwig 882673e8e59SChristoph Hellwig if (newsize <= oldsize) { 883673e8e59SChristoph Hellwig error = xfs_itruncate_extents(&tp, ip, XFS_DATA_FORK, newsize); 884c59d87c4SChristoph Hellwig if (error) 885c59d87c4SChristoph Hellwig goto out_trans_abort; 886c59d87c4SChristoph Hellwig 887c59d87c4SChristoph Hellwig /* 888c59d87c4SChristoph Hellwig * Truncated "down", so we're removing references to old data 889c59d87c4SChristoph Hellwig * here - if we delay flushing for a long time, we expose 890c59d87c4SChristoph Hellwig * ourselves unduly to the notorious NULL files problem. So, 891c59d87c4SChristoph Hellwig * we mark this inode and flush it when the file is closed, 892c59d87c4SChristoph Hellwig * and do not wait the usual (long) time for writeout. 893c59d87c4SChristoph Hellwig */ 894c59d87c4SChristoph Hellwig xfs_iflags_set(ip, XFS_ITRUNCATED); 89527b52867SBrian Foster 89627b52867SBrian Foster /* A truncate down always removes post-EOF blocks. */ 89727b52867SBrian Foster xfs_inode_clear_eofblocks_tag(ip); 898c59d87c4SChristoph Hellwig } 899c59d87c4SChristoph Hellwig 900fe60a8a0SChristoph Hellwig if (iattr->ia_valid & ATTR_MODE) 9010c3d88dfSChristoph Hellwig xfs_setattr_mode(ip, iattr); 902fe60a8a0SChristoph Hellwig if (iattr->ia_valid & (ATTR_ATIME|ATTR_CTIME|ATTR_MTIME)) 903c91c46c1SChristoph Hellwig xfs_setattr_time(ip, iattr); 904c59d87c4SChristoph Hellwig 905c59d87c4SChristoph Hellwig xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 906c59d87c4SChristoph Hellwig 907c59d87c4SChristoph Hellwig XFS_STATS_INC(xs_ig_attrchg); 908c59d87c4SChristoph Hellwig 909c59d87c4SChristoph Hellwig if (mp->m_flags & XFS_MOUNT_WSYNC) 910c59d87c4SChristoph Hellwig xfs_trans_set_sync(tp); 911c59d87c4SChristoph Hellwig 912c59d87c4SChristoph Hellwig error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); 913c59d87c4SChristoph Hellwig out_unlock: 914c59d87c4SChristoph Hellwig if (lock_flags) 915c59d87c4SChristoph Hellwig xfs_iunlock(ip, lock_flags); 916c59d87c4SChristoph Hellwig return error; 917c59d87c4SChristoph Hellwig 918c59d87c4SChristoph Hellwig out_trans_abort: 919c59d87c4SChristoph Hellwig commit_flags |= XFS_TRANS_ABORT; 920c59d87c4SChristoph Hellwig out_trans_cancel: 921c59d87c4SChristoph Hellwig xfs_trans_cancel(tp, commit_flags); 922c59d87c4SChristoph Hellwig goto out_unlock; 923c59d87c4SChristoph Hellwig } 924c59d87c4SChristoph Hellwig 925c59d87c4SChristoph Hellwig STATIC int 926c59d87c4SChristoph Hellwig xfs_vn_setattr( 927c59d87c4SChristoph Hellwig struct dentry *dentry, 928c59d87c4SChristoph Hellwig struct iattr *iattr) 929c59d87c4SChristoph Hellwig { 93076ca4c23SChristoph Hellwig struct xfs_inode *ip = XFS_I(dentry->d_inode); 93176ca4c23SChristoph Hellwig int error; 93276ca4c23SChristoph Hellwig 93376ca4c23SChristoph Hellwig if (iattr->ia_valid & ATTR_SIZE) { 93476ca4c23SChristoph Hellwig xfs_ilock(ip, XFS_IOLOCK_EXCL); 93576ca4c23SChristoph Hellwig error = xfs_setattr_size(ip, iattr); 93676ca4c23SChristoph Hellwig xfs_iunlock(ip, XFS_IOLOCK_EXCL); 93776ca4c23SChristoph Hellwig } else { 93876ca4c23SChristoph Hellwig error = xfs_setattr_nonsize(ip, iattr, 0); 93976ca4c23SChristoph Hellwig } 94076ca4c23SChristoph Hellwig 94176ca4c23SChristoph Hellwig return -error; 942c59d87c4SChristoph Hellwig } 943c59d87c4SChristoph Hellwig 94469ff2826SChristoph Hellwig STATIC int 94569ff2826SChristoph Hellwig xfs_vn_update_time( 94669ff2826SChristoph Hellwig struct inode *inode, 94769ff2826SChristoph Hellwig struct timespec *now, 94869ff2826SChristoph Hellwig int flags) 94969ff2826SChristoph Hellwig { 95069ff2826SChristoph Hellwig struct xfs_inode *ip = XFS_I(inode); 95169ff2826SChristoph Hellwig struct xfs_mount *mp = ip->i_mount; 95269ff2826SChristoph Hellwig struct xfs_trans *tp; 95369ff2826SChristoph Hellwig int error; 95469ff2826SChristoph Hellwig 95569ff2826SChristoph Hellwig trace_xfs_update_time(ip); 95669ff2826SChristoph Hellwig 95769ff2826SChristoph Hellwig tp = xfs_trans_alloc(mp, XFS_TRANS_FSYNC_TS); 9583d3c8b52SJie Liu error = xfs_trans_reserve(tp, &M_RES(mp)->tr_fsyncts, 0, 0); 95969ff2826SChristoph Hellwig if (error) { 96069ff2826SChristoph Hellwig xfs_trans_cancel(tp, 0); 96169ff2826SChristoph Hellwig return -error; 96269ff2826SChristoph Hellwig } 96369ff2826SChristoph Hellwig 96469ff2826SChristoph Hellwig xfs_ilock(ip, XFS_ILOCK_EXCL); 96569ff2826SChristoph Hellwig if (flags & S_CTIME) { 96669ff2826SChristoph Hellwig inode->i_ctime = *now; 96769ff2826SChristoph Hellwig ip->i_d.di_ctime.t_sec = (__int32_t)now->tv_sec; 96869ff2826SChristoph Hellwig ip->i_d.di_ctime.t_nsec = (__int32_t)now->tv_nsec; 96969ff2826SChristoph Hellwig } 97069ff2826SChristoph Hellwig if (flags & S_MTIME) { 97169ff2826SChristoph Hellwig inode->i_mtime = *now; 97269ff2826SChristoph Hellwig ip->i_d.di_mtime.t_sec = (__int32_t)now->tv_sec; 97369ff2826SChristoph Hellwig ip->i_d.di_mtime.t_nsec = (__int32_t)now->tv_nsec; 97469ff2826SChristoph Hellwig } 97569ff2826SChristoph Hellwig if (flags & S_ATIME) { 97669ff2826SChristoph Hellwig inode->i_atime = *now; 97769ff2826SChristoph Hellwig ip->i_d.di_atime.t_sec = (__int32_t)now->tv_sec; 97869ff2826SChristoph Hellwig ip->i_d.di_atime.t_nsec = (__int32_t)now->tv_nsec; 97969ff2826SChristoph Hellwig } 98069ff2826SChristoph Hellwig xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); 98169ff2826SChristoph Hellwig xfs_trans_log_inode(tp, ip, XFS_ILOG_TIMESTAMP); 98269ff2826SChristoph Hellwig return -xfs_trans_commit(tp, 0); 98369ff2826SChristoph Hellwig } 98469ff2826SChristoph Hellwig 985c59d87c4SChristoph Hellwig #define XFS_FIEMAP_FLAGS (FIEMAP_FLAG_SYNC|FIEMAP_FLAG_XATTR) 986c59d87c4SChristoph Hellwig 987c59d87c4SChristoph Hellwig /* 988c59d87c4SChristoph Hellwig * Call fiemap helper to fill in user data. 989c59d87c4SChristoph Hellwig * Returns positive errors to xfs_getbmap. 990c59d87c4SChristoph Hellwig */ 991c59d87c4SChristoph Hellwig STATIC int 992c59d87c4SChristoph Hellwig xfs_fiemap_format( 993c59d87c4SChristoph Hellwig void **arg, 994c59d87c4SChristoph Hellwig struct getbmapx *bmv, 995c59d87c4SChristoph Hellwig int *full) 996c59d87c4SChristoph Hellwig { 997c59d87c4SChristoph Hellwig int error; 998c59d87c4SChristoph Hellwig struct fiemap_extent_info *fieinfo = *arg; 999c59d87c4SChristoph Hellwig u32 fiemap_flags = 0; 1000c59d87c4SChristoph Hellwig u64 logical, physical, length; 1001c59d87c4SChristoph Hellwig 1002c59d87c4SChristoph Hellwig /* Do nothing for a hole */ 1003c59d87c4SChristoph Hellwig if (bmv->bmv_block == -1LL) 1004c59d87c4SChristoph Hellwig return 0; 1005c59d87c4SChristoph Hellwig 1006c59d87c4SChristoph Hellwig logical = BBTOB(bmv->bmv_offset); 1007c59d87c4SChristoph Hellwig physical = BBTOB(bmv->bmv_block); 1008c59d87c4SChristoph Hellwig length = BBTOB(bmv->bmv_length); 1009c59d87c4SChristoph Hellwig 1010c59d87c4SChristoph Hellwig if (bmv->bmv_oflags & BMV_OF_PREALLOC) 1011c59d87c4SChristoph Hellwig fiemap_flags |= FIEMAP_EXTENT_UNWRITTEN; 1012c59d87c4SChristoph Hellwig else if (bmv->bmv_oflags & BMV_OF_DELALLOC) { 1013635c4d0bSJie Liu fiemap_flags |= (FIEMAP_EXTENT_DELALLOC | 1014635c4d0bSJie Liu FIEMAP_EXTENT_UNKNOWN); 1015c59d87c4SChristoph Hellwig physical = 0; /* no block yet */ 1016c59d87c4SChristoph Hellwig } 1017c59d87c4SChristoph Hellwig if (bmv->bmv_oflags & BMV_OF_LAST) 1018c59d87c4SChristoph Hellwig fiemap_flags |= FIEMAP_EXTENT_LAST; 1019c59d87c4SChristoph Hellwig 1020c59d87c4SChristoph Hellwig error = fiemap_fill_next_extent(fieinfo, logical, physical, 1021c59d87c4SChristoph Hellwig length, fiemap_flags); 1022c59d87c4SChristoph Hellwig if (error > 0) { 1023c59d87c4SChristoph Hellwig error = 0; 1024c59d87c4SChristoph Hellwig *full = 1; /* user array now full */ 1025c59d87c4SChristoph Hellwig } 1026c59d87c4SChristoph Hellwig 1027c59d87c4SChristoph Hellwig return -error; 1028c59d87c4SChristoph Hellwig } 1029c59d87c4SChristoph Hellwig 1030c59d87c4SChristoph Hellwig STATIC int 1031c59d87c4SChristoph Hellwig xfs_vn_fiemap( 1032c59d87c4SChristoph Hellwig struct inode *inode, 1033c59d87c4SChristoph Hellwig struct fiemap_extent_info *fieinfo, 1034c59d87c4SChristoph Hellwig u64 start, 1035c59d87c4SChristoph Hellwig u64 length) 1036c59d87c4SChristoph Hellwig { 1037c59d87c4SChristoph Hellwig xfs_inode_t *ip = XFS_I(inode); 1038c59d87c4SChristoph Hellwig struct getbmapx bm; 1039c59d87c4SChristoph Hellwig int error; 1040c59d87c4SChristoph Hellwig 1041c59d87c4SChristoph Hellwig error = fiemap_check_flags(fieinfo, XFS_FIEMAP_FLAGS); 1042c59d87c4SChristoph Hellwig if (error) 1043c59d87c4SChristoph Hellwig return error; 1044c59d87c4SChristoph Hellwig 1045c59d87c4SChristoph Hellwig /* Set up bmap header for xfs internal routine */ 1046c59d87c4SChristoph Hellwig bm.bmv_offset = BTOBB(start); 1047c59d87c4SChristoph Hellwig /* Special case for whole file */ 1048c59d87c4SChristoph Hellwig if (length == FIEMAP_MAX_OFFSET) 1049c59d87c4SChristoph Hellwig bm.bmv_length = -1LL; 1050c59d87c4SChristoph Hellwig else 1051c59d87c4SChristoph Hellwig bm.bmv_length = BTOBB(length); 1052c59d87c4SChristoph Hellwig 1053c59d87c4SChristoph Hellwig /* We add one because in getbmap world count includes the header */ 1054c59d87c4SChristoph Hellwig bm.bmv_count = !fieinfo->fi_extents_max ? MAXEXTNUM : 1055c59d87c4SChristoph Hellwig fieinfo->fi_extents_max + 1; 1056c59d87c4SChristoph Hellwig bm.bmv_count = min_t(__s32, bm.bmv_count, 1057c59d87c4SChristoph Hellwig (PAGE_SIZE * 16 / sizeof(struct getbmapx))); 1058c59d87c4SChristoph Hellwig bm.bmv_iflags = BMV_IF_PREALLOC | BMV_IF_NO_HOLES; 1059c59d87c4SChristoph Hellwig if (fieinfo->fi_flags & FIEMAP_FLAG_XATTR) 1060c59d87c4SChristoph Hellwig bm.bmv_iflags |= BMV_IF_ATTRFORK; 1061c59d87c4SChristoph Hellwig if (!(fieinfo->fi_flags & FIEMAP_FLAG_SYNC)) 1062c59d87c4SChristoph Hellwig bm.bmv_iflags |= BMV_IF_DELALLOC; 1063c59d87c4SChristoph Hellwig 1064c59d87c4SChristoph Hellwig error = xfs_getbmap(ip, &bm, xfs_fiemap_format, fieinfo); 1065c59d87c4SChristoph Hellwig if (error) 1066c59d87c4SChristoph Hellwig return -error; 1067c59d87c4SChristoph Hellwig 1068c59d87c4SChristoph Hellwig return 0; 1069c59d87c4SChristoph Hellwig } 1070c59d87c4SChristoph Hellwig 107199b6436bSZhi Yong Wu STATIC int 107299b6436bSZhi Yong Wu xfs_vn_tmpfile( 107399b6436bSZhi Yong Wu struct inode *dir, 107499b6436bSZhi Yong Wu struct dentry *dentry, 107599b6436bSZhi Yong Wu umode_t mode) 107699b6436bSZhi Yong Wu { 1077*d540e43bSBrian Foster return xfs_generic_create(dir, dentry, mode, 0, true); 107899b6436bSZhi Yong Wu } 107999b6436bSZhi Yong Wu 1080c59d87c4SChristoph Hellwig static const struct inode_operations xfs_inode_operations = { 1081c59d87c4SChristoph Hellwig .get_acl = xfs_get_acl, 10822401dc29SChristoph Hellwig .set_acl = xfs_set_acl, 1083c59d87c4SChristoph Hellwig .getattr = xfs_vn_getattr, 1084c59d87c4SChristoph Hellwig .setattr = xfs_vn_setattr, 1085c59d87c4SChristoph Hellwig .setxattr = generic_setxattr, 1086c59d87c4SChristoph Hellwig .getxattr = generic_getxattr, 1087c59d87c4SChristoph Hellwig .removexattr = generic_removexattr, 1088c59d87c4SChristoph Hellwig .listxattr = xfs_vn_listxattr, 1089c59d87c4SChristoph Hellwig .fiemap = xfs_vn_fiemap, 109069ff2826SChristoph Hellwig .update_time = xfs_vn_update_time, 1091c59d87c4SChristoph Hellwig }; 1092c59d87c4SChristoph Hellwig 1093c59d87c4SChristoph Hellwig static const struct inode_operations xfs_dir_inode_operations = { 1094c59d87c4SChristoph Hellwig .create = xfs_vn_create, 1095c59d87c4SChristoph Hellwig .lookup = xfs_vn_lookup, 1096c59d87c4SChristoph Hellwig .link = xfs_vn_link, 1097c59d87c4SChristoph Hellwig .unlink = xfs_vn_unlink, 1098c59d87c4SChristoph Hellwig .symlink = xfs_vn_symlink, 1099c59d87c4SChristoph Hellwig .mkdir = xfs_vn_mkdir, 1100c59d87c4SChristoph Hellwig /* 1101c59d87c4SChristoph Hellwig * Yes, XFS uses the same method for rmdir and unlink. 1102c59d87c4SChristoph Hellwig * 1103c59d87c4SChristoph Hellwig * There are some subtile differences deeper in the code, 1104c59d87c4SChristoph Hellwig * but we use S_ISDIR to check for those. 1105c59d87c4SChristoph Hellwig */ 1106c59d87c4SChristoph Hellwig .rmdir = xfs_vn_unlink, 1107c59d87c4SChristoph Hellwig .mknod = xfs_vn_mknod, 1108c59d87c4SChristoph Hellwig .rename = xfs_vn_rename, 1109c59d87c4SChristoph Hellwig .get_acl = xfs_get_acl, 11102401dc29SChristoph Hellwig .set_acl = xfs_set_acl, 1111c59d87c4SChristoph Hellwig .getattr = xfs_vn_getattr, 1112c59d87c4SChristoph Hellwig .setattr = xfs_vn_setattr, 1113c59d87c4SChristoph Hellwig .setxattr = generic_setxattr, 1114c59d87c4SChristoph Hellwig .getxattr = generic_getxattr, 1115c59d87c4SChristoph Hellwig .removexattr = generic_removexattr, 1116c59d87c4SChristoph Hellwig .listxattr = xfs_vn_listxattr, 111769ff2826SChristoph Hellwig .update_time = xfs_vn_update_time, 111899b6436bSZhi Yong Wu .tmpfile = xfs_vn_tmpfile, 1119c59d87c4SChristoph Hellwig }; 1120c59d87c4SChristoph Hellwig 1121c59d87c4SChristoph Hellwig static const struct inode_operations xfs_dir_ci_inode_operations = { 1122c59d87c4SChristoph Hellwig .create = xfs_vn_create, 1123c59d87c4SChristoph Hellwig .lookup = xfs_vn_ci_lookup, 1124c59d87c4SChristoph Hellwig .link = xfs_vn_link, 1125c59d87c4SChristoph Hellwig .unlink = xfs_vn_unlink, 1126c59d87c4SChristoph Hellwig .symlink = xfs_vn_symlink, 1127c59d87c4SChristoph Hellwig .mkdir = xfs_vn_mkdir, 1128c59d87c4SChristoph Hellwig /* 1129c59d87c4SChristoph Hellwig * Yes, XFS uses the same method for rmdir and unlink. 1130c59d87c4SChristoph Hellwig * 1131c59d87c4SChristoph Hellwig * There are some subtile differences deeper in the code, 1132c59d87c4SChristoph Hellwig * but we use S_ISDIR to check for those. 1133c59d87c4SChristoph Hellwig */ 1134c59d87c4SChristoph Hellwig .rmdir = xfs_vn_unlink, 1135c59d87c4SChristoph Hellwig .mknod = xfs_vn_mknod, 1136c59d87c4SChristoph Hellwig .rename = xfs_vn_rename, 1137c59d87c4SChristoph Hellwig .get_acl = xfs_get_acl, 11382401dc29SChristoph Hellwig .set_acl = xfs_set_acl, 1139c59d87c4SChristoph Hellwig .getattr = xfs_vn_getattr, 1140c59d87c4SChristoph Hellwig .setattr = xfs_vn_setattr, 1141c59d87c4SChristoph Hellwig .setxattr = generic_setxattr, 1142c59d87c4SChristoph Hellwig .getxattr = generic_getxattr, 1143c59d87c4SChristoph Hellwig .removexattr = generic_removexattr, 1144c59d87c4SChristoph Hellwig .listxattr = xfs_vn_listxattr, 114569ff2826SChristoph Hellwig .update_time = xfs_vn_update_time, 114699b6436bSZhi Yong Wu .tmpfile = xfs_vn_tmpfile, 1147c59d87c4SChristoph Hellwig }; 1148c59d87c4SChristoph Hellwig 1149c59d87c4SChristoph Hellwig static const struct inode_operations xfs_symlink_inode_operations = { 1150c59d87c4SChristoph Hellwig .readlink = generic_readlink, 1151c59d87c4SChristoph Hellwig .follow_link = xfs_vn_follow_link, 115296c8c442SAl Viro .put_link = kfree_put_link, 1153c59d87c4SChristoph Hellwig .getattr = xfs_vn_getattr, 1154c59d87c4SChristoph Hellwig .setattr = xfs_vn_setattr, 1155c59d87c4SChristoph Hellwig .setxattr = generic_setxattr, 1156c59d87c4SChristoph Hellwig .getxattr = generic_getxattr, 1157c59d87c4SChristoph Hellwig .removexattr = generic_removexattr, 1158c59d87c4SChristoph Hellwig .listxattr = xfs_vn_listxattr, 115969ff2826SChristoph Hellwig .update_time = xfs_vn_update_time, 1160c59d87c4SChristoph Hellwig }; 1161c59d87c4SChristoph Hellwig 1162c59d87c4SChristoph Hellwig STATIC void 1163c59d87c4SChristoph Hellwig xfs_diflags_to_iflags( 1164c59d87c4SChristoph Hellwig struct inode *inode, 1165c59d87c4SChristoph Hellwig struct xfs_inode *ip) 1166c59d87c4SChristoph Hellwig { 1167c59d87c4SChristoph Hellwig if (ip->i_d.di_flags & XFS_DIFLAG_IMMUTABLE) 1168c59d87c4SChristoph Hellwig inode->i_flags |= S_IMMUTABLE; 1169c59d87c4SChristoph Hellwig else 1170c59d87c4SChristoph Hellwig inode->i_flags &= ~S_IMMUTABLE; 1171c59d87c4SChristoph Hellwig if (ip->i_d.di_flags & XFS_DIFLAG_APPEND) 1172c59d87c4SChristoph Hellwig inode->i_flags |= S_APPEND; 1173c59d87c4SChristoph Hellwig else 1174c59d87c4SChristoph Hellwig inode->i_flags &= ~S_APPEND; 1175c59d87c4SChristoph Hellwig if (ip->i_d.di_flags & XFS_DIFLAG_SYNC) 1176c59d87c4SChristoph Hellwig inode->i_flags |= S_SYNC; 1177c59d87c4SChristoph Hellwig else 1178c59d87c4SChristoph Hellwig inode->i_flags &= ~S_SYNC; 1179c59d87c4SChristoph Hellwig if (ip->i_d.di_flags & XFS_DIFLAG_NOATIME) 1180c59d87c4SChristoph Hellwig inode->i_flags |= S_NOATIME; 1181c59d87c4SChristoph Hellwig else 1182c59d87c4SChristoph Hellwig inode->i_flags &= ~S_NOATIME; 1183c59d87c4SChristoph Hellwig } 1184c59d87c4SChristoph Hellwig 1185c59d87c4SChristoph Hellwig /* 1186c59d87c4SChristoph Hellwig * Initialize the Linux inode, set up the operation vectors and 1187c59d87c4SChristoph Hellwig * unlock the inode. 1188c59d87c4SChristoph Hellwig * 1189c59d87c4SChristoph Hellwig * When reading existing inodes from disk this is called directly 1190c59d87c4SChristoph Hellwig * from xfs_iget, when creating a new inode it is called from 1191c59d87c4SChristoph Hellwig * xfs_ialloc after setting up the inode. 1192c59d87c4SChristoph Hellwig * 1193c59d87c4SChristoph Hellwig * We are always called with an uninitialised linux inode here. 1194c59d87c4SChristoph Hellwig * We need to initialise the necessary fields and take a reference 1195c59d87c4SChristoph Hellwig * on it. 1196c59d87c4SChristoph Hellwig */ 1197c59d87c4SChristoph Hellwig void 1198c59d87c4SChristoph Hellwig xfs_setup_inode( 1199c59d87c4SChristoph Hellwig struct xfs_inode *ip) 1200c59d87c4SChristoph Hellwig { 1201c59d87c4SChristoph Hellwig struct inode *inode = &ip->i_vnode; 1202ad22c7a0SDave Chinner gfp_t gfp_mask; 1203c59d87c4SChristoph Hellwig 1204c59d87c4SChristoph Hellwig inode->i_ino = ip->i_ino; 1205c59d87c4SChristoph Hellwig inode->i_state = I_NEW; 1206c59d87c4SChristoph Hellwig 1207c59d87c4SChristoph Hellwig inode_sb_list_add(inode); 1208c59d87c4SChristoph Hellwig /* make the inode look hashed for the writeback code */ 1209c59d87c4SChristoph Hellwig hlist_add_fake(&inode->i_hash); 1210c59d87c4SChristoph Hellwig 1211c59d87c4SChristoph Hellwig inode->i_mode = ip->i_d.di_mode; 1212bfe86848SMiklos Szeredi set_nlink(inode, ip->i_d.di_nlink); 12137aab1b28SDwight Engen inode->i_uid = xfs_uid_to_kuid(ip->i_d.di_uid); 12147aab1b28SDwight Engen inode->i_gid = xfs_gid_to_kgid(ip->i_d.di_gid); 1215c59d87c4SChristoph Hellwig 1216c59d87c4SChristoph Hellwig switch (inode->i_mode & S_IFMT) { 1217c59d87c4SChristoph Hellwig case S_IFBLK: 1218c59d87c4SChristoph Hellwig case S_IFCHR: 1219c59d87c4SChristoph Hellwig inode->i_rdev = 1220c59d87c4SChristoph Hellwig MKDEV(sysv_major(ip->i_df.if_u2.if_rdev) & 0x1ff, 1221c59d87c4SChristoph Hellwig sysv_minor(ip->i_df.if_u2.if_rdev)); 1222c59d87c4SChristoph Hellwig break; 1223c59d87c4SChristoph Hellwig default: 1224c59d87c4SChristoph Hellwig inode->i_rdev = 0; 1225c59d87c4SChristoph Hellwig break; 1226c59d87c4SChristoph Hellwig } 1227c59d87c4SChristoph Hellwig 1228c59d87c4SChristoph Hellwig inode->i_generation = ip->i_d.di_gen; 1229c59d87c4SChristoph Hellwig i_size_write(inode, ip->i_d.di_size); 1230c59d87c4SChristoph Hellwig inode->i_atime.tv_sec = ip->i_d.di_atime.t_sec; 1231c59d87c4SChristoph Hellwig inode->i_atime.tv_nsec = ip->i_d.di_atime.t_nsec; 1232c59d87c4SChristoph Hellwig inode->i_mtime.tv_sec = ip->i_d.di_mtime.t_sec; 1233c59d87c4SChristoph Hellwig inode->i_mtime.tv_nsec = ip->i_d.di_mtime.t_nsec; 1234c59d87c4SChristoph Hellwig inode->i_ctime.tv_sec = ip->i_d.di_ctime.t_sec; 1235c59d87c4SChristoph Hellwig inode->i_ctime.tv_nsec = ip->i_d.di_ctime.t_nsec; 1236c59d87c4SChristoph Hellwig xfs_diflags_to_iflags(inode, ip); 1237c59d87c4SChristoph Hellwig 12384bceb18fSDave Chinner ip->d_ops = ip->i_mount->m_nondir_inode_ops; 123993a8614eSDave Chinner lockdep_set_class(&ip->i_lock.mr_lock, &xfs_nondir_ilock_class); 1240c59d87c4SChristoph Hellwig switch (inode->i_mode & S_IFMT) { 1241c59d87c4SChristoph Hellwig case S_IFREG: 1242c59d87c4SChristoph Hellwig inode->i_op = &xfs_inode_operations; 1243c59d87c4SChristoph Hellwig inode->i_fop = &xfs_file_operations; 1244c59d87c4SChristoph Hellwig inode->i_mapping->a_ops = &xfs_address_space_operations; 1245c59d87c4SChristoph Hellwig break; 1246c59d87c4SChristoph Hellwig case S_IFDIR: 124793a8614eSDave Chinner lockdep_set_class(&ip->i_lock.mr_lock, &xfs_dir_ilock_class); 1248c59d87c4SChristoph Hellwig if (xfs_sb_version_hasasciici(&XFS_M(inode->i_sb)->m_sb)) 1249c59d87c4SChristoph Hellwig inode->i_op = &xfs_dir_ci_inode_operations; 1250c59d87c4SChristoph Hellwig else 1251c59d87c4SChristoph Hellwig inode->i_op = &xfs_dir_inode_operations; 1252c59d87c4SChristoph Hellwig inode->i_fop = &xfs_dir_file_operations; 125332c5483aSDave Chinner ip->d_ops = ip->i_mount->m_dir_inode_ops; 1254c59d87c4SChristoph Hellwig break; 1255c59d87c4SChristoph Hellwig case S_IFLNK: 1256c59d87c4SChristoph Hellwig inode->i_op = &xfs_symlink_inode_operations; 1257c59d87c4SChristoph Hellwig if (!(ip->i_df.if_flags & XFS_IFINLINE)) 1258c59d87c4SChristoph Hellwig inode->i_mapping->a_ops = &xfs_address_space_operations; 1259c59d87c4SChristoph Hellwig break; 1260c59d87c4SChristoph Hellwig default: 1261c59d87c4SChristoph Hellwig inode->i_op = &xfs_inode_operations; 1262c59d87c4SChristoph Hellwig init_special_inode(inode, inode->i_mode, inode->i_rdev); 1263c59d87c4SChristoph Hellwig break; 1264c59d87c4SChristoph Hellwig } 1265c59d87c4SChristoph Hellwig 1266c59d87c4SChristoph Hellwig /* 1267ad22c7a0SDave Chinner * Ensure all page cache allocations are done from GFP_NOFS context to 1268ad22c7a0SDave Chinner * prevent direct reclaim recursion back into the filesystem and blowing 1269ad22c7a0SDave Chinner * stacks or deadlocking. 1270ad22c7a0SDave Chinner */ 1271ad22c7a0SDave Chinner gfp_mask = mapping_gfp_mask(inode->i_mapping); 1272ad22c7a0SDave Chinner mapping_set_gfp_mask(inode->i_mapping, (gfp_mask & ~(__GFP_FS))); 1273ad22c7a0SDave Chinner 1274ad22c7a0SDave Chinner /* 1275c59d87c4SChristoph Hellwig * If there is no attribute fork no ACL can exist on this inode, 1276c59d87c4SChristoph Hellwig * and it can't have any file capabilities attached to it either. 1277c59d87c4SChristoph Hellwig */ 1278c59d87c4SChristoph Hellwig if (!XFS_IFORK_Q(ip)) { 1279c59d87c4SChristoph Hellwig inode_has_no_xattr(inode); 1280c59d87c4SChristoph Hellwig cache_no_acl(inode); 1281c59d87c4SChristoph Hellwig } 1282c59d87c4SChristoph Hellwig 1283c59d87c4SChristoph Hellwig xfs_iflags_clear(ip, XFS_INEW); 1284c59d87c4SChristoph Hellwig barrier(); 1285c59d87c4SChristoph Hellwig 1286c59d87c4SChristoph Hellwig unlock_new_inode(inode); 1287c59d87c4SChristoph Hellwig } 1288