From: Andrew Watts <akwatts@ymail.com>
To: linux-fsdevel@vger.kernel.org
Subject: [overlayfs/port] overlayfs: v13 port attempt to kernel 3.5
Date: Thu, 16 Aug 2012 15:44:43 -0500 [thread overview]
Message-ID: <20120816204440.GA8808@ymail.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 563 bytes --]
Hi.
I am trying to port the recent work of Andy Whitcroft (for kernel 3.4)
to kernel 3.5.
Due to changes in *__dentry_open in fs/open.c and to the inode_operations
struct, overlayfs v13 doesn't apply cleanly.
I am attaching consolidated diffs for both fs/open.c and include/linux/fs.h,
which contain the substantive changes I made to Andy's work, for review.
Please point out any errors I might have made.
I've not attached the changes I made to the patches against the Locking and
vfs.txt documentation as those weren't substantive.
Many thanks,
~ Andy
[-- Attachment #2: overlayfs-v13-3.5.diff --]
[-- Type: text/plain, Size: 6121 bytes --]
--- a/overlayfs2/fs/open.c 2012-08-16
+++ b/overlayfs2/fs/open.c 2012-08-16
@@ -667,7 +667,7 @@ int open_check_o_direct(struct file *f)
return 0;
}
-static struct file *do_dentry_open(struct dentry *dentry, struct vfsmount *mnt,
+static struct file *do_dentry_open(struct path *path,
struct file *f,
int (*open)(struct inode *, struct file *),
const struct cred *cred)
@@ -676,15 +676,16 @@ static struct file *do_dentry_open(struc
struct inode *inode;
int error;
+ path_get(path);
f->f_mode = OPEN_FMODE(f->f_flags) | FMODE_LSEEK |
FMODE_PREAD | FMODE_PWRITE;
if (unlikely(f->f_flags & O_PATH))
f->f_mode = FMODE_PATH;
- inode = dentry->d_inode;
+ inode = path->dentry->d_inode;
if (f->f_mode & FMODE_WRITE) {
- error = __get_file_write_access(inode, mnt);
+ error = __get_file_write_access(inode, path->mnt);
if (error)
goto cleanup_file;
if (!special_file(inode->i_mode))
@@ -692,8 +693,7 @@ static struct file *do_dentry_open(struc
}
f->f_mapping = inode->i_mapping;
- f->f_path.dentry = dentry;
- f->f_path.mnt = mnt;
+ f->f_path = *path;
f->f_pos = 0;
file_sb_list_add(f, inode->i_sb);
@@ -740,24 +740,23 @@ cleanup_all:
* here, so just reset the state.
*/
file_reset_write(f);
- mnt_drop_write(mnt);
+ mnt_drop_write(path->mnt);
}
}
file_sb_list_del(f);
f->f_path.dentry = NULL;
f->f_path.mnt = NULL;
cleanup_file:
- dput(dentry);
- mntput(mnt);
+ path_put(path);
return ERR_PTR(error);
}
-static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
+static struct file *__dentry_open(struct path *path,
struct file *f,
int (*open)(struct inode *, struct file *),
const struct cred *cred)
{
- struct file *res = do_dentry_open(dentry, mnt, f, open, cred);
+ struct file *res = do_dentry_open(path, mnt, f, open, cred);
if (!IS_ERR(res)) {
int error = open_check_o_direct(f);
if (error) {
@@ -792,14 +791,14 @@ static struct file *__dentry_open(struct
struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry,
int (*open)(struct inode *, struct file *))
{
+ struct path path = { .dentry = dentry, .mnt = nd->path.mnt };
const struct cred *cred = current_cred();
if (IS_ERR(nd->intent.open.file))
goto out;
if (IS_ERR(dentry))
goto out_err;
- nd->intent.open.file = __dentry_open(dget(dentry), mntget(nd->path.mnt),
- nd->intent.open.file,
+ nd->intent.open.file = __dentry_open(&path, nd->intent.open.file,
open, cred);
out:
return nd->intent.open.file;
@@ -831,9 +830,7 @@ struct file *nameidata_to_filp(struct na
} else {
struct file *res;
- path_get(&nd->path);
- res = do_dentry_open(nd->path.dentry, nd->path.mnt,
- filp, NULL, cred);
+ res = vfs_open(&nd->path, filp, cred);
if (!IS_ERR(res)) {
int error;
@@ -860,27 +857,48 @@ struct file *nameidata_to_filp(struct na
struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags,
const struct cred *cred)
{
- int error;
struct file *f;
+ struct file *ret;
+ struct path path = { .dentry = dentry, .mnt = mnt };
validate_creds(cred);
/* We must always pass in a valid mount pointer. */
BUG_ON(!mnt);
- error = -ENFILE;
+ ret = ERR_PTR(-ENFILE);
f = get_empty_filp();
- if (f == NULL) {
- dput(dentry);
- mntput(mnt);
- return ERR_PTR(error);
+ if (f != NULL) {
+ f->f_flags = flags;
+ ret = vfs_open(&path, f, cred);
}
+ path_put(&path);
- f->f_flags = flags;
- return __dentry_open(dentry, mnt, f, NULL, cred);
+ return ret;
}
EXPORT_SYMBOL(dentry_open);
+/**
+ * vfs_open - open the file at the given path
+ * @path: path to open
+ * @filp: newly allocated file with f_flag initialized
+ * @cred: credentials to use
+ *
+ * Open the file. If successful, the returned file will have acquired
+ * an additional reference for path.
+ */
+struct file *vfs_open(struct path *path, struct file *filp,
+ const struct cred *cred)
+{
+ struct inode *inode = path->dentry->d_inode;
+
+ if (inode->i_op->open)
+ return inode->i_op->open(path->dentry, filp, cred);
+ else
+ return __dentry_open(path, filp, NULL, cred);
+}
+EXPORT_SYMBOL(vfs_open);
+
static void __put_unused_fd(struct files_struct *files, unsigned int fd)
{
struct fdtable *fdt = files_fdtable(files);
--- a/overlayfs2/include/linux/fs.h 2012-08-16
+++ b/overlayfs2/include/linux/fs.h 2012-08-16
@@ -499,6 +499,12 @@ struct iattr {
*/
#include <linux/quota.h>
+/*
+ * Maximum number of layers of fs stack. Needs to be limited to
+ * prevent kernel stack overflow
+ */
+#define FILESYSTEM_MAX_STACK_DEPTH 2
+
/**
* enum positive_aop_returns - aop return codes with specific semantics
*
@@ -1542,6 +1548,11 @@ struct super_block {
/* Being remounted read-only */
int s_readonly_remount;
+
+ /*
+ * Indicates how deep in a filesystem stack this SB is
+ */
+ int s_stack_depth;
};
/* superblock cache pruning functions */
@@ -1693,6 +1704,8 @@ struct inode_operations {
int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start,
u64 len);
int (*update_time)(struct inode *, struct timespec *, int);
+ struct file *(*open) (struct dentry *, struct file *,
+ const struct cred *);
} ____cacheline_aligned;
struct seq_file;
@@ -2057,6 +2070,7 @@ extern long do_sys_open(int dfd, const c
extern struct file *filp_open(const char *, int, umode_t);
extern struct file *file_open_root(struct dentry *, struct vfsmount *,
const char *, int);
+extern struct file *vfs_open(struct path *, struct file *, const struct cred *);
extern struct file * dentry_open(struct dentry *, struct vfsmount *, int,
const struct cred *);
extern int filp_close(struct file *, fl_owner_t id);
@@ -2249,6 +2263,7 @@ extern sector_t bmap(struct inode *, sec
#endif
extern int notify_change(struct dentry *, struct iattr *);
extern int inode_permission(struct inode *, int);
+extern int inode_only_permission(struct inode *, int);
extern int generic_permission(struct inode *, int);
static inline bool execute_ok(struct inode *inode)
next reply other threads:[~2012-08-16 20:50 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-08-16 20:44 Andrew Watts [this message]
2012-08-16 21:14 ` [overlayfs/port] overlayfs: v13 port attempt to kernel 3.5 Sedat Dilek
2012-08-17 1:05 ` Andrew Watts
2012-08-17 9:18 ` Sedat Dilek
2012-08-20 10:38 ` J. R. Okajima
2012-08-20 11:26 ` Sedat Dilek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20120816204440.GA8808@ymail.com \
--to=akwatts@ymail.com \
--cc=linux-fsdevel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.