From: J. R. Okajima Date: Mon, 2 Mar 2009 03:01:32 +0000 (+0900) Subject: support linux-2.6.29-rcN X-Git-Url: http://git.c3sl.ufpr.br/gitweb?p=aufs%2Faufs2-2.6.git;a=commitdiff_plain;h=8cf6e539dee0bc3475c369fb47dea8788308524f;hp=c829c5602df0282219fe5f0dfdebb77902433703 support linux-2.6.29-rcN - replace do_fsync() by vfs_fsync(). - add credential to dentry_open(). - support squashfs, btrfs and xenfs (untested). - eliminate the test for inode->i_op. - replace current->fsuid by current_fsuid() call. - support security_path_*() functions. - version string. Signed-off-by: J. R. Okajima --- diff --git a/fs/aufs/dir.c b/fs/aufs/dir.c index 74e979e..44c78c9 100644 --- a/fs/aufs/dir.c +++ b/fs/aufs/dir.c @@ -218,7 +218,7 @@ static int au_do_fsync_dir(struct file *file, int datasync) if (!h_file || au_test_ro(sb, bindex, inode)) continue; - err = (int)do_fsync(h_file, datasync); + err = vfs_fsync(h_file, h_file->f_dentry, datasync); if (!err) { h_mtx = &h_file->f_dentry->d_inode->i_mutex; mutex_lock(h_mtx); diff --git a/fs/aufs/file.c b/fs/aufs/file.c index 2cba50b..470281b 100644 --- a/fs/aufs/file.c +++ b/fs/aufs/file.c @@ -69,7 +69,8 @@ struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags, flags = au_file_roflags(flags); flags &= ~O_CREAT; atomic_inc(&br->br_count); - h_file = dentry_open(dget(h_dentry), mntget(br->br_mnt), flags); + h_file = dentry_open(dget(h_dentry), mntget(br->br_mnt), flags, + current_cred()); if (IS_ERR(h_file)) goto out_br; diff --git a/fs/aufs/fstype.h b/fs/aufs/fstype.h index f6c5191..eac06aa 100644 --- a/fs/aufs/fstype.h +++ b/fs/aufs/fstype.h @@ -257,6 +257,33 @@ static inline int au_test_securityfs(struct super_block *sb __maybe_unused) #endif } +static inline int au_test_squashfs(struct super_block *sb __maybe_unused) +{ +#if defined(CONFIG_SQUASHFS) || defined(CONFIG_SQUASHFS_MODULE) + return sb->s_magic == SQUASHFS_MAGIC; +#else + return 0; +#endif +} + +static inline int au_test_btrfs(struct super_block *sb __maybe_unused) +{ +#if defined(CONFIG_BTRFS_FS) || defined(CONFIG_BTRFS_FS_MODULE) + return sb->s_magic == BTRFS_SUPER_MAGIC; +#else + return 0; +#endif +} + +static inline int au_test_xenfs(struct super_block *sb __maybe_unused) +{ +#if defined(CONFIG_XENFS) || defined(CONFIG_XENFS_MODULE) + return sb->s_magic == XENFS_SUPER_MAGIC; +#else + return 0; +#endif +} + /* ---------------------------------------------------------------------- */ /* * they can't be an aufs branch. @@ -267,6 +294,7 @@ static inline int au_test_fs_unsuppoted(struct super_block *sb) || au_test_sysfs(sb) || au_test_configfs(sb) || au_test_securityfs(sb) + || au_test_xenfs(sb) || au_test_ramfs(sb) /* || !strcmp(au_sbtype(sb), "unionfs") */ || au_test_aufs(sb); /* will be supported in next version */ @@ -307,6 +335,7 @@ static inline int au_test_fs_refresh_iattr(struct super_block *sb) || au_test_fuse(sb) /* || au_test_smbfs(sb) */ /* untested */ /* || au_test_ocfs2(sb) */ /* untested */ + /* || au_test_btrfs(sb) */ /* untested */ /* || au_test_coda(sb) */ /* untested */ /* || au_test_v9fs(sb) */ /* untested */ ; @@ -395,7 +424,8 @@ static inline int au_test_fs_trunc_xino(struct super_block *sb) */ static inline int au_test_fs_rr(struct super_block *sb) { - return au_test_iso9660(sb) + return au_test_squashfs(sb) + || au_test_iso9660(sb) || au_test_cramfs(sb) || au_test_romfs(sb); } diff --git a/fs/aufs/i_op.c b/fs/aufs/i_op.c index 40f6737..ec4a854 100644 --- a/fs/aufs/i_op.c +++ b/fs/aufs/i_op.c @@ -38,7 +38,6 @@ static int h_permission(struct inode *h_inode, int mask, if ((write_mask && !au_br_writable(brperm)) || (au_test_nfs(h_inode->i_sb) && S_ISDIR(h_inode->i_mode) && write_mask && !(mask & MAY_READ)) - || !h_inode->i_op || !h_inode->i_op->permission) { /* AuLabel(generic_permission); */ err = generic_permission(h_inode, mask, NULL); @@ -745,8 +744,8 @@ static int h_readlink(struct dentry *dentry, int bindex, char __user *buf, h_dentry = au_h_dptr(dentry, bindex); if (unlikely(/* !h_dentry || !h_dentry->d_inode - || */ !h_dentry->d_inode->i_op - || !h_dentry->d_inode->i_op->readlink)) + || !h_dentry->d_inode->i_op + || */ !h_dentry->d_inode->i_op->readlink)) goto out; err = security_inode_readlink(h_dentry); diff --git a/fs/aufs/inode.c b/fs/aufs/inode.c index 3871a45..c4a962b 100644 --- a/fs/aufs/inode.c +++ b/fs/aufs/inode.c @@ -341,7 +341,7 @@ int au_test_ro(struct super_block *sb, aufs_bindex_t bindex, int au_test_h_perm(struct inode *h_inode, int mask) { - if (!current->fsuid) + if (!current_fsuid()) return 0; return inode_permission(h_inode, mask); } diff --git a/fs/aufs/vfsub.c b/fs/aufs/vfsub.c index 5a4b0b5..a5d175c 100644 --- a/fs/aufs/vfsub.c +++ b/fs/aufs/vfsub.c @@ -130,9 +130,17 @@ void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1, int vfsub_create(struct inode *dir, struct path *path, int mode) { int err; + struct dentry *d; IMustLock(dir); + d = path->dentry; + path->dentry = d->d_parent; + err = security_path_mknod(path, path->dentry, mode, 0); + path->dentry = d; + if (unlikely(err)) + goto out; + if (au_test_fs_null_nd(dir->i_sb)) err = vfs_create(dir, path->dentry, mode, NULL); else { @@ -161,15 +169,24 @@ int vfsub_create(struct inode *dir, struct path *path, int mode) /*ignore*/ } + out: return err; } int vfsub_symlink(struct inode *dir, struct path *path, const char *symname) { int err; + struct dentry *d; IMustLock(dir); + d = path->dentry; + path->dentry = d->d_parent; + err = security_path_symlink(path, path->dentry, symname); + path->dentry = d; + if (unlikely(err)) + goto out; + err = vfs_symlink(dir, path->dentry, symname); if (!err) { struct path tmp = *path; @@ -182,15 +199,25 @@ int vfsub_symlink(struct inode *dir, struct path *path, const char *symname) } /*ignore*/ } + + out: return err; } int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev) { int err; + struct dentry *d; IMustLock(dir); + d = path->dentry; + path->dentry = d->d_parent; + err = security_path_mknod(path, path->dentry, mode, dev); + path->dentry = d; + if (unlikely(err)) + goto out; + err = vfs_mknod(dir, path->dentry, mode, dev); if (!err) { struct path tmp = *path; @@ -203,15 +230,25 @@ int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev) } /*ignore*/ } + + out: return err; } int vfsub_link(struct dentry *src_dentry, struct inode *dir, struct path *path) { int err; + struct dentry *d; IMustLock(dir); + d = path->dentry; + path->dentry = d->d_parent; + err = security_path_link(src_dentry, path, path->dentry); + path->dentry = d; + if (unlikely(err)) + goto out; + lockdep_off(); err = vfs_link(src_dentry, dir, path->dentry); lockdep_on(); @@ -229,6 +266,8 @@ int vfsub_link(struct dentry *src_dentry, struct inode *dir, struct path *path) } /*ignore*/ } + + out: return err; } @@ -237,19 +276,28 @@ int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry, { int err; struct path tmp = { - .dentry = path->dentry->d_parent, .mnt = path->mnt }; + struct dentry *d; IMustLock(dir); IMustLock(src_dir); + d = path->dentry; + path->dentry = d->d_parent; + tmp.dentry = src_dentry->d_parent; + err = security_path_rename(&tmp, src_dentry, path, path->dentry); + path->dentry = d; + if (unlikely(err)) + goto out; + lockdep_off(); err = vfs_rename(src_dir, src_dentry, dir, path->dentry); lockdep_on(); if (!err) { int did; + tmp.dentry = d->d_parent; vfsub_update_h_iattr(&tmp, &did); if (did) { tmp.dentry = src_dentry; @@ -259,15 +307,25 @@ int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry, } /*ignore*/ } + + out: return err; } int vfsub_mkdir(struct inode *dir, struct path *path, int mode) { int err; + struct dentry *d; IMustLock(dir); + d = path->dentry; + path->dentry = d->d_parent; + err = security_path_mkdir(path, path->dentry, mode); + path->dentry = d; + if (unlikely(err)) + goto out; + err = vfs_mkdir(dir, path->dentry, mode); if (!err) { struct path tmp = *path; @@ -280,15 +338,25 @@ int vfsub_mkdir(struct inode *dir, struct path *path, int mode) } /*ignore*/ } + + out: return err; } int vfsub_rmdir(struct inode *dir, struct path *path) { int err; + struct dentry *d; IMustLock(dir); + d = path->dentry; + path->dentry = d->d_parent; + err = security_path_rmdir(path, path->dentry); + path->dentry = d; + if (unlikely(err)) + goto out; + lockdep_off(); err = vfs_rmdir(dir, path->dentry); lockdep_on(); @@ -301,6 +369,7 @@ int vfsub_rmdir(struct inode *dir, struct path *path) vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/ } + out: return err; } @@ -419,6 +488,8 @@ int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr, } err = locks_verify_truncate(h_inode, h_file, length); + if (!err) + err = security_path_truncate(h_path, length, attr); if (!err) { lockdep_off(); err = do_truncate(h_path->dentry, length, attr, h_file); @@ -580,6 +651,12 @@ static void call_unlink(void *args) IMustLock(a->dir); + a->path->dentry = d->d_parent; + *a->errp = security_path_unlink(a->path, d); + a->path->dentry = d; + if (unlikely(*a->errp)) + return; + if (!stop_sillyrename) dget(d); h_inode = d->d_inode; diff --git a/fs/aufs/whout.c b/fs/aufs/whout.c index d322460..f2343d2 100644 --- a/fs/aufs/whout.c +++ b/fs/aufs/whout.c @@ -205,7 +205,7 @@ static int do_unlink_wh(struct inode *h_dir, struct path *h_path) * this may be a violation of unix fs semantics. */ force = (h_dir->i_mode & S_ISVTX) - && h_path->dentry->d_inode->i_uid != current->fsuid; + && h_path->dentry->d_inode->i_uid != current_fsuid(); return vfsub_unlink(h_dir, h_path, force); } @@ -273,7 +273,7 @@ static int test_linkable(struct dentry *h_root) { struct inode *h_dir = h_root->d_inode; - if (h_dir->i_op && h_dir->i_op->link) + if (h_dir->i_op->link) return 0; AuErr("%.*s (%s) doesn't support link(2), use noplink and rw+nolwh\n", diff --git a/fs/aufs/xino.c b/fs/aufs/xino.c index 664db26..bc19b86 100644 --- a/fs/aufs/xino.c +++ b/fs/aufs/xino.c @@ -146,7 +146,8 @@ static struct file *au_xino_create2(struct file *base_file, } file = dentry_open(dget(dentry), mntget(base_file->f_vfsmnt), - O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE); + O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE, + current_cred()); if (IS_ERR(file)) { AuErr("%.*s open err %ld\n", AuLNPair(name), PTR_ERR(file)); goto out_dput;