📄 vfs_intent-2.6-suse.patch
字号:
Index: linux-2.6.5-12.1/fs/exec.c===================================================================--- linux-2.6.5-12.1.orig/fs/exec.c 2004-05-10 12:21:56.000000000 -0400+++ linux-2.6.5-12.1/fs/exec.c 2004-06-03 18:31:28.000000000 -0400@@ -125,9 +125,10 @@ struct nameidata nd; int error; - nd.intent.open.flags = FMODE_READ;+ intent_init(&nd.intent, IT_OPEN); - FSHOOK_BEGIN_USER_WALK(open,+ nd.intent.it_flags = FMODE_READ|FMODE_EXEC;+ FSHOOK_BEGIN_USER_WALK_IT(open, error, library, LOOKUP_FOLLOW|LOOKUP_OPEN,@@ -144,7 +145,7 @@ goto out; } - 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;@@ -495,8 +496,9 @@ FSHOOK_BEGIN(open, err, .filename = name, .flags = O_RDONLY) - nd.intent.open.flags = FMODE_READ;- 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(name, LOOKUP_FOLLOW, &nd); file = ERR_PTR(err); if (!err) {@@ -509,7 +511,7 @@ err = -EACCES; 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) {Index: linux-2.6.5-12.1/fs/namei.c===================================================================--- linux-2.6.5-12.1.orig/fs/namei.c 2004-05-10 12:21:56.000000000 -0400+++ linux-2.6.5-12.1/fs/namei.c 2004-06-03 18:42:17.000000000 -0400@@ -270,8 +270,19 @@ 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); }@@ -348,7 +359,10 @@ { struct dentry * result; struct inode *dir = parent->d_inode;+ int counter = 0; +again:+ counter++; down(&dir->i_sem); /* * First re-do the cached lookup just in case it was created@@ -387,7 +401,10 @@ if (result->d_op && result->d_op->d_revalidate) { if (!result->d_op->d_revalidate(result, nd) && !d_invalidate(result)) { dput(result);- result = ERR_PTR(-ENOENT);+ if (counter > 10)+ result = ERR_PTR(-ESTALE);+ if (!IS_ERR(result))+ goto again; } } return result;@@ -564,6 +581,33 @@ 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. *@@ -664,8 +708,12 @@ goto out_dput; if (inode->i_op->follow_link) {+ int save_flags = nd->flags; mntget(next.mnt);+ 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)@@ -703,14 +749,34 @@ 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);+ nd->flags &= ~LOOKUP_LAST; if (err) break; follow_mount(&next.mnt, &next.dentry);@@ -936,7 +992,7 @@ } /* 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;@@ -956,11 +1012,16 @@ } 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() *@@ -972,7 +1033,8 @@ * that namei follows links, while lnamei does not. * SMP-safe */-int fastcall __user_walk(const char __user *name, unsigned flags, struct nameidata *nd, const char **pname)+int fastcall __user_walk_it(const char __user *name, unsigned flags,+ struct nameidata *nd, const char **pname) { char *tmp = getname(name); int err = PTR_ERR(tmp);@@ -987,6 +1049,13 @@ return err; } +int fastcall __user_walk(const char __user *name, unsigned flags,+ struct nameidata *nd, const char **pname)+{+ intent_init(&nd->intent, IT_LOOKUP);+ return __user_walk_it(name, flags, nd, pname);+}+ /* * It's inline, so penalty for filesystems that don't use sticky bit is * minimal.@@ -1259,8 +1328,8 @@ 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.@@ -1275,6 +1344,7 @@ /* * Create - we need to know the parent. */+ nd->intent.it_op |= IT_CREAT; error = path_lookup(pathname, LOOKUP_PARENT|LOOKUP_OPEN|LOOKUP_CREATE, nd); if (error) return error;@@ -1291,7 +1361,9 @@ 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);@@ -1396,7 +1468,9 @@ } 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; }@@ -2196,7 +2270,9 @@ __vfs_follow_link(struct nameidata *nd, const char *link) { int res = 0;+ struct lookup_intent it = nd->intent; char *name;+ if (IS_ERR(link)) goto fail; @@ -2206,6 +2282,10 @@ /* weird __emul_prefix() stuff did it */ goto out; }++ intent_init(&nd->intent, it.it_op);+ nd->intent.it_flags = it.it_flags;+ nd->intent.it_create_mode = it.it_create_mode; res = link_path_walk(link, nd); out: if (current->link_count || res || nd->last_type!=LAST_NORM)Index: linux-2.6.5-12.1/fs/namespace.c===================================================================--- linux-2.6.5-12.1.orig/fs/namespace.c 2004-05-10 12:21:56.000000000 -0400+++ linux-2.6.5-12.1/fs/namespace.c 2004-06-03 18:31:28.000000000 -0400@@ -108,6 +108,7 @@ static void detach_mnt(struct vfsmount *mnt, struct nameidata *old_nd) {+ memset(old_nd, 0, sizeof(*old_nd)); old_nd->dentry = mnt->mnt_mountpoint; old_nd->mnt = mnt->mnt_parent; mnt->mnt_parent = mnt;@@ -533,6 +534,8 @@ return err; if (!old_name || !*old_name) return -EINVAL;++ intent_init(&old_nd.intent, IT_LOOKUP); err = path_lookup(old_name, LOOKUP_FOLLOW, &old_nd); if (err) return err;@@ -601,6 +604,7 @@ return -EPERM; if (!old_name || !*old_name) return -EINVAL;+ intent_init(&old_nd.intent, IT_LOOKUP); err = path_lookup(old_name, LOOKUP_FOLLOW, &old_nd); if (err) return err;@@ -750,6 +754,7 @@ int retval = 0; int mnt_flags = 0; + intent_init(&nd.intent, IT_LOOKUP); /* Discard magic */ if ((flags & MS_MGC_MSK) == MS_MGC_VAL) flags &= ~MS_MGC_MSK;Index: linux-2.6.5-12.1/fs/open.c===================================================================--- linux-2.6.5-12.1.orig/fs/open.c 2004-05-10 12:21:56.000000000 -0400+++ linux-2.6.5-12.1/fs/open.c 2004-06-03 18:31:28.000000000 -0400@@ -227,12 +227,12 @@ struct nameidata nd; struct inode * inode; int error;-+ intent_init(&nd.intent, IT_GETATTR); error = -EINVAL; if (length < 0) /* sorry, but loff_t says... */ goto out; - FSHOOK_BEGIN_USER_PATH_WALK(truncate, error, path, nd, filename, .length = length)+ FSHOOK_BEGIN_USER_PATH_WALK_IT(truncate, error, path, nd, filename, .length = length) inode = nd.dentry->d_inode; @@ -466,6 +466,7 @@ int old_fsuid, old_fsgid; kernel_cap_t old_cap; int res;+ intent_init(&nd.intent, IT_GETATTR); if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ return -EINVAL;@@ -490,7 +491,7 @@ else current->cap_effective = current->cap_permitted; - FSHOOK_BEGIN_USER_WALK(access,+ FSHOOK_BEGIN_USER_WALK_IT(access, res, filename, LOOKUP_FOLLOW|LOOKUP_ACCESS,@@ -506,6 +507,7 @@ if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode) && !special_file(nd.dentry->d_inode->i_mode)) res = -EROFS;+ path_release(&nd); FSHOOK_END_USER_WALK(access, res, path)@@ -545,11 +547,13 @@ asmlinkage long sys_fchdir(unsigned int fd) {+ struct nameidata nd; struct file *file; struct dentry *dentry; struct inode *inode; struct vfsmount *mnt; int error;+ intent_init(&nd.intent, IT_GETATTR); FSHOOK_BEGIN(fchdir, error, .fd = fd) @@ -582,8 +586,9 @@ { struct nameidata nd; int error;+ intent_init(&nd.intent, IT_GETATTR); - FSHOOK_BEGIN_USER_WALK(chroot,+ FSHOOK_BEGIN_USER_WALK_IT(chroot, error, filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_NOALT,@@ -670,7 +675,7 @@ error = -EROFS; if (IS_RDONLY(inode)) goto dput_and_out;-+ error = -EPERM; if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) goto dput_and_out;@@ -804,27 +809,8 @@ * for the internal routines (ie open_namei()/follow_link() etc). 00 is * used by symlinks. */-struct file *filp_open(const char * filename, int flags, int mode)-{- int namei_flags, error;- struct nameidata nd;-- namei_flags = flags;- if ((namei_flags+1) & O_ACCMODE)- namei_flags++;- if (namei_flags & O_TRUNC)- namei_flags |= 2;-
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -