diff options
| author | Mauro Carvalho Chehab <[email protected]> | 2014-04-14 12:00:36 -0300 |
|---|---|---|
| committer | Mauro Carvalho Chehab <[email protected]> | 2014-04-14 12:00:36 -0300 |
| commit | 277a163c83d7ba93fba1e8980d29a9f8bfcfba6c (patch) | |
| tree | ccfd357d152292958957b6b8a993892e7a8cc95f /fs/xfs/xfs_iops.c | |
| parent | a83b93a7480441a47856dc9104bea970e84cda87 (diff) | |
| parent | c9eaa447e77efe77b7fa4c953bd62de8297fd6c5 (diff) | |
Merge tag 'v3.15-rc1' into patchwork
Linux 3.15-rc1
* tag 'v3.15-rc1': (12180 commits)
Linux 3.15-rc1
mm: Initialize error in shmem_file_aio_read()
cifs: Use min_t() when comparing "size_t" and "unsigned long"
sym53c8xx_2: Set DID_REQUEUE return code when aborting squeue
powerpc: Don't try to set LPCR unless we're in hypervisor mode
futex: update documentation for ordering guarantees
ceph: fix pr_fmt() redefinition
vti: don't allow to add the same tunnel twice
gre: don't allow to add the same tunnel twice
drivers: net: xen-netfront: fix array initialization bug
missing bits of "splice: fix racy pipe->buffers uses"
cifs: fix the race in cifs_writev()
ceph_sync_{,direct_}write: fix an oops on ceph_osdc_new_request() failure
pktgen: be friendly to LLTX devices
r8152: check RTL8152_UNPLUG
net: sun4i-emac: add promiscuous support
net/apne: replace IS_ERR and PTR_ERR with PTR_ERR_OR_ZERO
blackfin: cleanup board files
bf609: clock: drop unused clock bit set/clear functions
Blackfin: bf537: rename "CONFIG_ADT75"
...
Diffstat (limited to 'fs/xfs/xfs_iops.c')
| -rw-r--r-- | fs/xfs/xfs_iops.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 9ddfb8190ca1..89b07e43ca28 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -39,6 +39,7 @@ #include "xfs_da_btree.h" #include "xfs_dir2_priv.h" #include "xfs_dinode.h" +#include "xfs_trans_space.h" #include <linux/capability.h> #include <linux/xattr.h> @@ -48,6 +49,18 @@ #include <linux/fiemap.h> #include <linux/slab.h> +/* + * Directories have different lock order w.r.t. mmap_sem compared to regular + * files. This is due to readdir potentially triggering page faults on a user + * buffer inside filldir(), and this happens with the ilock on the directory + * held. For regular files, the lock order is the other way around - the + * mmap_sem is taken during the page fault, and then we lock the ilock to do + * block mapping. Hence we need a different class for the directory ilock so + * that lockdep can tell them apart. + */ +static struct lock_class_key xfs_nondir_ilock_class; +static struct lock_class_key xfs_dir_ilock_class; + static int xfs_initxattrs( struct inode *inode, @@ -1034,6 +1047,19 @@ xfs_vn_fiemap( return 0; } +STATIC int +xfs_vn_tmpfile( + struct inode *dir, + struct dentry *dentry, + umode_t mode) +{ + int error; + + error = xfs_create_tmpfile(XFS_I(dir), dentry, mode); + + return -error; +} + static const struct inode_operations xfs_inode_operations = { .get_acl = xfs_get_acl, .set_acl = xfs_set_acl, @@ -1072,6 +1098,7 @@ static const struct inode_operations xfs_dir_inode_operations = { .removexattr = generic_removexattr, .listxattr = xfs_vn_listxattr, .update_time = xfs_vn_update_time, + .tmpfile = xfs_vn_tmpfile, }; static const struct inode_operations xfs_dir_ci_inode_operations = { @@ -1099,6 +1126,7 @@ static const struct inode_operations xfs_dir_ci_inode_operations = { .removexattr = generic_removexattr, .listxattr = xfs_vn_listxattr, .update_time = xfs_vn_update_time, + .tmpfile = xfs_vn_tmpfile, }; static const struct inode_operations xfs_symlink_inode_operations = { @@ -1191,6 +1219,7 @@ xfs_setup_inode( xfs_diflags_to_iflags(inode, ip); ip->d_ops = ip->i_mount->m_nondir_inode_ops; + lockdep_set_class(&ip->i_lock.mr_lock, &xfs_nondir_ilock_class); switch (inode->i_mode & S_IFMT) { case S_IFREG: inode->i_op = &xfs_inode_operations; @@ -1198,6 +1227,7 @@ xfs_setup_inode( inode->i_mapping->a_ops = &xfs_address_space_operations; break; case S_IFDIR: + lockdep_set_class(&ip->i_lock.mr_lock, &xfs_dir_ilock_class); if (xfs_sb_version_hasasciici(&XFS_M(inode->i_sb)->m_sb)) inode->i_op = &xfs_dir_ci_inode_operations; else |