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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).