aboutsummaryrefslogtreecommitdiffstats
path: root/fs/quota/dquot.c
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2010-09-15 11:38:58 -0400
committerJan Kara <jack@suse.cz>2011-01-12 13:14:55 -0500
commitf00c9e44ad1a9660fe8cd3ca15b6cd9497172eab (patch)
treecbb47ae0d8aba9d8b3c44714b000156715cdf969 /fs/quota/dquot.c
parent4162cf64973df51fc885825bc9ca4d055891c49f (diff)
quota: Fix deadlock during path resolution
As Al Viro pointed out path resolution during Q_QUOTAON calls to quotactl is prone to deadlocks. We hold s_umount semaphore for reading during the path resolution and resolution itself may need to acquire the semaphore for writing when e. g. autofs mountpoint is passed. Solve the problem by performing the resolution before we get hold of the superblock (and thus s_umount semaphore). The whole thing is complicated by the fact that some filesystems (OCFS2) ignore the path argument. So to distinguish between filesystem which want the path and which do not we introduce new .quota_on_meta callback which does not get the path. OCFS2 then uses this callback instead of old .quota_on. CC: Al Viro <viro@ZenIV.linux.org.uk> CC: Christoph Hellwig <hch@lst.de> CC: Ted Ts'o <tytso@mit.edu> CC: Joel Becker <joel.becker@oracle.com> Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/quota/dquot.c')
-rw-r--r--fs/quota/dquot.c18
1 files changed, 2 insertions, 16 deletions
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index 84becd3e4772..a2a622e079f0 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -2189,8 +2189,8 @@ int dquot_resume(struct super_block *sb, int type)
2189} 2189}
2190EXPORT_SYMBOL(dquot_resume); 2190EXPORT_SYMBOL(dquot_resume);
2191 2191
2192int dquot_quota_on_path(struct super_block *sb, int type, int format_id, 2192int dquot_quota_on(struct super_block *sb, int type, int format_id,
2193 struct path *path) 2193 struct path *path)
2194{ 2194{
2195 int error = security_quota_on(path->dentry); 2195 int error = security_quota_on(path->dentry);
2196 if (error) 2196 if (error)
@@ -2204,20 +2204,6 @@ int dquot_quota_on_path(struct super_block *sb, int type, int format_id,
2204 DQUOT_LIMITS_ENABLED); 2204 DQUOT_LIMITS_ENABLED);
2205 return error; 2205 return error;
2206} 2206}
2207EXPORT_SYMBOL(dquot_quota_on_path);
2208
2209int dquot_quota_on(struct super_block *sb, int type, int format_id, char *name)
2210{
2211 struct path path;
2212 int error;
2213
2214 error = kern_path(name, LOOKUP_FOLLOW, &path);
2215 if (!error) {
2216 error = dquot_quota_on_path(sb, type, format_id, &path);
2217 path_put(&path);
2218 }
2219 return error;
2220}
2221EXPORT_SYMBOL(dquot_quota_on); 2207EXPORT_SYMBOL(dquot_quota_on);
2222 2208
2223/* 2209/*