@@ -183,7 +183,7 @@ static inline void mnt_dec_count(struct vfsmount *mnt)
183
183
unsigned int mnt_get_count (struct vfsmount * mnt )
184
184
{
185
185
#ifdef CONFIG_SMP
186
- unsigned int count = atomic_read ( & mnt -> mnt_longrefs ) ;
186
+ unsigned int count = 0 ;
187
187
int cpu ;
188
188
189
189
for_each_possible_cpu (cpu ) {
@@ -217,7 +217,7 @@ struct vfsmount *alloc_vfsmnt(const char *name)
217
217
if (!mnt -> mnt_pcp )
218
218
goto out_free_devname ;
219
219
220
- atomic_set ( & mnt -> mnt_longrefs , 1 );
220
+ this_cpu_add ( mnt -> mnt_pcp -> mnt_count , 1 );
221
221
#else
222
222
mnt -> mnt_count = 1 ;
223
223
mnt -> mnt_writers = 0 ;
@@ -624,8 +624,11 @@ static void commit_tree(struct vfsmount *mnt)
624
624
BUG_ON (parent == mnt );
625
625
626
626
list_add_tail (& head , & mnt -> mnt_list );
627
- list_for_each_entry (m , & head , mnt_list )
627
+ list_for_each_entry (m , & head , mnt_list ) {
628
628
m -> mnt_ns = n ;
629
+ atomic_inc (& m -> mnt_longterm );
630
+ }
631
+
629
632
list_splice (& head , n -> list .prev );
630
633
631
634
list_add_tail (& mnt -> mnt_hash , mount_hashtable +
@@ -734,51 +737,30 @@ static inline void mntfree(struct vfsmount *mnt)
734
737
deactivate_super (sb );
735
738
}
736
739
737
- #ifdef CONFIG_SMP
738
- static inline void __mntput (struct vfsmount * mnt , int longrefs )
740
+ static void mntput_no_expire (struct vfsmount * mnt )
739
741
{
740
- if (!longrefs ) {
741
742
put_again :
742
- br_read_lock (vfsmount_lock );
743
- if (likely (atomic_read (& mnt -> mnt_longrefs ))) {
744
- mnt_dec_count (mnt );
745
- br_read_unlock (vfsmount_lock );
746
- return ;
747
- }
743
+ #ifdef CONFIG_SMP
744
+ br_read_lock (vfsmount_lock );
745
+ if (likely (atomic_read (& mnt -> mnt_longterm ))) {
746
+ mnt_dec_count (mnt );
748
747
br_read_unlock (vfsmount_lock );
749
- } else {
750
- BUG_ON (!atomic_read (& mnt -> mnt_longrefs ));
751
- if (atomic_add_unless (& mnt -> mnt_longrefs , -1 , 1 ))
752
- return ;
748
+ return ;
753
749
}
750
+ br_read_unlock (vfsmount_lock );
754
751
755
752
br_write_lock (vfsmount_lock );
756
- if (!longrefs )
757
- mnt_dec_count (mnt );
758
- else
759
- atomic_dec (& mnt -> mnt_longrefs );
753
+ mnt_dec_count (mnt );
760
754
if (mnt_get_count (mnt )) {
761
755
br_write_unlock (vfsmount_lock );
762
756
return ;
763
757
}
764
- if (unlikely (mnt -> mnt_pinned )) {
765
- mnt_add_count (mnt , mnt -> mnt_pinned + 1 );
766
- mnt -> mnt_pinned = 0 ;
767
- br_write_unlock (vfsmount_lock );
768
- acct_auto_close_mnt (mnt );
769
- goto put_again ;
770
- }
771
- br_write_unlock (vfsmount_lock );
772
- mntfree (mnt );
773
- }
774
758
#else
775
- static inline void __mntput (struct vfsmount * mnt , int longrefs )
776
- {
777
- put_again :
778
759
mnt_dec_count (mnt );
779
760
if (likely (mnt_get_count (mnt )))
780
761
return ;
781
762
br_write_lock (vfsmount_lock );
763
+ #endif
782
764
if (unlikely (mnt -> mnt_pinned )) {
783
765
mnt_add_count (mnt , mnt -> mnt_pinned + 1 );
784
766
mnt -> mnt_pinned = 0 ;
@@ -789,20 +771,14 @@ static inline void __mntput(struct vfsmount *mnt, int longrefs)
789
771
br_write_unlock (vfsmount_lock );
790
772
mntfree (mnt );
791
773
}
792
- #endif
793
-
794
- static void mntput_no_expire (struct vfsmount * mnt )
795
- {
796
- __mntput (mnt , 0 );
797
- }
798
774
799
775
void mntput (struct vfsmount * mnt )
800
776
{
801
777
if (mnt ) {
802
778
/* avoid cacheline pingpong, hope gcc doesn't get "smart" */
803
779
if (unlikely (mnt -> mnt_expiry_mark ))
804
780
mnt -> mnt_expiry_mark = 0 ;
805
- __mntput (mnt , 0 );
781
+ mntput_no_expire (mnt );
806
782
}
807
783
}
808
784
EXPORT_SYMBOL (mntput );
@@ -815,33 +791,6 @@ struct vfsmount *mntget(struct vfsmount *mnt)
815
791
}
816
792
EXPORT_SYMBOL (mntget );
817
793
818
- void mntput_long (struct vfsmount * mnt )
819
- {
820
- #ifdef CONFIG_SMP
821
- if (mnt ) {
822
- /* avoid cacheline pingpong, hope gcc doesn't get "smart" */
823
- if (unlikely (mnt -> mnt_expiry_mark ))
824
- mnt -> mnt_expiry_mark = 0 ;
825
- __mntput (mnt , 1 );
826
- }
827
- #else
828
- mntput (mnt );
829
- #endif
830
- }
831
- EXPORT_SYMBOL (mntput_long );
832
-
833
- struct vfsmount * mntget_long (struct vfsmount * mnt )
834
- {
835
- #ifdef CONFIG_SMP
836
- if (mnt )
837
- atomic_inc (& mnt -> mnt_longrefs );
838
- return mnt ;
839
- #else
840
- return mntget (mnt );
841
- #endif
842
- }
843
- EXPORT_SYMBOL (mntget_long );
844
-
845
794
void mnt_pin (struct vfsmount * mnt )
846
795
{
847
796
br_write_lock (vfsmount_lock );
@@ -1216,7 +1165,7 @@ void release_mounts(struct list_head *head)
1216
1165
dput (dentry );
1217
1166
mntput (m );
1218
1167
}
1219
- mntput_long (mnt );
1168
+ mntput (mnt );
1220
1169
}
1221
1170
}
1222
1171
@@ -1240,6 +1189,7 @@ void umount_tree(struct vfsmount *mnt, int propagate, struct list_head *kill)
1240
1189
list_del_init (& p -> mnt_list );
1241
1190
__touch_mnt_namespace (p -> mnt_ns );
1242
1191
p -> mnt_ns = NULL ;
1192
+ atomic_dec (& p -> mnt_longterm );
1243
1193
list_del_init (& p -> mnt_child );
1244
1194
if (p -> mnt_parent != p ) {
1245
1195
p -> mnt_parent -> mnt_ghosts ++ ;
@@ -1969,7 +1919,7 @@ int do_add_mount(struct vfsmount *newmnt, struct path *path, int mnt_flags)
1969
1919
1970
1920
unlock :
1971
1921
up_write (& namespace_sem );
1972
- mntput_long (newmnt );
1922
+ mntput (newmnt );
1973
1923
return err ;
1974
1924
}
1975
1925
@@ -2291,6 +2241,20 @@ static struct mnt_namespace *alloc_mnt_ns(void)
2291
2241
return new_ns ;
2292
2242
}
2293
2243
2244
+ void mnt_make_longterm (struct vfsmount * mnt )
2245
+ {
2246
+ atomic_inc (& mnt -> mnt_longterm );
2247
+ }
2248
+
2249
+ void mnt_make_shortterm (struct vfsmount * mnt )
2250
+ {
2251
+ if (atomic_add_unless (& mnt -> mnt_longterm , -1 , 1 ))
2252
+ return ;
2253
+ br_write_lock (vfsmount_lock );
2254
+ atomic_dec (& mnt -> mnt_longterm );
2255
+ br_write_unlock (vfsmount_lock );
2256
+ }
2257
+
2294
2258
/*
2295
2259
* Allocate a new namespace structure and populate it with contents
2296
2260
* copied from the namespace of the passed in task structure.
@@ -2328,14 +2292,19 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
2328
2292
q = new_ns -> root ;
2329
2293
while (p ) {
2330
2294
q -> mnt_ns = new_ns ;
2295
+ atomic_inc (& q -> mnt_longterm );
2331
2296
if (fs ) {
2332
2297
if (p == fs -> root .mnt ) {
2298
+ fs -> root .mnt = mntget (q );
2299
+ atomic_inc (& q -> mnt_longterm );
2300
+ mnt_make_shortterm (p );
2333
2301
rootmnt = p ;
2334
- fs -> root .mnt = mntget_long (q );
2335
2302
}
2336
2303
if (p == fs -> pwd .mnt ) {
2304
+ fs -> pwd .mnt = mntget (q );
2305
+ atomic_inc (& q -> mnt_longterm );
2306
+ mnt_make_shortterm (p );
2337
2307
pwdmnt = p ;
2338
- fs -> pwd .mnt = mntget_long (q );
2339
2308
}
2340
2309
}
2341
2310
p = next_mnt (p , mnt_ns -> root );
@@ -2344,9 +2313,9 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
2344
2313
up_write (& namespace_sem );
2345
2314
2346
2315
if (rootmnt )
2347
- mntput_long (rootmnt );
2316
+ mntput (rootmnt );
2348
2317
if (pwdmnt )
2349
- mntput_long (pwdmnt );
2318
+ mntput (pwdmnt );
2350
2319
2351
2320
return new_ns ;
2352
2321
}
@@ -2379,6 +2348,7 @@ struct mnt_namespace *create_mnt_ns(struct vfsmount *mnt)
2379
2348
new_ns = alloc_mnt_ns ();
2380
2349
if (!IS_ERR (new_ns )) {
2381
2350
mnt -> mnt_ns = new_ns ;
2351
+ atomic_inc (& mnt -> mnt_longterm );
2382
2352
new_ns -> root = mnt ;
2383
2353
list_add (& new_ns -> list , & new_ns -> root -> mnt_list );
2384
2354
}
0 commit comments