···2121 char *(*d_dname)((struct dentry *dentry, char *buffer, int buflen);22222323locking rules:2424- dcache_lock rename_lock ->d_lock may block2525-d_revalidate: no no no yes2626-d_hash no no no no2727-d_compare: no yes no no 2828-d_delete: yes no yes no2929-d_release: no no no yes3030-d_iput: no no no yes3131-d_dname: no no no no2424+ rename_lock ->d_lock may block2525+d_revalidate: no no yes2626+d_hash no no no2727+d_compare: yes no no2828+d_delete: no yes no2929+d_release: no no yes3030+d_iput: no no yes3131+d_dname: no no no32323333--------------------------- inode_operations --------------------------- 3434prototypes:
+18-20
Documentation/filesystems/dentry-locking.txt
···3131doesn't acquire the dcache_lock for this and rely on RCU to ensure3232that the dentry has not been *freed*.33333434+dcache_lock no longer exists, dentry locking is explained in fs/dcache.c34353536Dcache locking details3637======================···51505251Dcache is a complex data structure with the hash table entries also5352linked together in other lists. In 2.4 kernel, dcache_lock protected5454-all the lists. We applied RCU only on hash chain walking. The rest of5555-the lists are still protected by dcache_lock. Some of the important5656-changes are :5353+all the lists. RCU dentry hash walking works like this:575458551. The deletion from hash chain is done using hlist_del_rcu() macro5956 which doesn't initialize next pointer of the deleted dentry and6057 this allows us to walk safely lock-free while a deletion is6161- happening.5858+ happening. This is a standard hlist_rcu iteration.625963602. Insertion of a dentry into the hash table is done using6461 hlist_add_head_rcu() which take care of ordering the writes - the···6566 which has since been replaced by hlist_for_each_entry_rcu(), while6667 walking the hash chain. The only requirement is that all6768 initialization to the dentry must be done before6868- hlist_add_head_rcu() since we don't have dcache_lock protection6969- while traversing the hash chain. This isn't different from the7070- existing code.6969+ hlist_add_head_rcu() since we don't have lock protection7070+ while traversing the hash chain.71717272-3. The dentry looked up without holding dcache_lock by cannot be7373- returned for walking if it is unhashed. It then may have a NULL7474- d_inode or other bogosity since RCU doesn't protect the other7575- fields in the dentry. We therefore use a flag DCACHE_UNHASHED to7676- indicate unhashed dentries and use this in conjunction with a7777- per-dentry lock (d_lock). Once looked up without the dcache_lock,7878- we acquire the per-dentry lock (d_lock) and check if the dentry is7979- unhashed. If so, the look-up is failed. If not, the reference count8080- of the dentry is increased and the dentry is returned.7272+3. The dentry looked up without holding locks cannot be returned for7373+ walking if it is unhashed. It then may have a NULL d_inode or other7474+ bogosity since RCU doesn't protect the other fields in the dentry. We7575+ therefore use a flag DCACHE_UNHASHED to indicate unhashed dentries7676+ and use this in conjunction with a per-dentry lock (d_lock). Once7777+ looked up without locks, we acquire the per-dentry lock (d_lock) and7878+ check if the dentry is unhashed. If so, the look-up is failed. If not,7979+ the reference count of the dentry is increased and the dentry is8080+ returned.818182824. Once a dentry is looked up, it must be ensured during the path walk8383 for that component it doesn't go away. In pre-2.5.10 code, this was···8486 In some sense, dcache_rcu path walking looks like the pre-2.5.108587 version.86888787-5. All dentry hash chain updates must take the dcache_lock as well as8888- the per-dentry lock in that order. dput() does this to ensure that8989- a dentry that has just been looked up in another CPU doesn't get9090- deleted before dget() can be done on it.8989+5. All dentry hash chain updates must take the per-dentry lock (see9090+ fs/dcache.c). This excludes dput() to ensure that a dentry that has9191+ been looked up concurrently does not get deleted before dget() can9292+ take a ref.919392946. There are several ways to do reference counting of RCU protected9395 objects. One such example is in ipv4 route cache where deferred
+7-1
Documentation/filesystems/porting
···216216->d_parent changes are not protected by BKL anymore. Read access is safe217217if at least one of the following is true:218218 * filesystem has no cross-directory rename()219219- * dcache_lock is held220219 * we know that parent had been locked (e.g. we are looking at221220->d_parent of ->lookup() argument).222221 * we are called from ->rename().···339340 .d_hash() calling convention and locking rules are significantly340341changed. Read updated documentation in Documentation/filesystems/vfs.txt (and341342look at examples of other filesystems) for guidance.343343+344344+---345345+[mandatory]346346+ dcache_lock is gone, replaced by fine grained locks. See fs/dcache.c347347+for details of what locks to replace dcache_lock with in order to protect348348+particular things. Most of the time, a filesystem only needs ->d_lock, which349349+protects *all* the dcache state of a given dentry.
+1-4
arch/powerpc/platforms/cell/spufs/inode.c
···159159160160 mutex_lock(&dir->d_inode->i_mutex);161161 list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_u.d_child) {162162- spin_lock(&dcache_lock);163162 spin_lock(&dentry->d_lock);164163 if (!(d_unhashed(dentry)) && dentry->d_inode) {165164 dget_locked_dlock(dentry);166165 __d_drop(dentry);167166 spin_unlock(&dentry->d_lock);168167 simple_unlink(dir->d_inode, dentry);169169- /* XXX: what is dcache_lock protecting here? Other168168+ /* XXX: what was dcache_lock protecting here? Other170169 * filesystems (IB, configfs) release dcache_lock171170 * before unlink */172172- spin_unlock(&dcache_lock);173171 dput(dentry);174172 } else {175173 spin_unlock(&dentry->d_lock);176176- spin_unlock(&dcache_lock);177174 }178175 }179176 shrink_dcache_parent(dir);
···270270{271271 struct dentry *dentry;272272273273- spin_lock(&dcache_lock);274273 spin_lock(&dcache_inode_lock);275274 /* Directory should have only one entry. */276275 BUG_ON(S_ISDIR(inode->i_mode) && !list_is_singular(&inode->i_dentry));277276 dentry = list_entry(inode->i_dentry.next, struct dentry, d_alias);278277 spin_unlock(&dcache_inode_lock);279279- spin_unlock(&dcache_lock);280278 return dentry;281279}282280
-2
fs/affs/amigaffs.c
···128128 void *data = dentry->d_fsdata;129129 struct list_head *head, *next;130130131131- spin_lock(&dcache_lock);132131 spin_lock(&dcache_inode_lock);133132 head = &inode->i_dentry;134133 next = head->next;···140141 next = next->next;141142 }142143 spin_unlock(&dcache_inode_lock);143143- spin_unlock(&dcache_lock);144144}145145146146
+3
fs/autofs4/autofs_i.h
···1616#include <linux/auto_fs4.h>1717#include <linux/auto_dev-ioctl.h>1818#include <linux/mutex.h>1919+#include <linux/spinlock.h>1920#include <linux/list.h>20212122/* This is the range of ioctl() numbers we claim as ours */···6059 printk(KERN_ERR "pid %d: %s: " fmt "\n", \6160 current->pid, __func__, ##args); \6261} while (0)6262+6363+extern spinlock_t autofs4_lock;63646465/* Unified info structure. This is pointed to by both the dentry and6566 inode structures. Each file in the filesystem has an instance of this
···23232424#include "autofs_i.h"25252626+DEFINE_SPINLOCK(autofs4_lock);2727+2628static int autofs4_dir_symlink(struct inode *,struct dentry *,const char *);2729static int autofs4_dir_unlink(struct inode *,struct dentry *);2830static int autofs4_dir_rmdir(struct inode *,struct dentry *);···144142 * autofs file system so just let the libfs routines handle145143 * it.146144 */147147- spin_lock(&dcache_lock);145145+ spin_lock(&autofs4_lock);148146 spin_lock(&dentry->d_lock);149147 if (!d_mountpoint(dentry) && list_empty(&dentry->d_subdirs)) {150148 spin_unlock(&dentry->d_lock);151151- spin_unlock(&dcache_lock);149149+ spin_unlock(&autofs4_lock);152150 return -ENOENT;153151 }154152 spin_unlock(&dentry->d_lock);155155- spin_unlock(&dcache_lock);153153+ spin_unlock(&autofs4_lock);156154157155out:158156 return dcache_dir_open(inode, file);···257255 /* We trigger a mount for almost all flags */258256 lookup_type = autofs4_need_mount(nd->flags);259257 spin_lock(&sbi->fs_lock);260260- spin_lock(&dcache_lock);258258+ spin_lock(&autofs4_lock);261259 spin_lock(&dentry->d_lock);262260 if (!(lookup_type || ino->flags & AUTOFS_INF_PENDING)) {263261 spin_unlock(&dentry->d_lock);264264- spin_unlock(&dcache_lock);262262+ spin_unlock(&autofs4_lock);265263 spin_unlock(&sbi->fs_lock);266264 goto follow;267265 }···274272 if (ino->flags & AUTOFS_INF_PENDING ||275273 (!d_mountpoint(dentry) && list_empty(&dentry->d_subdirs))) {276274 spin_unlock(&dentry->d_lock);277277- spin_unlock(&dcache_lock);275275+ spin_unlock(&autofs4_lock);278276 spin_unlock(&sbi->fs_lock);279277280278 status = try_to_fill_dentry(dentry, nd->flags);···284282 goto follow;285283 }286284 spin_unlock(&dentry->d_lock);287287- spin_unlock(&dcache_lock);285285+ spin_unlock(&autofs4_lock);288286 spin_unlock(&sbi->fs_lock);289287follow:290288 /*···355353 return 0;356354357355 /* Check for a non-mountpoint directory with no contents */358358- spin_lock(&dcache_lock);356356+ spin_lock(&autofs4_lock);359357 spin_lock(&dentry->d_lock);360358 if (S_ISDIR(dentry->d_inode->i_mode) &&361359 !d_mountpoint(dentry) && list_empty(&dentry->d_subdirs)) {362360 DPRINTK("dentry=%p %.*s, emptydir",363361 dentry, dentry->d_name.len, dentry->d_name.name);364362 spin_unlock(&dentry->d_lock);365365- spin_unlock(&dcache_lock);363363+ spin_unlock(&autofs4_lock);366364367365 /* The daemon never causes a mount to trigger */368366 if (oz_mode)···379377 return status;380378 }381379 spin_unlock(&dentry->d_lock);382382- spin_unlock(&dcache_lock);380380+ spin_unlock(&autofs4_lock);383381384382 return 1;385383}···434432 const unsigned char *str = name->name;435433 struct list_head *p, *head;436434437437- spin_lock(&dcache_lock);435435+ spin_lock(&autofs4_lock);438436 spin_lock(&sbi->lookup_lock);439437 head = &sbi->active_list;440438 list_for_each(p, head) {···467465 dget_dlock(active);468466 spin_unlock(&active->d_lock);469467 spin_unlock(&sbi->lookup_lock);470470- spin_unlock(&dcache_lock);468468+ spin_unlock(&autofs4_lock);471469 return active;472470 }473471next:474472 spin_unlock(&active->d_lock);475473 }476474 spin_unlock(&sbi->lookup_lock);477477- spin_unlock(&dcache_lock);475475+ spin_unlock(&autofs4_lock);478476479477 return NULL;480478}···489487 const unsigned char *str = name->name;490488 struct list_head *p, *head;491489492492- spin_lock(&dcache_lock);490490+ spin_lock(&autofs4_lock);493491 spin_lock(&sbi->lookup_lock);494492 head = &sbi->expiring_list;495493 list_for_each(p, head) {···522520 dget_dlock(expiring);523521 spin_unlock(&expiring->d_lock);524522 spin_unlock(&sbi->lookup_lock);525525- spin_unlock(&dcache_lock);523523+ spin_unlock(&autofs4_lock);526524 return expiring;527525 }528526next:529527 spin_unlock(&expiring->d_lock);530528 }531529 spin_unlock(&sbi->lookup_lock);532532- spin_unlock(&dcache_lock);530530+ spin_unlock(&autofs4_lock);533531534532 return NULL;535533}···765763766764 dir->i_mtime = CURRENT_TIME;767765768768- spin_lock(&dcache_lock);766766+ spin_lock(&autofs4_lock);769767 autofs4_add_expiring(dentry);770768 spin_lock(&dentry->d_lock);771769 __d_drop(dentry);772770 spin_unlock(&dentry->d_lock);773773- spin_unlock(&dcache_lock);771771+ spin_unlock(&autofs4_lock);774772775773 return 0;776774}···787785 if (!autofs4_oz_mode(sbi))788786 return -EACCES;789787790790- spin_lock(&dcache_lock);788788+ spin_lock(&autofs4_lock);791789 spin_lock(&sbi->lookup_lock);792790 spin_lock(&dentry->d_lock);793791 if (!list_empty(&dentry->d_subdirs)) {794792 spin_unlock(&dentry->d_lock);795793 spin_unlock(&sbi->lookup_lock);796796- spin_unlock(&dcache_lock);794794+ spin_unlock(&autofs4_lock);797795 return -ENOTEMPTY;798796 }799797 __autofs4_add_expiring(dentry);800798 spin_unlock(&sbi->lookup_lock);801799 __d_drop(dentry);802800 spin_unlock(&dentry->d_lock);803803- spin_unlock(&dcache_lock);801801+ spin_unlock(&autofs4_lock);804802805803 if (atomic_dec_and_test(&ino->count)) {806804 p_ino = autofs4_dentry_ino(dentry->d_parent);
+4-3
fs/autofs4/waitq.c
···194194rename_retry:195195 buf = *name;196196 len = 0;197197+197198 seq = read_seqbegin(&rename_lock);198199 rcu_read_lock();199199- spin_lock(&dcache_lock);200200+ spin_lock(&autofs4_lock);200201 for (tmp = dentry ; tmp != root ; tmp = tmp->d_parent)201202 len += tmp->d_name.len + 1;202203203204 if (!len || --len > NAME_MAX) {204204- spin_unlock(&dcache_lock);205205+ spin_unlock(&autofs4_lock);205206 rcu_read_unlock();206207 if (read_seqretry(&rename_lock, seq))207208 goto rename_retry;···218217 p -= tmp->d_name.len;219218 strncpy(p, tmp->d_name.name, tmp->d_name.len);220219 }221221- spin_unlock(&dcache_lock);220220+ spin_unlock(&autofs4_lock);222221 rcu_read_unlock();223222 if (read_seqretry(&rename_lock, seq))224223 goto rename_retry;
+1-5
fs/ceph/dir.c
···112112 dout("__dcache_readdir %p at %llu (last %p)\n", dir, filp->f_pos,113113 last);114114115115- spin_lock(&dcache_lock);116115 spin_lock(&parent->d_lock);117116118117 /* start at beginning? */···155156 dget_dlock(dentry);156157 spin_unlock(&dentry->d_lock);157158 spin_unlock(&parent->d_lock);158158- spin_unlock(&dcache_lock);159159160160 dout(" %llu (%llu) dentry %p %.*s %p\n", di->offset, filp->f_pos,161161 dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_inode);···180182181183 filp->f_pos++;182184183183- /* make sure a dentry wasn't dropped while we didn't have dcache_lock */185185+ /* make sure a dentry wasn't dropped while we didn't have parent lock */184186 if (!ceph_i_test(dir, CEPH_I_COMPLETE)) {185187 dout(" lost I_COMPLETE on %p; falling back to mds\n", dir);186188 err = -EAGAIN;187189 goto out;188190 }189191190190- spin_lock(&dcache_lock);191192 spin_lock(&parent->d_lock);192193 p = p->prev; /* advance to next dentry */193194 goto more;194195195196out_unlock:196197 spin_unlock(&parent->d_lock);197197- spin_unlock(&dcache_lock);198198out:199199 if (last)200200 dput(last);
···5454 * - d_alias, d_inode5555 *5656 * Ordering:5757- * dcache_lock5858- * dcache_inode_lock5959- * dentry->d_lock6060- * dcache_lru_lock6161- * dcache_hash_lock5757+ * dcache_inode_lock5858+ * dentry->d_lock5959+ * dcache_lru_lock6060+ * dcache_hash_lock6261 *6362 * If there is an ancestor relationship:6463 * dentry->d_parent->...->d_parent->d_lock···7677__cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_inode_lock);7778static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_hash_lock);7879static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_lru_lock);7979-__cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_lock);8080__cacheline_aligned_in_smp DEFINE_SEQLOCK(rename_lock);81818282EXPORT_SYMBOL(rename_lock);8383EXPORT_SYMBOL(dcache_inode_lock);8484-EXPORT_SYMBOL(dcache_lock);85848685static struct kmem_cache *dentry_cache __read_mostly;8786···136139}137140138141/*139139- * no dcache_lock, please.142142+ * no locks, please.140143 */141144static void d_free(struct dentry *dentry)142145{···159162static void dentry_iput(struct dentry * dentry)160163 __releases(dentry->d_lock)161164 __releases(dcache_inode_lock)162162- __releases(dcache_lock)163165{164166 struct inode *inode = dentry->d_inode;165167 if (inode) {···166170 list_del_init(&dentry->d_alias);167171 spin_unlock(&dentry->d_lock);168172 spin_unlock(&dcache_inode_lock);169169- spin_unlock(&dcache_lock);170173 if (!inode->i_nlink)171174 fsnotify_inoderemove(inode);172175 if (dentry->d_op && dentry->d_op->d_iput)···175180 } else {176181 spin_unlock(&dentry->d_lock);177182 spin_unlock(&dcache_inode_lock);178178- spin_unlock(&dcache_lock);179183 }180184}181185···229235 *230236 * If this is the root of the dentry tree, return NULL.231237 *232232- * dcache_lock and d_lock and d_parent->d_lock must be held by caller, and233233- * are dropped by d_kill.238238+ * dentry->d_lock and parent->d_lock must be held by caller, and are dropped by239239+ * d_kill.234240 */235241static struct dentry *d_kill(struct dentry *dentry, struct dentry *parent)236242 __releases(dentry->d_lock)237243 __releases(parent->d_lock)238244 __releases(dcache_inode_lock)239239- __releases(dcache_lock)240245{241246 dentry->d_parent = NULL;242247 list_del(&dentry->d_u.d_child);···278285279286void d_drop(struct dentry *dentry)280287{281281- spin_lock(&dcache_lock);282288 spin_lock(&dentry->d_lock);283289 __d_drop(dentry);284290 spin_unlock(&dentry->d_lock);285285- spin_unlock(&dcache_lock);286291}287292EXPORT_SYMBOL(d_drop);288293···328337 else329338 parent = dentry->d_parent;330339 if (dentry->d_count == 1) {331331- if (!spin_trylock(&dcache_lock)) {332332- /*333333- * Something of a livelock possibility we could avoid334334- * by taking dcache_lock and trying again, but we335335- * want to reduce dcache_lock anyway so this will336336- * get improved.337337- */338338-drop1:339339- spin_unlock(&dentry->d_lock);340340- goto repeat;341341- }342340 if (!spin_trylock(&dcache_inode_lock)) {343341drop2:344344- spin_unlock(&dcache_lock);345345- goto drop1;342342+ spin_unlock(&dentry->d_lock);343343+ goto repeat;346344 }347345 if (parent && !spin_trylock(&parent->d_lock)) {348346 spin_unlock(&dcache_inode_lock);···343363 spin_unlock(&dentry->d_lock);344364 if (parent)345365 spin_unlock(&parent->d_lock);346346- spin_unlock(&dcache_lock);347366 return;348367 }349368···366387 if (parent)367388 spin_unlock(&parent->d_lock);368389 spin_unlock(&dcache_inode_lock);369369- spin_unlock(&dcache_lock);370390 return;371391372392unhash_it:···396418 /*397419 * If it's already been dropped, return OK.398420 */399399- spin_lock(&dcache_lock);400421 spin_lock(&dentry->d_lock);401422 if (d_unhashed(dentry)) {402423 spin_unlock(&dentry->d_lock);403403- spin_unlock(&dcache_lock);404424 return 0;405425 }406426 /*···407431 */408432 if (!list_empty(&dentry->d_subdirs)) {409433 spin_unlock(&dentry->d_lock);410410- spin_unlock(&dcache_lock);411434 shrink_dcache_parent(dentry);412412- spin_lock(&dcache_lock);413435 spin_lock(&dentry->d_lock);414436 }415437···424450 if (dentry->d_count > 1) {425451 if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode)) {426452 spin_unlock(&dentry->d_lock);427427- spin_unlock(&dcache_lock);428453 return -EBUSY;429454 }430455 }431456432457 __d_drop(dentry);433458 spin_unlock(&dentry->d_lock);434434- spin_unlock(&dcache_lock);435459 return 0;436460}437461EXPORT_SYMBOL(d_invalidate);438462439439-/* This must be called with dcache_lock and d_lock held */463463+/* This must be called with d_lock held */440464static inline struct dentry * __dget_locked_dlock(struct dentry *dentry)441465{442466 dentry->d_count++;···442470 return dentry;443471}444472445445-/* This should be called _only_ with dcache_lock held */473473+/* This must be called with d_lock held */446474static inline struct dentry * __dget_locked(struct dentry *dentry)447475{448476 spin_lock(&dentry->d_lock);···547575 struct dentry *de = NULL;548576549577 if (!list_empty(&inode->i_dentry)) {550550- spin_lock(&dcache_lock);551578 spin_lock(&dcache_inode_lock);552579 de = __d_find_alias(inode, 0);553580 spin_unlock(&dcache_inode_lock);554554- spin_unlock(&dcache_lock);555581 }556582 return de;557583}···563593{564594 struct dentry *dentry;565595restart:566566- spin_lock(&dcache_lock);567596 spin_lock(&dcache_inode_lock);568597 list_for_each_entry(dentry, &inode->i_dentry, d_alias) {569598 spin_lock(&dentry->d_lock);···571602 __d_drop(dentry);572603 spin_unlock(&dentry->d_lock);573604 spin_unlock(&dcache_inode_lock);574574- spin_unlock(&dcache_lock);575605 dput(dentry);576606 goto restart;577607 }578608 spin_unlock(&dentry->d_lock);579609 }580610 spin_unlock(&dcache_inode_lock);581581- spin_unlock(&dcache_lock);582611}583612EXPORT_SYMBOL(d_prune_aliases);584613···592625 __releases(dentry->d_lock)593626 __releases(parent->d_lock)594627 __releases(dcache_inode_lock)595595- __releases(dcache_lock)596628{597629 __d_drop(dentry);598630 dentry = d_kill(dentry, parent);599631600632 /*601601- * Prune ancestors. Locking is simpler than in dput(),602602- * because dcache_lock needs to be taken anyway.633633+ * Prune ancestors.603634 */604635 while (dentry) {605605- spin_lock(&dcache_lock);606636 spin_lock(&dcache_inode_lock);607637again:608638 spin_lock(&dentry->d_lock);···617653 spin_unlock(&parent->d_lock);618654 spin_unlock(&dentry->d_lock);619655 spin_unlock(&dcache_inode_lock);620620- spin_unlock(&dcache_lock);621656 return;622657 }623658···665702 spin_unlock(&dcache_lru_lock);666703667704 prune_one_dentry(dentry, parent);668668- /* dcache_lock, dcache_inode_lock and dentry->d_lock dropped */669669- spin_lock(&dcache_lock);705705+ /* dcache_inode_lock and dentry->d_lock dropped */670706 spin_lock(&dcache_inode_lock);671707 spin_lock(&dcache_lru_lock);672708 }···687725 LIST_HEAD(tmp);688726 int cnt = *count;689727690690- spin_lock(&dcache_lock);691728 spin_lock(&dcache_inode_lock);692729relock:693730 spin_lock(&dcache_lru_lock);···727766 list_splice(&referenced, &sb->s_dentry_lru);728767 spin_unlock(&dcache_lru_lock);729768 spin_unlock(&dcache_inode_lock);730730- spin_unlock(&dcache_lock);731769}732770733771/**···748788749789 if (unused == 0 || count == 0)750790 return;751751- spin_lock(&dcache_lock);752791 if (count >= unused)753792 prune_ratio = 1;754793 else···784825 if (down_read_trylock(&sb->s_umount)) {785826 if ((sb->s_root != NULL) &&786827 (!list_empty(&sb->s_dentry_lru))) {787787- spin_unlock(&dcache_lock);788828 __shrink_dcache_sb(sb, &w_count,789829 DCACHE_REFERENCED);790830 pruned -= w_count;791791- spin_lock(&dcache_lock);792831 }793832 up_read(&sb->s_umount);794833 }···802845 if (p)803846 __put_super(p);804847 spin_unlock(&sb_lock);805805- spin_unlock(&dcache_lock);806848}807849808850/**···815859{816860 LIST_HEAD(tmp);817861818818- spin_lock(&dcache_lock);819862 spin_lock(&dcache_inode_lock);820863 spin_lock(&dcache_lru_lock);821864 while (!list_empty(&sb->s_dentry_lru)) {···823868 }824869 spin_unlock(&dcache_lru_lock);825870 spin_unlock(&dcache_inode_lock);826826- spin_unlock(&dcache_lock);827871}828872EXPORT_SYMBOL(shrink_dcache_sb);829873···839885 BUG_ON(!IS_ROOT(dentry));840886841887 /* detach this root from the system */842842- spin_lock(&dcache_lock);843888 spin_lock(&dentry->d_lock);844889 dentry_lru_del(dentry);845890 __d_drop(dentry);846891 spin_unlock(&dentry->d_lock);847847- spin_unlock(&dcache_lock);848892849893 for (;;) {850894 /* descend to the first leaf in the current subtree */···851899852900 /* this is a branch with children - detach all of them853901 * from the system in one go */854854- spin_lock(&dcache_lock);855902 spin_lock(&dentry->d_lock);856903 list_for_each_entry(loop, &dentry->d_subdirs,857904 d_u.d_child) {···861910 spin_unlock(&loop->d_lock);862911 }863912 spin_unlock(&dentry->d_lock);864864- spin_unlock(&dcache_lock);865913866914 /* move to the first child */867915 dentry = list_entry(dentry->d_subdirs.next,···927977928978/*929979 * destroy the dentries attached to a superblock on unmounting930930- * - we don't need to use dentry->d_lock, and only need dcache_lock when931931- * removing the dentry from the system lists and hashes because:980980+ * - we don't need to use dentry->d_lock because:932981 * - the superblock is detached from all mountings and open files, so the933982 * dentry trees will not be rearranged by the VFS934983 * - s_umount is write-locked, so the memory pressure shrinker will ignore···9781029 this_parent = parent;9791030 seq = read_seqbegin(&rename_lock);9801031981981- spin_lock(&dcache_lock);9821032 if (d_mountpoint(parent))9831033 goto positive;9841034 spin_lock(&this_parent->d_lock);···10231075 if (this_parent != child->d_parent ||10241076 read_seqretry(&rename_lock, seq)) {10251077 spin_unlock(&this_parent->d_lock);10261026- spin_unlock(&dcache_lock);10271078 rcu_read_unlock();10281079 goto rename_retry;10291080 }···10311084 goto resume;10321085 }10331086 spin_unlock(&this_parent->d_lock);10341034- spin_unlock(&dcache_lock);10351087 if (read_seqretry(&rename_lock, seq))10361088 goto rename_retry;10371089 return 0; /* No mount points found in tree */10381090positive:10391039- spin_unlock(&dcache_lock);10401091 if (read_seqretry(&rename_lock, seq))10411092 goto rename_retry;10421093 return 1;···10661121 this_parent = parent;10671122 seq = read_seqbegin(&rename_lock);1068112310691069- spin_lock(&dcache_lock);10701124 spin_lock(&this_parent->d_lock);10711125repeat:10721126 next = this_parent->d_subdirs.next;···11291185 if (this_parent != child->d_parent ||11301186 read_seqretry(&rename_lock, seq)) {11311187 spin_unlock(&this_parent->d_lock);11321132- spin_unlock(&dcache_lock);11331188 rcu_read_unlock();11341189 goto rename_retry;11351190 }···11381195 }11391196out:11401197 spin_unlock(&this_parent->d_lock);11411141- spin_unlock(&dcache_lock);11421198 if (read_seqretry(&rename_lock, seq))11431199 goto rename_retry;11441200 return found;···12391297 INIT_LIST_HEAD(&dentry->d_u.d_child);1240129812411299 if (parent) {12421242- spin_lock(&dcache_lock);12431300 spin_lock(&parent->d_lock);12441301 spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);12451302 dentry->d_parent = dget_dlock(parent);···12461305 list_add(&dentry->d_u.d_child, &parent->d_subdirs);12471306 spin_unlock(&dentry->d_lock);12481307 spin_unlock(&parent->d_lock);12491249- spin_unlock(&dcache_lock);12501308 }1251130912521310 this_cpu_inc(nr_dentry);···12651325}12661326EXPORT_SYMBOL(d_alloc_name);1267132712681268-/* the caller must hold dcache_lock */12691328static void __d_instantiate(struct dentry *dentry, struct inode *inode)12701329{12711330 spin_lock(&dentry->d_lock);···12931354void d_instantiate(struct dentry *entry, struct inode * inode)12941355{12951356 BUG_ON(!list_empty(&entry->d_alias));12961296- spin_lock(&dcache_lock);12971357 spin_lock(&dcache_inode_lock);12981358 __d_instantiate(entry, inode);12991359 spin_unlock(&dcache_inode_lock);13001300- spin_unlock(&dcache_lock);13011360 security_d_instantiate(entry, inode);13021361}13031362EXPORT_SYMBOL(d_instantiate);···1359142213601423 BUG_ON(!list_empty(&entry->d_alias));1361142413621362- spin_lock(&dcache_lock);13631425 spin_lock(&dcache_inode_lock);13641426 result = __d_instantiate_unique(entry, inode);13651427 spin_unlock(&dcache_inode_lock);13661366- spin_unlock(&dcache_lock);1367142813681429 if (!result) {13691430 security_d_instantiate(entry, inode);···14501515 }14511516 tmp->d_parent = tmp; /* make sure dput doesn't croak */1452151714531453- spin_lock(&dcache_lock);15181518+14541519 spin_lock(&dcache_inode_lock);14551520 res = __d_find_alias(inode, 0);14561521 if (res) {14571522 spin_unlock(&dcache_inode_lock);14581458- spin_unlock(&dcache_lock);14591523 dput(tmp);14601524 goto out_iput;14611525 }···14721538 spin_unlock(&tmp->d_lock);14731539 spin_unlock(&dcache_inode_lock);1474154014751475- spin_unlock(&dcache_lock);14761541 return tmp;1477154214781543 out_iput:···15011568 struct dentry *new = NULL;1502156915031570 if (inode && S_ISDIR(inode->i_mode)) {15041504- spin_lock(&dcache_lock);15051571 spin_lock(&dcache_inode_lock);15061572 new = __d_find_alias(inode, 1);15071573 if (new) {15081574 BUG_ON(!(new->d_flags & DCACHE_DISCONNECTED));15091575 spin_unlock(&dcache_inode_lock);15101510- spin_unlock(&dcache_lock);15111576 security_d_instantiate(new, inode);15121577 d_move(new, dentry);15131578 iput(inode);15141579 } else {15151515- /* already taking dcache_lock, so d_add() by hand */15801580+ /* already taking dcache_inode_lock, so d_add() by hand */15161581 __d_instantiate(dentry, inode);15171582 spin_unlock(&dcache_inode_lock);15181518- spin_unlock(&dcache_lock);15191583 security_d_instantiate(dentry, inode);15201584 d_rehash(dentry);15211585 }···15851655 * Negative dentry: instantiate it unless the inode is a directory and15861656 * already has a dentry.15871657 */15881588- spin_lock(&dcache_lock);15891658 spin_lock(&dcache_inode_lock);15901659 if (!S_ISDIR(inode->i_mode) || list_empty(&inode->i_dentry)) {15911660 __d_instantiate(found, inode);15921661 spin_unlock(&dcache_inode_lock);15931593- spin_unlock(&dcache_lock);15941662 security_d_instantiate(found, inode);15951663 return found;15961664 }···16001672 new = list_entry(inode->i_dentry.next, struct dentry, d_alias);16011673 dget_locked(new);16021674 spin_unlock(&dcache_inode_lock);16031603- spin_unlock(&dcache_lock);16041675 security_d_instantiate(found, inode);16051676 d_move(new, found);16061677 iput(inode);···17701843{17711844 struct dentry *child;1772184517731773- spin_lock(&dcache_lock);17741846 spin_lock(&dparent->d_lock);17751847 list_for_each_entry(child, &dparent->d_subdirs, d_u.d_child) {17761848 if (dentry == child) {···17771851 __dget_locked_dlock(dentry);17781852 spin_unlock(&dentry->d_lock);17791853 spin_unlock(&dparent->d_lock);17801780- spin_unlock(&dcache_lock);17811854 return 1;17821855 }17831856 }17841857 spin_unlock(&dparent->d_lock);17851785- spin_unlock(&dcache_lock);1786185817871859 return 0;17881860}···18131889 /*18141890 * Are we the only user?18151891 */18161816- spin_lock(&dcache_lock);18171892 spin_lock(&dcache_inode_lock);18181893 spin_lock(&dentry->d_lock);18191894 isdir = S_ISDIR(dentry->d_inode->i_mode);···1828190518291906 spin_unlock(&dentry->d_lock);18301907 spin_unlock(&dcache_inode_lock);18311831- spin_unlock(&dcache_lock);1832190818331909 fsnotify_nameremove(dentry, isdir);18341910}···1854193218551933void d_rehash(struct dentry * entry)18561934{18571857- spin_lock(&dcache_lock);18581935 spin_lock(&entry->d_lock);18591936 spin_lock(&dcache_hash_lock);18601937 _d_rehash(entry);18611938 spin_unlock(&dcache_hash_lock);18621939 spin_unlock(&entry->d_lock);18631863- spin_unlock(&dcache_lock);18641940}18651941EXPORT_SYMBOL(d_rehash);18661942···18811961 BUG_ON(!mutex_is_locked(&dentry->d_inode->i_mutex));18821962 BUG_ON(dentry->d_name.len != name->len); /* d_lookup gives this */1883196318841884- spin_lock(&dcache_lock);18851964 spin_lock(&dentry->d_lock);18861965 memcpy((unsigned char *)dentry->d_name.name, name->name, name->len);18871966 spin_unlock(&dentry->d_lock);18881888- spin_unlock(&dcache_lock);18891967}18901968EXPORT_SYMBOL(dentry_update_name_case);18911969···19762058 * The hash value has to match the hash queue that the dentry is on..19772059 */19782060/*19791979- * d_move_locked - move a dentry20612061+ * d_move - move a dentry19802062 * @dentry: entry to move19812063 * @target: new dentry19822064 *19832065 * Update the dcache to reflect the move of a file name. Negative19842066 * dcache entries should not be moved in this way.19852067 */19861986-static void d_move_locked(struct dentry * dentry, struct dentry * target)20682068+void d_move(struct dentry * dentry, struct dentry * target)19872069{19882070 if (!dentry->d_inode)19892071 printk(KERN_WARNING "VFS: moving negative dcache entry\n");···20322114 spin_unlock(&dentry->d_lock);20332115 write_sequnlock(&rename_lock);20342116}20352035-20362036-/**20372037- * d_move - move a dentry20382038- * @dentry: entry to move20392039- * @target: new dentry20402040- *20412041- * Update the dcache to reflect the move of a file name. Negative20422042- * dcache entries should not be moved in this way.20432043- */20442044-20452045-void d_move(struct dentry * dentry, struct dentry * target)20462046-{20472047- spin_lock(&dcache_lock);20482048- d_move_locked(dentry, target);20492049- spin_unlock(&dcache_lock);20502050-}20512117EXPORT_SYMBOL(d_move);2052211820532119/**···20572155 * This helper attempts to cope with remotely renamed directories20582156 *20592157 * It assumes that the caller is already holding20602060- * dentry->d_parent->d_inode->i_mutex and the dcache_lock21582158+ * dentry->d_parent->d_inode->i_mutex and the dcache_inode_lock20612159 *20622160 * Note: If ever the locking in lock_rename() changes, then please20632161 * remember to update this too...20642162 */20652163static struct dentry *__d_unalias(struct dentry *dentry, struct dentry *alias)20662066- __releases(dcache_lock)20672164 __releases(dcache_inode_lock)20682165{20692166 struct mutex *m1 = NULL, *m2 = NULL;···20862185 goto out_err;20872186 m2 = &alias->d_parent->d_inode->i_mutex;20882187out_unalias:20892089- d_move_locked(alias, dentry);21882188+ d_move(alias, dentry);20902189 ret = alias;20912190out_err:20922191 spin_unlock(&dcache_inode_lock);20932093- spin_unlock(&dcache_lock);20942192 if (m2)20952193 mutex_unlock(m2);20962194 if (m1)···2149224921502250 BUG_ON(!d_unhashed(dentry));2151225121522152- spin_lock(&dcache_lock);21532252 spin_lock(&dcache_inode_lock);2154225321552254 if (!inode) {···21942295 spin_unlock(&dcache_hash_lock);21952296 spin_unlock(&actual->d_lock);21962297 spin_unlock(&dcache_inode_lock);21972197- spin_unlock(&dcache_lock);21982298out_nolock:21992299 if (actual == dentry) {22002300 security_d_instantiate(dentry, inode);···2205230722062308shouldnt_be_hashed:22072309 spin_unlock(&dcache_inode_lock);22082208- spin_unlock(&dcache_lock);22092310 BUG();22102311}22112312EXPORT_SYMBOL_GPL(d_materialise_unique);···23182421 int error;2319242223202423 prepend(&res, &buflen, "\0", 1);23212321- spin_lock(&dcache_lock);23222424 write_seqlock(&rename_lock);23232425 error = prepend_path(path, root, &res, &buflen);23242426 write_sequnlock(&rename_lock);23252325- spin_unlock(&dcache_lock);2326242723272428 if (error)23282429 return ERR_PTR(error);···23822487 return path->dentry->d_op->d_dname(path->dentry, buf, buflen);2383248823842489 get_fs_root(current->fs, &root);23852385- spin_lock(&dcache_lock);23862490 write_seqlock(&rename_lock);23872491 tmp = root;23882492 error = path_with_deleted(path, &tmp, &res, &buflen);23892493 if (error)23902494 res = ERR_PTR(error);23912495 write_sequnlock(&rename_lock);23922392- spin_unlock(&dcache_lock);23932496 path_put(&root);23942497 return res;23952498}···24132520 return path->dentry->d_op->d_dname(path->dentry, buf, buflen);2414252124152522 get_fs_root(current->fs, &root);24162416- spin_lock(&dcache_lock);24172523 write_seqlock(&rename_lock);24182524 tmp = root;24192525 error = path_with_deleted(path, &tmp, &res, &buflen);24202526 if (!error && !path_equal(&tmp, &root))24212527 error = prepend_unreachable(&res, &buflen);24222528 write_sequnlock(&rename_lock);24232423- spin_unlock(&dcache_lock);24242529 path_put(&root);24252530 if (error)24262531 res = ERR_PTR(error);···24852594{24862595 char *retval;2487259624882488- spin_lock(&dcache_lock);24892597 write_seqlock(&rename_lock);24902598 retval = __dentry_path(dentry, buf, buflen);24912599 write_sequnlock(&rename_lock);24922492- spin_unlock(&dcache_lock);2493260024942601 return retval;24952602}···24982609 char *p = NULL;24992610 char *retval;2500261125012501- spin_lock(&dcache_lock);25022612 write_seqlock(&rename_lock);25032613 if (d_unlinked(dentry)) {25042614 p = buf + buflen;···25072619 }25082620 retval = __dentry_path(dentry, buf, buflen);25092621 write_sequnlock(&rename_lock);25102510- spin_unlock(&dcache_lock);25112622 if (!IS_ERR(retval) && p)25122623 *p = '/'; /* restore '/' overriden with '\0' */25132624 return retval;25142625Elong:25152515- spin_unlock(&dcache_lock);25162626 return ERR_PTR(-ENAMETOOLONG);25172627}25182628···25442658 get_fs_root_and_pwd(current->fs, &root, &pwd);2545265925462660 error = -ENOENT;25472547- spin_lock(&dcache_lock);25482661 write_seqlock(&rename_lock);25492662 if (!d_unlinked(pwd.dentry)) {25502663 unsigned long len;···25542669 prepend(&cwd, &buflen, "\0", 1);25552670 error = prepend_path(&pwd, &tmp, &cwd, &buflen);25562671 write_sequnlock(&rename_lock);25572557- spin_unlock(&dcache_lock);2558267225592673 if (error)25602674 goto out;···25742690 }25752691 } else {25762692 write_sequnlock(&rename_lock);25772577- spin_unlock(&dcache_lock);25782693 }2579269425802695out:···26592776rename_retry:26602777 this_parent = root;26612778 seq = read_seqbegin(&rename_lock);26622662- spin_lock(&dcache_lock);26632779 spin_lock(&this_parent->d_lock);26642780repeat:26652781 next = this_parent->d_subdirs.next;···27052823 if (this_parent != child->d_parent ||27062824 read_seqretry(&rename_lock, seq)) {27072825 spin_unlock(&this_parent->d_lock);27082708- spin_unlock(&dcache_lock);27092826 rcu_read_unlock();27102827 goto rename_retry;27112828 }···27132832 goto resume;27142833 }27152834 spin_unlock(&this_parent->d_lock);27162716- spin_unlock(&dcache_lock);27172835 if (read_seqretry(&rename_lock, seq))27182836 goto rename_retry;27192837}
-4
fs/exportfs/expfs.c
···4747 if (acceptable(context, result))4848 return result;49495050- spin_lock(&dcache_lock);5150 spin_lock(&dcache_inode_lock);5251 list_for_each_entry(dentry, &result->d_inode->i_dentry, d_alias) {5352 dget_locked(dentry);5453 spin_unlock(&dcache_inode_lock);5555- spin_unlock(&dcache_lock);5654 if (toput)5755 dput(toput);5856 if (dentry != result && acceptable(context, dentry)) {5957 dput(result);6058 return dentry;6159 }6262- spin_lock(&dcache_lock);6360 spin_lock(&dcache_inode_lock);6461 toput = dentry;6562 }6663 spin_unlock(&dcache_inode_lock);6767- spin_unlock(&dcache_lock);68646965 if (toput)7066 dput(toput);
-8
fs/libfs.c
···100100 struct dentry *cursor = file->private_data;101101 loff_t n = file->f_pos - 2;102102103103- spin_lock(&dcache_lock);104103 spin_lock(&dentry->d_lock);105104 /* d_lock not required for cursor */106105 list_del(&cursor->d_u.d_child);···115116 }116117 list_add_tail(&cursor->d_u.d_child, p);117118 spin_unlock(&dentry->d_lock);118118- spin_unlock(&dcache_lock);119119 }120120 }121121 mutex_unlock(&dentry->d_inode->i_mutex);···157159 i++;158160 /* fallthrough */159161 default:160160- spin_lock(&dcache_lock);161162 spin_lock(&dentry->d_lock);162163 if (filp->f_pos == 2)163164 list_move(q, &dentry->d_subdirs);···172175173176 spin_unlock(&next->d_lock);174177 spin_unlock(&dentry->d_lock);175175- spin_unlock(&dcache_lock);176178 if (filldir(dirent, next->d_name.name, 177179 next->d_name.len, filp->f_pos, 178180 next->d_inode->i_ino, 179181 dt_type(next->d_inode)) < 0)180182 return 0;181181- spin_lock(&dcache_lock);182183 spin_lock(&dentry->d_lock);183184 spin_lock_nested(&next->d_lock, DENTRY_D_LOCK_NESTED);184185 /* next is still alive */···186191 filp->f_pos++;187192 }188193 spin_unlock(&dentry->d_lock);189189- spin_unlock(&dcache_lock);190194 }191195 return 0;192196}···279285 struct dentry *child;280286 int ret = 0;281287282282- spin_lock(&dcache_lock);283288 spin_lock(&dentry->d_lock);284289 list_for_each_entry(child, &dentry->d_subdirs, d_u.d_child) {285290 spin_lock_nested(&child->d_lock, DENTRY_D_LOCK_NESTED);···291298 ret = 1;292299out:293300 spin_unlock(&dentry->d_lock);294294- spin_unlock(&dcache_lock);295301 return ret;296302}297303
+2-7
fs/namei.c
···612612 return 1;613613}614614615615-/* no need for dcache_lock, as serialization is taken care in616616- * namespace.c615615+/*616616+ * serialization is taken care of in namespace.c617617 */618618static int __follow_mount(struct path *path)619619{···645645 }646646}647647648648-/* no need for dcache_lock, as serialization is taken care in649649- * namespace.c650650- */651648int follow_down(struct path *path)652649{653650 struct vfsmount *mounted;···21282131{21292132 dget(dentry);21302133 shrink_dcache_parent(dentry);21312131- spin_lock(&dcache_lock);21322134 spin_lock(&dentry->d_lock);21332135 if (dentry->d_count == 2)21342136 __d_drop(dentry);21352137 spin_unlock(&dentry->d_lock);21362136- spin_unlock(&dcache_lock);21372138}2138213921392140int vfs_rmdir(struct inode *dir, struct dentry *dentry)
-3
fs/ncpfs/dir.c
···391391 }392392393393 /* If a pointer is invalid, we search the dentry. */394394- spin_lock(&dcache_lock);395394 spin_lock(&parent->d_lock);396395 next = parent->d_subdirs.next;397396 while (next != &parent->d_subdirs) {···401402 else402403 dent = NULL;403404 spin_unlock(&parent->d_lock);404404- spin_unlock(&dcache_lock);405405 goto out;406406 }407407 next = next->next;408408 }409409 spin_unlock(&parent->d_lock);410410- spin_unlock(&dcache_lock);411410 return NULL;412411413412out:
-4
fs/ncpfs/ncplib_kernel.h
···193193 struct list_head *next;194194 struct dentry *dentry;195195196196- spin_lock(&dcache_lock);197196 spin_lock(&parent->d_lock);198197 next = parent->d_subdirs.next;199198 while (next != &parent->d_subdirs) {···206207 next = next->next;207208 }208209 spin_unlock(&parent->d_lock);209209- spin_unlock(&dcache_lock);210210}211211212212static inline void···215217 struct list_head *next;216218 struct dentry *dentry;217219218218- spin_lock(&dcache_lock);219220 spin_lock(&parent->d_lock);220221 next = parent->d_subdirs.next;221222 while (next != &parent->d_subdirs) {···224227 next = next->next;225228 }226229 spin_unlock(&parent->d_lock);227227- spin_unlock(&dcache_lock);228230}229231230232struct ncp_cache_head {
···6363 * This again causes shrink_dcache_for_umount_subtree() to6464 * Oops, since the test for IS_ROOT() will fail.6565 */6666- spin_lock(&dcache_lock);6766 spin_lock(&dcache_inode_lock);6867 spin_lock(&sb->s_root->d_lock);6968 list_del_init(&sb->s_root->d_alias);7069 spin_unlock(&sb->s_root->d_lock);7170 spin_unlock(&dcache_inode_lock);7272- spin_unlock(&dcache_lock);7371 }7472 return 0;7573}
···5959 /* determine if the children should tell inode about their events */6060 watched = fsnotify_inode_watches_children(inode);61616262- spin_lock(&dcache_lock);6362 spin_lock(&dcache_inode_lock);6463 /* run all of the dentries associated with this inode. Since this is a6564 * directory, there damn well better only be one item on this list */···8384 spin_unlock(&alias->d_lock);8485 }8586 spin_unlock(&dcache_inode_lock);8686- spin_unlock(&dcache_lock);8787}88888989/* Notify this dentry's parent about a child's events. */
···183183#define DCACHE_GENOCIDE 0x0200184184185185extern spinlock_t dcache_inode_lock;186186-extern spinlock_t dcache_lock;187186extern seqlock_t rename_lock;188187189188static inline int dname_external(struct dentry *dentry)···295296 * destroyed when it has references. dget() should never be296297 * called for dentries with zero reference counter. For these cases297298 * (preferably none, functions in dcache.c are sufficient for normal298298- * needs and they take necessary precautions) you should hold dcache_lock299299- * and call dget_locked() instead of dget().299299+ * needs and they take necessary precautions) you should hold d_lock300300+ * and call dget_dlock() instead of dget().300301 */301302static inline struct dentry *dget_dlock(struct dentry *dentry)302303{
+5-1
include/linux/fs.h
···13781378#else13791379 struct list_head s_files;13801380#endif13811381- /* s_dentry_lru and s_nr_dentry_unused are protected by dcache_lock */13811381+ /* s_dentry_lru, s_nr_dentry_unused protected by dcache.c lru locks */13821382 struct list_head s_dentry_lru; /* unused dentry lru */13831383 int s_nr_dentry_unused; /* # of dentry on lru */13841384···24462446{24472447 ino_t res;2448244824492449+ /*24502450+ * Don't strictly need d_lock here? If the parent ino could change24512451+ * then surely we'd have a deeper race in the caller?24522452+ */24492453 spin_lock(&dentry->d_lock);24502454 res = dentry->d_parent->d_inode->i_ino;24512455 spin_unlock(&dentry->d_lock);
-2
include/linux/fsnotify.h
···17171818/*1919 * fsnotify_d_instantiate - instantiate a dentry for inode2020- * Called with dcache_lock held.2120 */2221static inline void fsnotify_d_instantiate(struct dentry *dentry,2322 struct inode *inode)···61626263/*6364 * fsnotify_d_move - dentry has been moved6464- * Called with dcache_lock and dentry->d_lock held.6565 */6666static inline void fsnotify_d_move(struct dentry *dentry)6767{
+7-4
include/linux/fsnotify_backend.h
···329329{330330 struct dentry *parent;331331332332- assert_spin_locked(&dcache_lock);333332 assert_spin_locked(&dentry->d_lock);334333334334+ /*335335+ * Serialisation of setting PARENT_WATCHED on the dentries is provided336336+ * by d_lock. If inotify_inode_watched changes after we have taken337337+ * d_lock, the following __fsnotify_update_child_dentry_flags call will338338+ * find our entry, so it will spin until we complete here, and update339339+ * us with the new state.340340+ */335341 parent = dentry->d_parent;336342 if (parent->d_inode && fsnotify_inode_watches_children(parent->d_inode))337343 dentry->d_flags |= DCACHE_FSNOTIFY_PARENT_WATCHED;···347341348342/*349343 * fsnotify_d_instantiate - instantiate a dentry for inode350350- * Called with dcache_lock held.351344 */352345static inline void __fsnotify_d_instantiate(struct dentry *dentry, struct inode *inode)353346{354347 if (!inode)355348 return;356356-357357- assert_spin_locked(&dcache_lock);358349359350 spin_lock(&dentry->d_lock);360351 __fsnotify_update_dcache_flags(dentry);
-1
include/linux/namei.h
···4141 * - require a directory4242 * - ending slashes ok even for nonexistent files4343 * - internal "there are more path components" flag4444- * - locked when lookup done with dcache_lock held4544 * - dentry cache is untrusted; force a real lookup4645 */4746#define LOOKUP_FOLLOW 1