From: adilger Date: Wed, 22 Jan 2003 13:47:15 +0000 (+0000) Subject: Fix one cause of bug 430 (hardlinks) that showed up with simul, but this was X-Git-Tag: v1_7_110~2^11~209 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=d7613e7c7fe06147a438c09b34241ebf754988ba;p=fs%2Flustre-release.git Fix one cause of bug 430 (hardlinks) that showed up with simul, but this was a recently introduced bug and not the real source of problems. Back to the drawing board in terms of finding a repeatable testcase. The only thing learned from this and the previous extN orphan assertion (bug 670) is that they were both caused by dentry refcount problems, and the files related to that dentry refcount were unlinked. --- diff --git a/lustre/kernel_patches/patches/vfs_intent.patch b/lustre/kernel_patches/patches/vfs_intent.patch index 94dc41e..611104d 100644 --- a/lustre/kernel_patches/patches/vfs_intent.patch +++ b/lustre/kernel_patches/patches/vfs_intent.patch @@ -27,11 +27,11 @@ return 0; } + -+ /* network invalidation by Lustre */ -+ if (dentry->d_flags & DCACHE_LUSTRE_INVALID) { -+ spin_unlock(&dcache_lock); -+ return 0; -+ } ++ /* network invalidation by Lustre */ ++ if (dentry->d_flags & DCACHE_LUSTRE_INVALID) { ++ spin_unlock(&dcache_lock); ++ return 0; ++ } + /* * Check whether to do a partial shrink_dcache @@ -128,7 +128,7 @@ */ -static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd) +static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd, -+ struct lookup_intent *it) ++ struct lookup_intent *it) { int err; if (current->link_count >= max_recursive_link) @@ -137,14 +137,14 @@ current->total_link_count++; UPDATE_ATIME(dentry->d_inode); - err = dentry->d_inode->i_op->follow_link(dentry, nd); -+ if (dentry->d_inode->i_op->follow_link2) -+ err = dentry->d_inode->i_op->follow_link2(dentry, nd, it); -+ else -+ err = dentry->d_inode->i_op->follow_link(dentry, nd); ++ if (dentry->d_inode->i_op->follow_link2) ++ err = dentry->d_inode->i_op->follow_link2(dentry, nd, it); ++ else ++ err = dentry->d_inode->i_op->follow_link(dentry, nd); current->link_count--; return err; loop: -+ intent_release(dentry, it); ++ intent_release(dentry, it); path_release(nd); return -ELOOP; } @@ -208,15 +208,14 @@ err = PTR_ERR(dentry); if (IS_ERR(dentry)) break; -@@ -606,8 +642,10 @@ last_component: +@@ -606,8 +642,9 @@ last_component: ; inode = dentry->d_inode; if ((lookup_flags & LOOKUP_FOLLOW) - && inode && inode->i_op && inode->i_op->follow_link) { - err = do_follow_link(dentry, nd); + && inode && inode->i_op && -+ (inode->i_op->follow_link || -+ inode->i_op->follow_link2)) { ++ (inode->i_op->follow_link || inode->i_op->follow_link2)) { + err = do_follow_link(dentry, nd, it); dput(dentry); if (err) @@ -235,8 +234,8 @@ dput(dentry); break; } -+ if (err) -+ intent_release(nd->dentry, it); ++ if (err) ++ intent_release(nd->dentry, it); path_release(nd); return_err: return err; @@ -385,8 +384,8 @@ /* * Create - we need to know the parent. */ -+ it.it_mode = mode; -+ it.it_op |= IT_CREAT; ++ it.it_mode = mode; ++ it.it_op |= IT_CREAT; error = path_lookup(pathname, LOOKUP_PARENT, &nd); if (error) return ERR_PTR(error); @@ -413,7 +412,7 @@ goto exit_dput; - if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link) + if (dentry->d_inode->i_op && (dentry->d_inode->i_op->follow_link || -+ dentry->d_inode->i_op->follow_link2)) ++ dentry->d_inode->i_op->follow_link2)) goto do_link; dput(nd.dentry); @@ -422,13 +421,13 @@ open_flags &= ~O_TRUNC; - return dentry_open(nd.dentry, nd.mnt, open_flags); -+ return dentry_open_it(nd.dentry, nd.mnt, open_flags, &it); ++ return dentry_open_it(nd.dentry, nd.mnt, open_flags, &it); exit_dput: -+ intent_release(dentry, &it); ++ intent_release(dentry, &it); dput(dentry); exit: -+ intent_release(nd.dentry, &it); ++ intent_release(nd.dentry, &it); path_release(&nd); return ERR_PTR(error); @@ -437,10 +436,10 @@ */ UPDATE_ATIME(dentry->d_inode); - error = dentry->d_inode->i_op->follow_link(dentry, &nd); -+ if (dentry->d_inode->i_op->follow_link2) -+ error = dentry->d_inode->i_op->follow_link2(dentry, &nd, &it); -+ else -+ error = dentry->d_inode->i_op->follow_link(dentry, &nd); ++ if (dentry->d_inode->i_op->follow_link2) ++ error = dentry->d_inode->i_op->follow_link2(dentry, &nd, &it); ++ else ++ error = dentry->d_inode->i_op->follow_link(dentry, &nd); + if (error) + intent_release(dentry, &it); dput(dentry); @@ -487,17 +486,17 @@ goto out; - dentry = lookup_create(&nd, 0); + -+ if (nd.dentry->d_inode->i_op->mknod2) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->mknod2(nd.dentry->d_inode, -+ nd.last.name, -+ nd.last.len, -+ mode, dev); -+ /* the file system want to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto out2; -+ } -+ ++ if (nd.dentry->d_inode->i_op->mknod2) { ++ struct inode_operations *op = nd.dentry->d_inode->i_op; ++ error = op->mknod2(nd.dentry->d_inode, ++ nd.last.name, ++ nd.last.len, ++ mode, dev); ++ /* the file system want to use normal vfs path now */ ++ if (error != -EOPNOTSUPP) ++ goto out2; ++ } ++ + dentry = lookup_create(&nd, 0, &it); error = PTR_ERR(dentry); @@ -527,16 +526,16 @@ if (error) goto out; - dentry = lookup_create(&nd, 1); -+ if (nd.dentry->d_inode->i_op->mkdir2) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->mkdir2(nd.dentry->d_inode, -+ nd.last.name, -+ nd.last.len, -+ mode); -+ /* the file system want to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto out2; -+ } ++ if (nd.dentry->d_inode->i_op->mkdir2) { ++ struct inode_operations *op = nd.dentry->d_inode->i_op; ++ error = op->mkdir2(nd.dentry->d_inode, ++ nd.last.name, ++ nd.last.len, ++ mode); ++ /* the file system want to use normal vfs path now */ ++ if (error != -EOPNOTSUPP) ++ goto out2; ++ } + dentry = lookup_create(&nd, 1, &it); error = PTR_ERR(dentry); if (!IS_ERR(dentry)) { @@ -562,15 +561,15 @@ error = -EBUSY; goto exit1; } -+ if (nd.dentry->d_inode->i_op->rmdir2) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->rmdir2(nd.dentry->d_inode, -+ nd.last.name, -+ nd.last.len); -+ /* the file system want to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto exit1; -+ } ++ if (nd.dentry->d_inode->i_op->rmdir2) { ++ struct inode_operations *op = nd.dentry->d_inode->i_op; ++ error = op->rmdir2(nd.dentry->d_inode, ++ nd.last.name, ++ nd.last.len); ++ /* the file system want to use normal vfs path now */ ++ if (error != -EOPNOTSUPP) ++ goto exit1; ++ } down(&nd.dentry->d_inode->i_sem); - dentry = lookup_hash(&nd.last, nd.dentry); + dentry = lookup_hash_it(&nd.last, nd.dentry, &it); @@ -593,15 +592,15 @@ error = -EISDIR; if (nd.last_type != LAST_NORM) goto exit1; -+ if (nd.dentry->d_inode->i_op->unlink2) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->unlink2(nd.dentry->d_inode, -+ nd.last.name, -+ nd.last.len); -+ /* the file system want to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto exit1; -+ } ++ if (nd.dentry->d_inode->i_op->unlink2) { ++ struct inode_operations *op = nd.dentry->d_inode->i_op; ++ error = op->unlink2(nd.dentry->d_inode, ++ nd.last.name, ++ nd.last.len); ++ /* the file system want to use normal vfs path now */ ++ if (error != -EOPNOTSUPP) ++ goto exit1; ++ } down(&nd.dentry->d_inode->i_sem); - dentry = lookup_hash(&nd.last, nd.dentry); + dentry = lookup_hash_it(&nd.last, nd.dentry, &it); @@ -629,16 +628,16 @@ if (error) goto out; - dentry = lookup_create(&nd, 0); -+ if (nd.dentry->d_inode->i_op->symlink2) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->symlink2(nd.dentry->d_inode, -+ nd.last.name, -+ nd.last.len, -+ from); -+ /* the file system want to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto out2; -+ } ++ if (nd.dentry->d_inode->i_op->symlink2) { ++ struct inode_operations *op = nd.dentry->d_inode->i_op; ++ error = op->symlink2(nd.dentry->d_inode, ++ nd.last.name, ++ nd.last.len, ++ from); ++ /* the file system want to use normal vfs path now */ ++ if (error != -EOPNOTSUPP) ++ goto out2; ++ } + it.it_data = from; + dentry = lookup_create(&nd, 0, &it); error = PTR_ERR(dentry); @@ -648,10 +647,10 @@ dput(dentry); } up(&nd.dentry->d_inode->i_sem); -+ out2: ++ out2: path_release(&nd); -out: -+ out: ++ out: putname(to); } putname(from); @@ -677,16 +676,16 @@ if (old_nd.mnt != nd.mnt) goto out_release; - new_dentry = lookup_create(&nd, 0); -+ if (nd.dentry->d_inode->i_op->link2) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->link2(old_nd.dentry->d_inode, -+ nd.dentry->d_inode, -+ nd.last.name, -+ nd.last.len); -+ /* the file system want to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto out_release; -+ } ++ if (nd.dentry->d_inode->i_op->link2) { ++ struct inode_operations *op = nd.dentry->d_inode->i_op; ++ error = op->link2(old_nd.dentry->d_inode, ++ nd.dentry->d_inode, ++ nd.last.name, ++ nd.last.len); ++ /* the file system want to use normal vfs path now */ ++ if (error != -EOPNOTSUPP) ++ goto out_release; ++ } + it.it_op = IT_LINK2; + new_dentry = lookup_create(&nd, 0, &it); error = PTR_ERR(new_dentry); @@ -762,19 +761,19 @@ if (newnd.last_type != LAST_NORM) goto exit2; -+ if (old_dir->d_inode->i_op->rename2) { -+ lock_kernel(); -+ error = old_dir->d_inode->i_op->rename2(old_dir->d_inode, -+ new_dir->d_inode, -+ oldnd.last.name, -+ oldnd.last.len, -+ newnd.last.name, -+ newnd.last.len); -+ unlock_kernel(); -+ /* the file system want to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto exit2; -+ } ++ if (old_dir->d_inode->i_op->rename2) { ++ lock_kernel(); ++ error = old_dir->d_inode->i_op->rename2(old_dir->d_inode, ++ new_dir->d_inode, ++ oldnd.last.name, ++ oldnd.last.len, ++ newnd.last.name, ++ newnd.last.len); ++ unlock_kernel(); ++ /* the file system want to use normal vfs path now */ ++ if (error != -EOPNOTSUPP) ++ goto exit2; ++ } + double_lock(new_dir, old_dir); @@ -813,7 +812,7 @@ static inline int -__vfs_follow_link(struct nameidata *nd, const char *link) +__vfs_follow_link(struct nameidata *nd, const char *link, -+ struct lookup_intent *it) ++ struct lookup_intent *it) { int res = 0; char *name; @@ -835,7 +834,7 @@ +} + +int vfs_follow_link_it(struct nameidata *nd, const char *link, -+ struct lookup_intent *it) ++ struct lookup_intent *it) +{ + return __vfs_follow_link(nd, link, it); } @@ -1212,24 +1211,24 @@ int (*link) (struct dentry *,struct inode *,struct dentry *); + int (*link2) (struct inode *,struct inode *, const char *, int); int (*unlink) (struct inode *,struct dentry *); -+ int (*unlink2) (struct inode *, char *, int); ++ int (*unlink2) (struct inode *, const char *, int); int (*symlink) (struct inode *,struct dentry *,const char *); -+ int (*symlink2) (struct inode *,const char *, int, const char *); ++ int (*symlink2) (struct inode *, const char *, int, const char *); int (*mkdir) (struct inode *,struct dentry *,int); -+ int (*mkdir2) (struct inode *,char *, int,int); ++ int (*mkdir2) (struct inode *, const char *, int,int); int (*rmdir) (struct inode *,struct dentry *); -+ int (*rmdir2) (struct inode *, char *, int); ++ int (*rmdir2) (struct inode *, const char *, int); int (*mknod) (struct inode *,struct dentry *,int,int); -+ int (*mknod2) (struct inode *,char *, int,int,int); ++ int (*mknod2) (struct inode *, const char *, int,int,int); int (*rename) (struct inode *, struct dentry *, struct inode *, struct dentry *); + int (*rename2) (struct inode *, struct inode *, -+ char *oldname, int oldlen, -+ char *newname, int newlen); ++ const char *oldname, int oldlen, ++ const char *newname, int newlen); int (*readlink) (struct dentry *, char *,int); int (*follow_link) (struct dentry *, struct nameidata *); + int (*follow_link2) (struct dentry *, struct nameidata *, -+ struct lookup_intent *it); ++ struct lookup_intent *it); void (*truncate) (struct inode *); int (*permission) (struct inode *, int); int (*revalidate) (struct dentry *); @@ -1255,7 +1254,7 @@ extern int vfs_readlink(struct dentry *, char *, int, const char *); extern int vfs_follow_link(struct nameidata *, const char *); +extern int vfs_follow_link_it(struct nameidata *, const char *, -+ struct lookup_intent *it); ++ struct lookup_intent *it); extern int page_readlink(struct dentry *, char *, int); extern int page_follow_link(struct dentry *, struct nameidata *); extern struct inode_operations page_symlink_inode_operations;