@@ -2306,28 +2306,60 @@ EXPORT_SYMBOL(dquot_quota_off);
23062306 * Turn quotas on on a device
23072307 */
23082308
2309- /*
2310- * Helper function to turn quotas on when we already have the inode of
2311- * quota file and no quota information is loaded.
2312- */
2313- static int vfs_load_quota_inode (struct inode * inode , int type , int format_id ,
2309+ static int vfs_setup_quota_inode (struct inode * inode , int type )
2310+ {
2311+ struct super_block * sb = inode -> i_sb ;
2312+ struct quota_info * dqopt = sb_dqopt (sb );
2313+
2314+ if (!S_ISREG (inode -> i_mode ))
2315+ return - EACCES ;
2316+ if (IS_RDONLY (inode ))
2317+ return - EROFS ;
2318+ if (sb_has_quota_loaded (sb , type ))
2319+ return - EBUSY ;
2320+
2321+ dqopt -> files [type ] = igrab (inode );
2322+ if (!dqopt -> files [type ])
2323+ return - EIO ;
2324+ if (!(dqopt -> flags & DQUOT_QUOTA_SYS_FILE )) {
2325+ /* We don't want quota and atime on quota files (deadlocks
2326+ * possible) Also nobody should write to the file - we use
2327+ * special IO operations which ignore the immutable bit. */
2328+ inode_lock (inode );
2329+ inode -> i_flags |= S_NOQUOTA ;
2330+ inode_unlock (inode );
2331+ /*
2332+ * When S_NOQUOTA is set, remove dquot references as no more
2333+ * references can be added
2334+ */
2335+ __dquot_drop (inode );
2336+ }
2337+ return 0 ;
2338+ }
2339+
2340+ static void vfs_cleanup_quota_inode (struct super_block * sb , int type )
2341+ {
2342+ struct quota_info * dqopt = sb_dqopt (sb );
2343+ struct inode * inode = dqopt -> files [type ];
2344+
2345+ if (!(dqopt -> flags & DQUOT_QUOTA_SYS_FILE )) {
2346+ inode_lock (inode );
2347+ inode -> i_flags &= ~S_NOQUOTA ;
2348+ inode_unlock (inode );
2349+ }
2350+ dqopt -> files [type ] = NULL ;
2351+ iput (inode );
2352+ }
2353+
2354+ int dquot_load_quota_sb (struct super_block * sb , int type , int format_id ,
23142355 unsigned int flags )
23152356{
23162357 struct quota_format_type * fmt = find_quota_format (format_id );
2317- struct super_block * sb = inode -> i_sb ;
23182358 struct quota_info * dqopt = sb_dqopt (sb );
23192359 int error ;
23202360
23212361 if (!fmt )
23222362 return - ESRCH ;
2323- if (!S_ISREG (inode -> i_mode )) {
2324- error = - EACCES ;
2325- goto out_fmt ;
2326- }
2327- if (IS_RDONLY (inode )) {
2328- error = - EROFS ;
2329- goto out_fmt ;
2330- }
23312363 if (!sb -> s_op -> quota_write || !sb -> s_op -> quota_read ||
23322364 (type == PRJQUOTA && sb -> dq_op -> get_projid == NULL )) {
23332365 error = - EINVAL ;
@@ -2359,35 +2391,17 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id,
23592391 invalidate_bdev (sb -> s_bdev );
23602392 }
23612393
2362- if (!(dqopt -> flags & DQUOT_QUOTA_SYS_FILE )) {
2363- /* We don't want quota and atime on quota files (deadlocks
2364- * possible) Also nobody should write to the file - we use
2365- * special IO operations which ignore the immutable bit. */
2366- inode_lock (inode );
2367- inode -> i_flags |= S_NOQUOTA ;
2368- inode_unlock (inode );
2369- /*
2370- * When S_NOQUOTA is set, remove dquot references as no more
2371- * references can be added
2372- */
2373- __dquot_drop (inode );
2374- }
2375-
2376- error = - EIO ;
2377- dqopt -> files [type ] = igrab (inode );
2378- if (!dqopt -> files [type ])
2379- goto out_file_flags ;
23802394 error = - EINVAL ;
23812395 if (!fmt -> qf_ops -> check_quota_file (sb , type ))
2382- goto out_file_init ;
2396+ goto out_fmt ;
23832397
23842398 dqopt -> ops [type ] = fmt -> qf_ops ;
23852399 dqopt -> info [type ].dqi_format = fmt ;
23862400 dqopt -> info [type ].dqi_fmt_id = format_id ;
23872401 INIT_LIST_HEAD (& dqopt -> info [type ].dqi_dirty_list );
23882402 error = dqopt -> ops [type ]-> read_file_info (sb , type );
23892403 if (error < 0 )
2390- goto out_file_init ;
2404+ goto out_fmt ;
23912405 if (dqopt -> flags & DQUOT_QUOTA_SYS_FILE ) {
23922406 spin_lock (& dq_data_lock );
23932407 dqopt -> info [type ].dqi_flags |= DQF_SYS_FILE ;
@@ -2402,18 +2416,30 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id,
24022416 dquot_disable (sb , type , flags );
24032417
24042418 return error ;
2405- out_file_init :
2406- dqopt -> files [type ] = NULL ;
2407- iput (inode );
2408- out_file_flags :
2409- inode_lock (inode );
2410- inode -> i_flags &= ~S_NOQUOTA ;
2411- inode_unlock (inode );
24122419out_fmt :
24132420 put_quota_format (fmt );
24142421
24152422 return error ;
24162423}
2424+ EXPORT_SYMBOL (dquot_load_quota_sb );
2425+
2426+ /*
2427+ * Helper function to turn quotas on when we already have the inode of
2428+ * quota file and no quota information is loaded.
2429+ */
2430+ static int vfs_load_quota_inode (struct inode * inode , int type , int format_id ,
2431+ unsigned int flags )
2432+ {
2433+ int err ;
2434+
2435+ err = vfs_setup_quota_inode (inode , type );
2436+ if (err < 0 )
2437+ return err ;
2438+ err = dquot_load_quota_sb (inode -> i_sb , type , format_id , flags );
2439+ if (err < 0 )
2440+ vfs_cleanup_quota_inode (inode -> i_sb , type );
2441+ return err ;
2442+ }
24172443
24182444/* Reenable quotas on remount RW */
24192445int dquot_resume (struct super_block * sb , int type )
0 commit comments