📄 vfs_intent-2.6-rhel4.patch
字号:
diff -rup RH_2_6_9_55.orig/fs/cifs/dir.c RH_2_6_9_55/fs/cifs/dir.c--- RH_2_6_9_55.orig/fs/cifs/dir.c+++ RH_2_6_9_55/fs/cifs/dir.c@@ -157,11 +157,7 @@ cifs_create(struct inode *inode, struct #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0) if(nd && (nd->flags & LOOKUP_OPEN)) {-#if LINUX_VERSION_CODE == KERNEL_VERSION(2,6,5) /* SUSE included Lustre patch */ int oflags = nd->intent.it_flags;-#else- int oflags = nd->intent.open.flags;-#endif desiredAccess = 0; if (oflags & FMODE_READ)diff -rup RH_2_6_9_55.orig/fs/exec.c RH_2_6_9_55/fs/exec.c--- RH_2_6_9_55.orig/fs/exec.c+++ RH_2_6_9_55/fs/exec.c@@ -126,9 +126,10 @@ asmlinkage long sys_uselib(const char __ struct file * file; struct nameidata nd; int error;-- nd.intent.open.flags = FMODE_READ|FMODE_EXEC;- error = __user_walk(library, LOOKUP_FOLLOW|LOOKUP_OPEN, &nd);+ intent_init(&nd.intent, IT_OPEN);+ + nd.intent.it_flags = FMODE_READ|FMODE_EXEC;+ error = __user_walk_it(library, LOOKUP_FOLLOW|LOOKUP_OPEN, &nd); if (error) goto out; @@ -140,7 +141,7 @@ asmlinkage long sys_uselib(const char __ if (error) goto exit; - file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);+ file = dentry_open_it(nd.dentry, nd.mnt, O_RDONLY, &nd.intent); error = PTR_ERR(file); if (IS_ERR(file)) goto out;@@ -489,8 +490,9 @@ struct file *open_exec(const char *name) int err; struct file *file; - nd.intent.open.flags = FMODE_READ|FMODE_EXEC;- err = path_lookup(name, LOOKUP_FOLLOW|LOOKUP_OPEN, &nd);+ intent_init(&nd.intent, IT_OPEN);+ nd.intent.it_flags = FMODE_READ|FMODE_EXEC;+ err = path_lookup_it(name, LOOKUP_FOLLOW, &nd); file = ERR_PTR(err); if (!err) {@@ -501,7 +503,7 @@ struct file *open_exec(const char *name) int err = permission(inode, MAY_EXEC, &nd); file = ERR_PTR(err); if (!err) {- file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);+ file = dentry_open_it(nd.dentry, nd.mnt, O_RDONLY, &nd.intent); if (!IS_ERR(file)) { err = deny_write_access(file); if (err) {diff -rup RH_2_6_9_55.orig/fs/inode.c RH_2_6_9_55/fs/inode.c--- RH_2_6_9_55.orig/fs/inode.c+++ RH_2_6_9_55/fs/inode.c@@ -235,6 +235,7 @@ void __iget(struct inode * inode) inodes_stat.nr_unused--; } +EXPORT_SYMBOL(__iget); /** * clear_inode - clear an inode * @inode: inode to cleardiff -rup RH_2_6_9_55.orig/fs/namei.c RH_2_6_9_55/fs/namei.c--- RH_2_6_9_55.orig/fs/namei.c+++ RH_2_6_9_55/fs/namei.c@@ -282,8 +282,19 @@ int deny_write_access(struct file * file return 0; } +void intent_release(struct lookup_intent *it)+{+ if (!it)+ return;+ if (it->it_magic != INTENT_MAGIC)+ return;+ if (it->it_op_release)+ it->it_op_release(it);+}+ void path_release(struct nameidata *nd) {+ intent_release(&nd->intent); dput(nd->dentry); mntput(nd->mnt); }@@ -395,8 +406,12 @@ static struct dentry * real_lookup(struc { struct dentry * result; struct inode *dir = parent->d_inode;-+ int counter = 0;+ +again: down(&dir->i_sem);+ counter++;+ /* * First re-do the cached lookup just in case it was created * while we waited for the directory semaphore..@@ -433,8 +448,12 @@ static struct dentry * real_lookup(struc up(&dir->i_sem); if (result->d_op && result->d_op->d_revalidate) { result = do_revalidate(result, nd);- if (!result)- result = ERR_PTR(-ENOENT);+ if (!result) {+ if (counter > 10)+ result = ERR_PTR(-ESTALE);+ if (!IS_ERR(result))+ goto again;+ } } return result; }@@ -464,6 +483,7 @@ static inline int __vfs_follow_link(stru { int res = 0; char *name;+ if (IS_ERR(link)) goto fail; @@ -473,6 +493,7 @@ static inline int __vfs_follow_link(stru /* weird __emul_prefix() stuff did it */ goto out; }+ intent_reset_fs_part(&nd->intent); res = link_path_walk(link, nd); out: if (nd->depth || res || nd->last_type!=LAST_NORM)@@ -681,6 +702,33 @@ fail: return PTR_ERR(dentry); } +static int revalidate_special(struct nameidata *nd)+{+ struct dentry *dentry = nd->dentry;+ int err, counter = 0;++ revalidate_again:+ if (!dentry->d_op || !dentry->d_op->d_revalidate)+ return 0;+ if (!dentry->d_op->d_revalidate(dentry, nd)) {+ struct dentry *new;+ if ((err = permission(dentry->d_parent->d_inode, MAY_EXEC, nd)))+ return err;+ new = real_lookup(dentry->d_parent, &dentry->d_name, nd);+ if (IS_ERR(new))+ return PTR_ERR(new);+ d_invalidate(dentry);+ dput(dentry);+ nd->dentry = dentry = new;+ counter++;+ if (counter < 10)+ goto revalidate_again;+ printk("excessive revalidate_it loops\n");+ return -ESTALE;+ }+ return 0;+}+ /* * Name resolution. * This is the basic name resolution function, turning a pathname into@@ -782,13 +830,17 @@ static fastcall int __link_path_walk(con goto out_dput; if (inode->i_op->follow_link) {+ int save_flags = nd->flags; mntget(next.mnt); if (next.mnt != nd->mnt) { dput(nd->dentry); nd->mnt = next.mnt; nd->dentry = dget(next.dentry); }+ nd->flags |= LOOKUP_LINK_NOTLAST; err = do_follow_link(next.dentry, nd);+ if (!(save_flags & LOOKUP_LINK_NOTLAST))+ nd->flags &= ~LOOKUP_LINK_NOTLAST; dput(next.dentry); mntput(next.mnt); if (err)@@ -828,14 +880,34 @@ last_component: inode = nd->dentry->d_inode; /* fallthrough */ case 1:+ nd->flags |= LOOKUP_LAST;+ err = revalidate_special(nd);+ nd->flags &= ~LOOKUP_LAST;+ if (!nd->dentry->d_inode)+ err = -ENOENT;+ if (err) {+ path_release(nd);+ goto return_err;+ }+ if (lookup_flags & LOOKUP_DIRECTORY) {+ err = -ENOTDIR;+ if (!nd->dentry->d_inode->i_op ||+ !nd->dentry->d_inode->i_op->lookup){+ path_release(nd);+ goto return_err;+ }+ } goto return_reval; }+ if (nd->dentry->d_op && nd->dentry->d_op->d_hash) { err = nd->dentry->d_op->d_hash(nd->dentry, &this); if (err < 0) break; }+ nd->flags |= LOOKUP_LAST; err = do_lookup(nd, &this, &next, atomic);+ nd->flags &= ~LOOKUP_LAST; if (err) break; follow_mount(&next.mnt, &next.dentry);@@ -1007,7 +1079,7 @@ set_it: } /* Returns 0 and nd will be valid on success; Retuns error, otherwise. */-int fastcall path_lookup(const char *name, unsigned int flags, struct nameidata *nd)+int fastcall path_lookup_it(const char *name, unsigned int flags, struct nameidata *nd) { int retval = 0; @@ -1041,6 +1113,12 @@ out: return retval; } +int fastcall path_lookup(const char *name, unsigned int flags, struct nameidata *nd)+{+ intent_init(&nd->intent, IT_GETATTR);+ return path_lookup_it(name, flags, nd);+}+ /* * Restricted form of lookup. Doesn't follow links, single-component only, * needs parent already locked. Doesn't follow mounts.@@ -1091,7 +1169,7 @@ struct dentry * lookup_hash(struct qstr } /* SMP-safe */-struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)+struct dentry * lookup_one_len_it(const char * name, struct dentry * base, int len, struct nameidata *nd) { unsigned long hash; struct qstr this;@@ -1111,11 +1189,16 @@ struct dentry * lookup_one_len(const cha } this.hash = end_name_hash(hash); - return lookup_hash(&this, base);+ return __lookup_hash(&this, base, nd); access: return ERR_PTR(-EACCES); } +struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)+{+ return lookup_one_len_it(name, base, len, NULL);+}+ /* * namei() *@@ -1127,18 +1210,24 @@ access: * that namei follows links, while lnamei does not. * SMP-safe */-int fastcall __user_walk(const char __user *name, unsigned flags, struct nameidata *nd)+int fastcall __user_walk_it(const char __user *name, unsigned flags, struct nameidata *nd) { char *tmp = getname(name); int err = PTR_ERR(tmp); if (!IS_ERR(tmp)) {- err = path_lookup(tmp, flags, nd);+ err = path_lookup_it(tmp, flags, nd); putname(tmp); } return err; } +int fastcall __user_walk(const char __user *name, unsigned flags, struct nameidata *nd)+{+ intent_init(&nd->intent, IT_LOOKUP);+ return __user_walk_it(name, flags, nd);+}+ /* * It's inline, so penalty for filesystems that don't use sticky bit is * minimal.@@ -1384,7 +1473,7 @@ int may_open(struct nameidata *nd, int a if (!error) { DQUOT_INIT(inode); - error = do_truncate(dentry, 0, ATTR_MTIME|ATTR_CTIME);+ error = do_truncate(dentry, 0, ATTR_MTIME|ATTR_CTIME|ATTR_FROM_OPEN); } put_write_access(inode); if (error)@@ -1425,14 +1514,14 @@ int open_namei(const char * pathname, in acc_mode |= MAY_APPEND; /* Fill in the open() intent data */- nd->intent.open.flags = flag;- nd->intent.open.create_mode = mode;+ nd->intent.it_flags = flag;+ nd->intent.it_create_mode = mode; /* * The simplest case - just a plain lookup. */ if (!(flag & O_CREAT)) {- error = path_lookup(pathname, lookup_flags(flag)|LOOKUP_OPEN, nd);+ error = path_lookup_it(pathname, lookup_flags(flag)|LOOKUP_OPEN, nd); if (error) return error; goto ok;@@ -1441,7 +1530,8 @@ int open_namei(const char * pathname, in /* * Create - we need to know the parent. */- error = path_lookup(pathname, LOOKUP_PARENT|LOOKUP_OPEN|LOOKUP_CREATE, nd);+ nd->intent.it_op |= IT_CREAT;+ error = path_lookup_it(pathname, LOOKUP_PARENT|LOOKUP_OPEN|LOOKUP_CREATE, nd); if (error) return error; @@ -1457,7 +1547,9 @@ int open_namei(const char * pathname, in dir = nd->dentry; nd->flags &= ~LOOKUP_PARENT; down(&dir->d_inode->i_sem);+ nd->flags |= LOOKUP_LAST; dentry = __lookup_hash(&nd->last, nd->dentry, nd);+ nd->flags &= ~LOOKUP_LAST; do_last: error = PTR_ERR(dentry);@@ -1570,7 +1662,9 @@ do_link: } dir = nd->dentry; down(&dir->d_inode->i_sem);+ nd->flags |= LOOKUP_LAST; dentry = __lookup_hash(&nd->last, nd->dentry, nd);+ nd->flags &= ~LOOKUP_LAST; __putname(nd->last.name); goto do_last; }@@ -1644,10 +1738,20 @@ asmlinkage long sys_mknod(const char __u tmp = getname(filename); if (IS_ERR(tmp)) return PTR_ERR(tmp);-- error = path_lookup(tmp, LOOKUP_PARENT, &nd);+ + intent_init(&nd.intent, IT_LOOKUP);+ error = path_lookup_it(tmp, LOOKUP_PARENT, &nd); if (error) goto out;++ if (nd.dentry->d_inode->i_op->mknod_raw) {+ struct inode_operations *op = nd.dentry->d_inode->i_op;+ error = op->mknod_raw(&nd, mode, dev);+ /* the file system wants to use normal vfs path now */+ if (error != -EOPNOTSUPP)+ goto out2;+ }+ dentry = lookup_create(&nd, 0); error = PTR_ERR(dentry); @@ -1674,6 +1778,7 @@ asmlinkage long sys_mknod(const char __u dput(dentry); } up(&nd.dentry->d_inode->i_sem);+out2: path_release(&nd); out: putname(tmp);@@ -1716,10 +1821,20 @@ asmlinkage long sys_mkdir(const char __u if (!IS_ERR(tmp)) { struct dentry *dentry; struct nameidata nd;+ intent_init(&nd.intent, IT_LOOKUP); - error = path_lookup(tmp, LOOKUP_PARENT, &nd);+ error = path_lookup_it(tmp, LOOKUP_PARENT, &nd); if (error) goto out;++ if (nd.dentry->d_inode->i_op->mkdir_raw) {+ struct inode_operations *op = nd.dentry->d_inode->i_op;+ error = op->mkdir_raw(&nd, mode);+ /* the file system wants to use normal vfs path now */+ if (error != -EOPNOTSUPP)+ goto out2;+ }+ dentry = lookup_create(&nd, 1); error = PTR_ERR(dentry); if (!IS_ERR(dentry)) {@@ -1729,6 +1844,7 @@ asmlinkage long sys_mkdir(const char __u dput(dentry); } up(&nd.dentry->d_inode->i_sem);+out2: path_release(&nd); out: putname(tmp);@@ -1814,7 +1930,8 @@ asmlinkage long sys_rmdir(const char __u if(IS_ERR(name)) return PTR_ERR(name); - error = path_lookup(name, LOOKUP_PARENT, &nd);+ intent_init(&nd.intent, IT_LOOKUP);+ error = path_lookup_it(name, LOOKUP_PARENT, &nd); if (error) goto exit; @@ -1829,6 +1946,16 @@ asmlinkage long sys_rmdir(const char __u error = -EBUSY; goto exit1; }++ if (nd.dentry->d_inode->i_op->rmdir_raw) {+ struct inode_operations *op = nd.dentry->d_inode->i_op;++ error = op->rmdir_raw(&nd);+ /* the file system wants 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); error = PTR_ERR(dentry);@@ -1892,12 +2019,22 @@ asmlinkage long sys_unlink(const char __ if(IS_ERR(name)) return PTR_ERR(name); - error = path_lookup(name, LOOKUP_PARENT, &nd);+ intent_init(&nd.intent, IT_LOOKUP);+ error = path_lookup_it(name, LOOKUP_PARENT, &nd); if (error) goto exit; error = -EISDIR; if (nd.last_type != LAST_NORM) goto exit1;+ + if (nd.dentry->d_inode->i_op->unlink_raw) {+ struct inode_operations *op = nd.dentry->d_inode->i_op;+ error = op->unlink_raw(&nd);+ /* the file system wants 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); error = PTR_ERR(dentry);@@ -1965,10 +2102,20 @@ asmlinkage long sys_symlink(const char _ if (!IS_ERR(to)) { struct dentry *dentry; struct nameidata nd;+ intent_init(&nd.intent, IT_LOOKUP); - error = path_lookup(to, LOOKUP_PARENT, &nd);+ error = path_lookup_it(to, LOOKUP_PARENT, &nd); if (error) goto out;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -