mirror of
https://github.com/team-infusion-developers/android_kernel_samsung_msm8976.git
synced 2024-11-07 04:09:21 +00:00
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6: isofs: Fix lseek() to position beyond 4 GB vfs: remove unused MNT_STRICTATIME vfs: show unreachable paths in getcwd and proc vfs: only add " (deleted)" where necessary vfs: add prepend_path() helper vfs: __d_path: dont prepend the name of the root dentry ia64: perfmon: add d_dname method vfs: add helpers to get root and pwd cachefiles: use path_get instead of lone dget fs/sysv/super.c: add support for non-PDP11 v7 filesystems V7: Adjust sanity checks for some volumes Add v7 alias v9fs: fixup for inode_setattr being removed Manual merge to take Al's version of the fs/sysv/super.c file: it merged cleanly, but Al had removed an unnecessary header include, so his side was better.
This commit is contained in:
commit
5af568cbd5
15 changed files with 223 additions and 130 deletions
|
@ -2191,8 +2191,15 @@ pfmfs_delete_dentry(struct dentry *dentry)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static char *pfmfs_dname(struct dentry *dentry, char *buffer, int buflen)
|
||||
{
|
||||
return dynamic_dname(dentry, buffer, buflen, "pfm:[%lu]",
|
||||
dentry->d_inode->i_ino);
|
||||
}
|
||||
|
||||
static const struct dentry_operations pfmfs_dentry_operations = {
|
||||
.d_delete = pfmfs_delete_dentry,
|
||||
.d_dname = pfmfs_dname,
|
||||
};
|
||||
|
||||
|
||||
|
@ -2202,8 +2209,7 @@ pfm_alloc_file(pfm_context_t *ctx)
|
|||
struct file *file;
|
||||
struct inode *inode;
|
||||
struct path path;
|
||||
char name[32];
|
||||
struct qstr this;
|
||||
struct qstr this = { .name = "" };
|
||||
|
||||
/*
|
||||
* allocate a new inode
|
||||
|
@ -2218,11 +2224,6 @@ pfm_alloc_file(pfm_context_t *ctx)
|
|||
inode->i_uid = current_fsuid();
|
||||
inode->i_gid = current_fsgid();
|
||||
|
||||
sprintf(name, "[%lu]", inode->i_ino);
|
||||
this.name = name;
|
||||
this.len = strlen(name);
|
||||
this.hash = inode->i_ino;
|
||||
|
||||
/*
|
||||
* allocate a new dcache entry
|
||||
*/
|
||||
|
|
|
@ -1263,10 +1263,19 @@ static int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr)
|
|||
return PTR_ERR(fid);
|
||||
|
||||
retval = p9_client_setattr(fid, &p9attr);
|
||||
if (retval >= 0)
|
||||
retval = inode_setattr(dentry->d_inode, iattr);
|
||||
if (retval < 0)
|
||||
return retval;
|
||||
|
||||
return retval;
|
||||
if ((iattr->ia_valid & ATTR_SIZE) &&
|
||||
iattr->ia_size != i_size_read(dentry->d_inode)) {
|
||||
retval = vmtruncate(dentry->d_inode, iattr->ia_size);
|
||||
if (retval)
|
||||
return retval;
|
||||
}
|
||||
|
||||
setattr_copy(dentry->d_inode, iattr);
|
||||
mark_inode_dirty(dentry->d_inode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -552,8 +552,7 @@ static int cachefiles_daemon_tag(struct cachefiles_cache *cache, char *args)
|
|||
*/
|
||||
static int cachefiles_daemon_cull(struct cachefiles_cache *cache, char *args)
|
||||
{
|
||||
struct fs_struct *fs;
|
||||
struct dentry *dir;
|
||||
struct path path;
|
||||
const struct cred *saved_cred;
|
||||
int ret;
|
||||
|
||||
|
@ -573,24 +572,21 @@ static int cachefiles_daemon_cull(struct cachefiles_cache *cache, char *args)
|
|||
}
|
||||
|
||||
/* extract the directory dentry from the cwd */
|
||||
fs = current->fs;
|
||||
read_lock(&fs->lock);
|
||||
dir = dget(fs->pwd.dentry);
|
||||
read_unlock(&fs->lock);
|
||||
get_fs_pwd(current->fs, &path);
|
||||
|
||||
if (!S_ISDIR(dir->d_inode->i_mode))
|
||||
if (!S_ISDIR(path.dentry->d_inode->i_mode))
|
||||
goto notdir;
|
||||
|
||||
cachefiles_begin_secure(cache, &saved_cred);
|
||||
ret = cachefiles_cull(cache, dir, args);
|
||||
ret = cachefiles_cull(cache, path.dentry, args);
|
||||
cachefiles_end_secure(cache, saved_cred);
|
||||
|
||||
dput(dir);
|
||||
path_put(&path);
|
||||
_leave(" = %d", ret);
|
||||
return ret;
|
||||
|
||||
notdir:
|
||||
dput(dir);
|
||||
path_put(&path);
|
||||
kerror("cull command requires dirfd to be a directory");
|
||||
return -ENOTDIR;
|
||||
|
||||
|
@ -628,8 +624,7 @@ inval:
|
|||
*/
|
||||
static int cachefiles_daemon_inuse(struct cachefiles_cache *cache, char *args)
|
||||
{
|
||||
struct fs_struct *fs;
|
||||
struct dentry *dir;
|
||||
struct path path;
|
||||
const struct cred *saved_cred;
|
||||
int ret;
|
||||
|
||||
|
@ -649,24 +644,21 @@ static int cachefiles_daemon_inuse(struct cachefiles_cache *cache, char *args)
|
|||
}
|
||||
|
||||
/* extract the directory dentry from the cwd */
|
||||
fs = current->fs;
|
||||
read_lock(&fs->lock);
|
||||
dir = dget(fs->pwd.dentry);
|
||||
read_unlock(&fs->lock);
|
||||
get_fs_pwd(current->fs, &path);
|
||||
|
||||
if (!S_ISDIR(dir->d_inode->i_mode))
|
||||
if (!S_ISDIR(path.dentry->d_inode->i_mode))
|
||||
goto notdir;
|
||||
|
||||
cachefiles_begin_secure(cache, &saved_cred);
|
||||
ret = cachefiles_check_in_use(cache, dir, args);
|
||||
ret = cachefiles_check_in_use(cache, path.dentry, args);
|
||||
cachefiles_end_secure(cache, saved_cred);
|
||||
|
||||
dput(dir);
|
||||
path_put(&path);
|
||||
//_leave(" = %d", ret);
|
||||
return ret;
|
||||
|
||||
notdir:
|
||||
dput(dir);
|
||||
path_put(&path);
|
||||
kerror("inuse command requires dirfd to be a directory");
|
||||
return -ENOTDIR;
|
||||
|
||||
|
|
188
fs/dcache.c
188
fs/dcache.c
|
@ -1905,48 +1905,30 @@ static int prepend_name(char **buffer, int *buflen, struct qstr *name)
|
|||
}
|
||||
|
||||
/**
|
||||
* __d_path - return the path of a dentry
|
||||
* Prepend path string to a buffer
|
||||
*
|
||||
* @path: the dentry/vfsmount to report
|
||||
* @root: root vfsmnt/dentry (may be modified by this function)
|
||||
* @buffer: buffer to return value in
|
||||
* @buflen: buffer length
|
||||
* @buffer: pointer to the end of the buffer
|
||||
* @buflen: pointer to buffer length
|
||||
*
|
||||
* Convert a dentry into an ASCII path name. If the entry has been deleted
|
||||
* the string " (deleted)" is appended. Note that this is ambiguous.
|
||||
*
|
||||
* Returns a pointer into the buffer or an error code if the
|
||||
* path was too long.
|
||||
*
|
||||
* "buflen" should be positive. Caller holds the dcache_lock.
|
||||
* Caller holds the dcache_lock.
|
||||
*
|
||||
* If path is not reachable from the supplied root, then the value of
|
||||
* root is changed (without modifying refcounts).
|
||||
*/
|
||||
char *__d_path(const struct path *path, struct path *root,
|
||||
char *buffer, int buflen)
|
||||
static int prepend_path(const struct path *path, struct path *root,
|
||||
char **buffer, int *buflen)
|
||||
{
|
||||
struct dentry *dentry = path->dentry;
|
||||
struct vfsmount *vfsmnt = path->mnt;
|
||||
char *end = buffer + buflen;
|
||||
char *retval;
|
||||
bool slash = false;
|
||||
int error = 0;
|
||||
|
||||
spin_lock(&vfsmount_lock);
|
||||
prepend(&end, &buflen, "\0", 1);
|
||||
if (d_unlinked(dentry) &&
|
||||
(prepend(&end, &buflen, " (deleted)", 10) != 0))
|
||||
goto Elong;
|
||||
|
||||
if (buflen < 1)
|
||||
goto Elong;
|
||||
/* Get '/' right */
|
||||
retval = end-1;
|
||||
*retval = '/';
|
||||
|
||||
for (;;) {
|
||||
while (dentry != root->dentry || vfsmnt != root->mnt) {
|
||||
struct dentry * parent;
|
||||
|
||||
if (dentry == root->dentry && vfsmnt == root->mnt)
|
||||
break;
|
||||
if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
|
||||
/* Global root? */
|
||||
if (vfsmnt->mnt_parent == vfsmnt) {
|
||||
|
@ -1958,28 +1940,88 @@ char *__d_path(const struct path *path, struct path *root,
|
|||
}
|
||||
parent = dentry->d_parent;
|
||||
prefetch(parent);
|
||||
if ((prepend_name(&end, &buflen, &dentry->d_name) != 0) ||
|
||||
(prepend(&end, &buflen, "/", 1) != 0))
|
||||
goto Elong;
|
||||
retval = end;
|
||||
error = prepend_name(buffer, buflen, &dentry->d_name);
|
||||
if (!error)
|
||||
error = prepend(buffer, buflen, "/", 1);
|
||||
if (error)
|
||||
break;
|
||||
|
||||
slash = true;
|
||||
dentry = parent;
|
||||
}
|
||||
|
||||
out:
|
||||
if (!error && !slash)
|
||||
error = prepend(buffer, buflen, "/", 1);
|
||||
|
||||
spin_unlock(&vfsmount_lock);
|
||||
return retval;
|
||||
return error;
|
||||
|
||||
global_root:
|
||||
retval += 1; /* hit the slash */
|
||||
if (prepend_name(&retval, &buflen, &dentry->d_name) != 0)
|
||||
goto Elong;
|
||||
/*
|
||||
* Filesystems needing to implement special "root names"
|
||||
* should do so with ->d_dname()
|
||||
*/
|
||||
if (IS_ROOT(dentry) &&
|
||||
(dentry->d_name.len != 1 || dentry->d_name.name[0] != '/')) {
|
||||
WARN(1, "Root dentry has weird name <%.*s>\n",
|
||||
(int) dentry->d_name.len, dentry->d_name.name);
|
||||
}
|
||||
root->mnt = vfsmnt;
|
||||
root->dentry = dentry;
|
||||
goto out;
|
||||
}
|
||||
|
||||
Elong:
|
||||
retval = ERR_PTR(-ENAMETOOLONG);
|
||||
goto out;
|
||||
/**
|
||||
* __d_path - return the path of a dentry
|
||||
* @path: the dentry/vfsmount to report
|
||||
* @root: root vfsmnt/dentry (may be modified by this function)
|
||||
* @buffer: buffer to return value in
|
||||
* @buflen: buffer length
|
||||
*
|
||||
* Convert a dentry into an ASCII path name.
|
||||
*
|
||||
* Returns a pointer into the buffer or an error code if the
|
||||
* path was too long.
|
||||
*
|
||||
* "buflen" should be positive. Caller holds the dcache_lock.
|
||||
*
|
||||
* If path is not reachable from the supplied root, then the value of
|
||||
* root is changed (without modifying refcounts).
|
||||
*/
|
||||
char *__d_path(const struct path *path, struct path *root,
|
||||
char *buf, int buflen)
|
||||
{
|
||||
char *res = buf + buflen;
|
||||
int error;
|
||||
|
||||
prepend(&res, &buflen, "\0", 1);
|
||||
error = prepend_path(path, root, &res, &buflen);
|
||||
if (error)
|
||||
return ERR_PTR(error);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* same as __d_path but appends "(deleted)" for unlinked files.
|
||||
*/
|
||||
static int path_with_deleted(const struct path *path, struct path *root,
|
||||
char **buf, int *buflen)
|
||||
{
|
||||
prepend(buf, buflen, "\0", 1);
|
||||
if (d_unlinked(path->dentry)) {
|
||||
int error = prepend(buf, buflen, " (deleted)", 10);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
|
||||
return prepend_path(path, root, buf, buflen);
|
||||
}
|
||||
|
||||
static int prepend_unreachable(char **buffer, int *buflen)
|
||||
{
|
||||
return prepend(buffer, buflen, "(unreachable)", 13);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2000,9 +2042,10 @@ Elong:
|
|||
*/
|
||||
char *d_path(const struct path *path, char *buf, int buflen)
|
||||
{
|
||||
char *res;
|
||||
char *res = buf + buflen;
|
||||
struct path root;
|
||||
struct path tmp;
|
||||
int error;
|
||||
|
||||
/*
|
||||
* We have various synthetic filesystems that never get mounted. On
|
||||
|
@ -2014,19 +2057,51 @@ char *d_path(const struct path *path, char *buf, int buflen)
|
|||
if (path->dentry->d_op && path->dentry->d_op->d_dname)
|
||||
return path->dentry->d_op->d_dname(path->dentry, buf, buflen);
|
||||
|
||||
read_lock(¤t->fs->lock);
|
||||
root = current->fs->root;
|
||||
path_get(&root);
|
||||
read_unlock(¤t->fs->lock);
|
||||
get_fs_root(current->fs, &root);
|
||||
spin_lock(&dcache_lock);
|
||||
tmp = root;
|
||||
res = __d_path(path, &tmp, buf, buflen);
|
||||
error = path_with_deleted(path, &tmp, &res, &buflen);
|
||||
if (error)
|
||||
res = ERR_PTR(error);
|
||||
spin_unlock(&dcache_lock);
|
||||
path_put(&root);
|
||||
return res;
|
||||
}
|
||||
EXPORT_SYMBOL(d_path);
|
||||
|
||||
/**
|
||||
* d_path_with_unreachable - return the path of a dentry
|
||||
* @path: path to report
|
||||
* @buf: buffer to return value in
|
||||
* @buflen: buffer length
|
||||
*
|
||||
* The difference from d_path() is that this prepends "(unreachable)"
|
||||
* to paths which are unreachable from the current process' root.
|
||||
*/
|
||||
char *d_path_with_unreachable(const struct path *path, char *buf, int buflen)
|
||||
{
|
||||
char *res = buf + buflen;
|
||||
struct path root;
|
||||
struct path tmp;
|
||||
int error;
|
||||
|
||||
if (path->dentry->d_op && path->dentry->d_op->d_dname)
|
||||
return path->dentry->d_op->d_dname(path->dentry, buf, buflen);
|
||||
|
||||
get_fs_root(current->fs, &root);
|
||||
spin_lock(&dcache_lock);
|
||||
tmp = root;
|
||||
error = path_with_deleted(path, &tmp, &res, &buflen);
|
||||
if (!error && !path_equal(&tmp, &root))
|
||||
error = prepend_unreachable(&res, &buflen);
|
||||
spin_unlock(&dcache_lock);
|
||||
path_put(&root);
|
||||
if (error)
|
||||
res = ERR_PTR(error);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function for dentry_operations.d_dname() members
|
||||
*/
|
||||
|
@ -2129,27 +2204,30 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size)
|
|||
if (!page)
|
||||
return -ENOMEM;
|
||||
|
||||
read_lock(¤t->fs->lock);
|
||||
pwd = current->fs->pwd;
|
||||
path_get(&pwd);
|
||||
root = current->fs->root;
|
||||
path_get(&root);
|
||||
read_unlock(¤t->fs->lock);
|
||||
get_fs_root_and_pwd(current->fs, &root, &pwd);
|
||||
|
||||
error = -ENOENT;
|
||||
spin_lock(&dcache_lock);
|
||||
if (!d_unlinked(pwd.dentry)) {
|
||||
unsigned long len;
|
||||
struct path tmp = root;
|
||||
char * cwd;
|
||||
char *cwd = page + PAGE_SIZE;
|
||||
int buflen = PAGE_SIZE;
|
||||
|
||||
cwd = __d_path(&pwd, &tmp, page, PAGE_SIZE);
|
||||
prepend(&cwd, &buflen, "\0", 1);
|
||||
error = prepend_path(&pwd, &tmp, &cwd, &buflen);
|
||||
spin_unlock(&dcache_lock);
|
||||
|
||||
error = PTR_ERR(cwd);
|
||||
if (IS_ERR(cwd))
|
||||
if (error)
|
||||
goto out;
|
||||
|
||||
/* Unreachable from current root */
|
||||
if (!path_equal(&tmp, &root)) {
|
||||
error = prepend_unreachable(&cwd, &buflen);
|
||||
if (error)
|
||||
goto out;
|
||||
}
|
||||
|
||||
error = -ERANGE;
|
||||
len = PAGE_SIZE + page - cwd;
|
||||
if (len <= size) {
|
||||
|
|
|
@ -106,12 +106,7 @@ struct fs_struct *copy_fs_struct(struct fs_struct *old)
|
|||
fs->in_exec = 0;
|
||||
rwlock_init(&fs->lock);
|
||||
fs->umask = old->umask;
|
||||
read_lock(&old->lock);
|
||||
fs->root = old->root;
|
||||
path_get(&old->root);
|
||||
fs->pwd = old->pwd;
|
||||
path_get(&old->pwd);
|
||||
read_unlock(&old->lock);
|
||||
get_fs_root_and_pwd(old, &fs->root, &fs->pwd);
|
||||
}
|
||||
return fs;
|
||||
}
|
||||
|
|
|
@ -722,7 +722,12 @@ root_found:
|
|||
}
|
||||
|
||||
s->s_magic = ISOFS_SUPER_MAGIC;
|
||||
s->s_maxbytes = 0xffffffff; /* We can handle files up to 4 GB */
|
||||
|
||||
/*
|
||||
* With multi-extent files, file size is only limited by the maximum
|
||||
* size of a file system, which is 8 TB.
|
||||
*/
|
||||
s->s_maxbytes = 0x80000000000LL;
|
||||
|
||||
/*
|
||||
* The CDROM is read-only, has no nodes (devices) on it, and since
|
||||
|
|
15
fs/namei.c
15
fs/namei.c
|
@ -483,13 +483,8 @@ ok:
|
|||
|
||||
static __always_inline void set_root(struct nameidata *nd)
|
||||
{
|
||||
if (!nd->root.mnt) {
|
||||
struct fs_struct *fs = current->fs;
|
||||
read_lock(&fs->lock);
|
||||
nd->root = fs->root;
|
||||
path_get(&nd->root);
|
||||
read_unlock(&fs->lock);
|
||||
}
|
||||
if (!nd->root.mnt)
|
||||
get_fs_root(current->fs, &nd->root);
|
||||
}
|
||||
|
||||
static int link_path_walk(const char *, struct nameidata *);
|
||||
|
@ -1015,11 +1010,7 @@ static int path_init(int dfd, const char *name, unsigned int flags, struct namei
|
|||
nd->path = nd->root;
|
||||
path_get(&nd->root);
|
||||
} else if (dfd == AT_FDCWD) {
|
||||
struct fs_struct *fs = current->fs;
|
||||
read_lock(&fs->lock);
|
||||
nd->path = fs->pwd;
|
||||
path_get(&fs->pwd);
|
||||
read_unlock(&fs->lock);
|
||||
get_fs_pwd(current->fs, &nd->path);
|
||||
} else {
|
||||
struct dentry *dentry;
|
||||
|
||||
|
|
|
@ -788,7 +788,6 @@ static void show_mnt_opts(struct seq_file *m, struct vfsmount *mnt)
|
|||
{ MNT_NOATIME, ",noatime" },
|
||||
{ MNT_NODIRATIME, ",nodiratime" },
|
||||
{ MNT_RELATIME, ",relatime" },
|
||||
{ MNT_STRICTATIME, ",strictatime" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct proc_fs_info *fs_infop;
|
||||
|
@ -2213,10 +2212,7 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
|
|||
goto out1;
|
||||
}
|
||||
|
||||
read_lock(¤t->fs->lock);
|
||||
root = current->fs->root;
|
||||
path_get(¤t->fs->root);
|
||||
read_unlock(¤t->fs->lock);
|
||||
get_fs_root(current->fs, &root);
|
||||
down_write(&namespace_sem);
|
||||
mutex_lock(&old.dentry->d_inode->i_mutex);
|
||||
error = -EINVAL;
|
||||
|
|
|
@ -149,18 +149,13 @@ static unsigned int pid_entry_count_dirs(const struct pid_entry *entries,
|
|||
return count;
|
||||
}
|
||||
|
||||
static int get_fs_path(struct task_struct *task, struct path *path, bool root)
|
||||
static int get_task_root(struct task_struct *task, struct path *root)
|
||||
{
|
||||
struct fs_struct *fs;
|
||||
int result = -ENOENT;
|
||||
|
||||
task_lock(task);
|
||||
fs = task->fs;
|
||||
if (fs) {
|
||||
read_lock(&fs->lock);
|
||||
*path = root ? fs->root : fs->pwd;
|
||||
path_get(path);
|
||||
read_unlock(&fs->lock);
|
||||
if (task->fs) {
|
||||
get_fs_root(task->fs, root);
|
||||
result = 0;
|
||||
}
|
||||
task_unlock(task);
|
||||
|
@ -173,7 +168,12 @@ static int proc_cwd_link(struct inode *inode, struct path *path)
|
|||
int result = -ENOENT;
|
||||
|
||||
if (task) {
|
||||
result = get_fs_path(task, path, 0);
|
||||
task_lock(task);
|
||||
if (task->fs) {
|
||||
get_fs_pwd(task->fs, path);
|
||||
result = 0;
|
||||
}
|
||||
task_unlock(task);
|
||||
put_task_struct(task);
|
||||
}
|
||||
return result;
|
||||
|
@ -185,7 +185,7 @@ static int proc_root_link(struct inode *inode, struct path *path)
|
|||
int result = -ENOENT;
|
||||
|
||||
if (task) {
|
||||
result = get_fs_path(task, path, 1);
|
||||
result = get_task_root(task, path);
|
||||
put_task_struct(task);
|
||||
}
|
||||
return result;
|
||||
|
@ -597,7 +597,7 @@ static int mounts_open_common(struct inode *inode, struct file *file,
|
|||
get_mnt_ns(ns);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
if (ns && get_fs_path(task, &root, 1) == 0)
|
||||
if (ns && get_task_root(task, &root) == 0)
|
||||
ret = 0;
|
||||
put_task_struct(task);
|
||||
}
|
||||
|
@ -1526,7 +1526,7 @@ static int do_proc_readlink(struct path *path, char __user *buffer, int buflen)
|
|||
if (!tmp)
|
||||
return -ENOMEM;
|
||||
|
||||
pathname = d_path(path, tmp, PAGE_SIZE);
|
||||
pathname = d_path_with_unreachable(path, tmp, PAGE_SIZE);
|
||||
len = PTR_ERR(pathname);
|
||||
if (IS_ERR(pathname))
|
||||
goto out;
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/buffer_head.h>
|
||||
#include <linux/parser.h>
|
||||
#include "sysv.h"
|
||||
|
||||
/*
|
||||
|
|
|
@ -315,6 +315,7 @@ extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...);
|
|||
|
||||
extern char *__d_path(const struct path *path, struct path *root, char *, int);
|
||||
extern char *d_path(const struct path *, char *, int);
|
||||
extern char *d_path_with_unreachable(const struct path *, char *, int);
|
||||
extern char *__dentry_path(struct dentry *, char *, int);
|
||||
extern char *dentry_path(struct dentry *, char *, int);
|
||||
|
||||
|
|
|
@ -21,4 +21,31 @@ extern void free_fs_struct(struct fs_struct *);
|
|||
extern void daemonize_fs_struct(void);
|
||||
extern int unshare_fs_struct(void);
|
||||
|
||||
static inline void get_fs_root(struct fs_struct *fs, struct path *root)
|
||||
{
|
||||
read_lock(&fs->lock);
|
||||
*root = fs->root;
|
||||
path_get(root);
|
||||
read_unlock(&fs->lock);
|
||||
}
|
||||
|
||||
static inline void get_fs_pwd(struct fs_struct *fs, struct path *pwd)
|
||||
{
|
||||
read_lock(&fs->lock);
|
||||
*pwd = fs->pwd;
|
||||
path_get(pwd);
|
||||
read_unlock(&fs->lock);
|
||||
}
|
||||
|
||||
static inline void get_fs_root_and_pwd(struct fs_struct *fs, struct path *root,
|
||||
struct path *pwd)
|
||||
{
|
||||
read_lock(&fs->lock);
|
||||
*root = fs->root;
|
||||
path_get(root);
|
||||
*pwd = fs->pwd;
|
||||
path_get(pwd);
|
||||
read_unlock(&fs->lock);
|
||||
}
|
||||
|
||||
#endif /* _LINUX_FS_STRUCT_H */
|
||||
|
|
|
@ -27,7 +27,6 @@ struct mnt_namespace;
|
|||
#define MNT_NODIRATIME 0x10
|
||||
#define MNT_RELATIME 0x20
|
||||
#define MNT_READONLY 0x40 /* does the user want this to be r/o? */
|
||||
#define MNT_STRICTATIME 0x80
|
||||
|
||||
#define MNT_SHRINKABLE 0x100
|
||||
#define MNT_WRITE_HOLD 0x200
|
||||
|
|
|
@ -12,4 +12,9 @@ struct path {
|
|||
extern void path_get(struct path *);
|
||||
extern void path_put(struct path *);
|
||||
|
||||
static inline int path_equal(const struct path *path1, const struct path *path2)
|
||||
{
|
||||
return path1->mnt == path2->mnt && path1->dentry == path2->dentry;
|
||||
}
|
||||
|
||||
#endif /* _LINUX_PATH_H */
|
||||
|
|
|
@ -1835,13 +1835,8 @@ void __audit_getname(const char *name)
|
|||
context->names[context->name_count].ino = (unsigned long)-1;
|
||||
context->names[context->name_count].osid = 0;
|
||||
++context->name_count;
|
||||
if (!context->pwd.dentry) {
|
||||
read_lock(¤t->fs->lock);
|
||||
context->pwd = current->fs->pwd;
|
||||
path_get(¤t->fs->pwd);
|
||||
read_unlock(¤t->fs->lock);
|
||||
}
|
||||
|
||||
if (!context->pwd.dentry)
|
||||
get_fs_pwd(current->fs, &context->pwd);
|
||||
}
|
||||
|
||||
/* audit_putname - intercept a putname request
|
||||
|
|
Loading…
Reference in a new issue