]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - fs/namei.c
Deassign device in kvm_free_assgined_device
[mv-sheeva.git] / fs / namei.c
index ab441af4196b20cb728667a6c43b63e1ab525533..dd5c9f0bf82994d39020b6b9ad534cc094170ad9 100644 (file)
@@ -226,6 +226,16 @@ int generic_permission(struct inode *inode, int mask,
        return -EACCES;
 }
 
+/**
+ * inode_permission  -  check for access rights to a given inode
+ * @inode:     inode to check permission on
+ * @mask:      right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
+ *
+ * Used to check for read/write/execute permissions on an inode.
+ * We use "fsuid" for this, letting us set arbitrary permissions
+ * for filesystem access without changing the "normal" uids which
+ * are used for other things.
+ */
 int inode_permission(struct inode *inode, int mask)
 {
        int retval;
@@ -247,7 +257,6 @@ int inode_permission(struct inode *inode, int mask)
                        return -EACCES;
        }
 
-       /* Ordinary permission routines do not understand MAY_APPEND. */
        if (inode->i_op && inode->i_op->permission)
                retval = inode->i_op->permission(inode, mask);
        else
@@ -264,21 +273,6 @@ int inode_permission(struct inode *inode, int mask)
                        mask & (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND));
 }
 
-/**
- * vfs_permission  -  check for access rights to a given path
- * @nd:                lookup result that describes the path
- * @mask:      right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
- *
- * Used to check for read/write/execute permissions on a path.
- * We use "fsuid" for this, letting us set arbitrary permissions
- * for filesystem access without changing the "normal" uids which
- * are used for other things.
- */
-int vfs_permission(struct nameidata *nd, int mask)
-{
-       return inode_permission(nd->path.dentry->d_inode, mask);
-}
-
 /**
  * file_permission  -  check for additional access rights to a given file
  * @file:      file to check access rights for
@@ -289,7 +283,7 @@ int vfs_permission(struct nameidata *nd, int mask)
  *
  * Note:
  *     Do not use this function in new code.  All access checks should
- *     be done using vfs_permission().
+ *     be done using inode_permission().
  */
 int file_permission(struct file *file, int mask)
 {
@@ -527,18 +521,6 @@ out_unlock:
        return result;
 }
 
-/* SMP-safe */
-static __always_inline void
-walk_init_root(const char *name, struct nameidata *nd)
-{
-       struct fs_struct *fs = current->fs;
-
-       read_lock(&fs->lock);
-       nd->path = fs->root;
-       path_get(&fs->root);
-       read_unlock(&fs->lock);
-}
-
 /*
  * Wrapper to retry pathname resolution whenever the underlying
  * file system returns an ESTALE.
@@ -576,9 +558,16 @@ static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *l
                goto fail;
 
        if (*link == '/') {
+               struct fs_struct *fs = current->fs;
+
                path_put(&nd->path);
-               walk_init_root(link, nd);
+
+               read_lock(&fs->lock);
+               nd->path = fs->root;
+               path_get(&fs->root);
+               read_unlock(&fs->lock);
        }
+
        res = link_path_walk(link, nd);
        if (nd->depth || res || nd->last_type!=LAST_NORM)
                return res;
@@ -859,7 +848,8 @@ static int __link_path_walk(const char *name, struct nameidata *nd)
                nd->flags |= LOOKUP_CONTINUE;
                err = exec_permission_lite(inode);
                if (err == -EAGAIN)
-                       err = vfs_permission(nd, MAY_EXEC);
+                       err = inode_permission(nd->path.dentry->d_inode,
+                                              MAY_EXEC);
                if (err)
                        break;
 
@@ -1493,9 +1483,9 @@ int vfs_create(struct inode *dir, struct dentry *dentry, int mode,
        return error;
 }
 
-int may_open(struct nameidata *nd, int acc_mode, int flag)
+int may_open(struct path *path, int acc_mode, int flag)
 {
-       struct dentry *dentry = nd->path.dentry;
+       struct dentry *dentry = path->dentry;
        struct inode *inode = dentry->d_inode;
        int error;
 
@@ -1516,13 +1506,13 @@ int may_open(struct nameidata *nd, int acc_mode, int flag)
        if (S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
                flag &= ~O_TRUNC;
        } else if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) {
-               if (nd->path.mnt->mnt_flags & MNT_NODEV)
+               if (path->mnt->mnt_flags & MNT_NODEV)
                        return -EACCES;
 
                flag &= ~O_TRUNC;
        }
 
-       error = vfs_permission(nd, acc_mode);
+       error = inode_permission(inode, acc_mode);
        if (error)
                return error;
        /*
@@ -1557,7 +1547,7 @@ int may_open(struct nameidata *nd, int acc_mode, int flag)
                 */
                error = locks_verify_locked(inode);
                if (!error)
-                       error = security_path_truncate(&nd->path, 0,
+                       error = security_path_truncate(path, 0,
                                               ATTR_MTIME|ATTR_CTIME|ATTR_OPEN);
                if (!error) {
                        DQUOT_INIT(inode);
@@ -1600,7 +1590,7 @@ out_unlock:
        if (error)
                return error;
        /* Don't check for write permission, don't truncate */
-       return may_open(nd, 0, flag & ~O_TRUNC);
+       return may_open(&nd->path, 0, flag & ~O_TRUNC);
 }
 
 /*
@@ -1786,7 +1776,7 @@ ok:
                if (error)
                        goto exit;
        }
-       error = may_open(&nd, acc_mode, flag);
+       error = may_open(&nd.path, acc_mode, flag);
        if (error) {
                if (will_write)
                        mnt_drop_write(nd.path.mnt);
@@ -2786,13 +2776,16 @@ int vfs_follow_link(struct nameidata *nd, const char *link)
 /* get the link contents into pagecache */
 static char *page_getlink(struct dentry * dentry, struct page **ppage)
 {
-       struct page * page;
+       char *kaddr;
+       struct page *page;
        struct address_space *mapping = dentry->d_inode->i_mapping;
        page = read_mapping_page(mapping, 0, NULL);
        if (IS_ERR(page))
                return (char*)page;
        *ppage = page;
-       return kmap(page);
+       kaddr = kmap(page);
+       nd_terminate_link(kaddr, dentry->d_inode->i_size, PAGE_SIZE - 1);
+       return kaddr;
 }
 
 int page_readlink(struct dentry *dentry, char __user *buffer, int buflen)
@@ -2885,7 +2878,6 @@ EXPORT_SYMBOL(path_lookup);
 EXPORT_SYMBOL(kern_path);
 EXPORT_SYMBOL(vfs_path_lookup);
 EXPORT_SYMBOL(inode_permission);
-EXPORT_SYMBOL(vfs_permission);
 EXPORT_SYMBOL(file_permission);
 EXPORT_SYMBOL(unlock_rename);
 EXPORT_SYMBOL(vfs_create);
@@ -2901,3 +2893,10 @@ EXPORT_SYMBOL(vfs_symlink);
 EXPORT_SYMBOL(vfs_unlink);
 EXPORT_SYMBOL(dentry_unhash);
 EXPORT_SYMBOL(generic_readlink);
+
+/* to be mentioned only in INIT_TASK */
+struct fs_struct init_fs = {
+       .count          = ATOMIC_INIT(1),
+       .lock           = __RW_LOCK_UNLOCKED(init_fs.lock),
+       .umask          = 0022,
+};