From: Andreas Gruenbacher <agruen@suse.de>
Subject: Allow filesystems to handle MAY_APPEND
Patch-mainline: not yet
    
The MS_WITHAPPEND super_block flag tells the vfs that the permission
inode operation understands the MAY_APPEND flag. This is required for
implementing permission models which go beyond the traditional UNIX
semantics.

If a filesystem does not set the flag, the behavior is unchanged.

Signed-off-by: Andreas Gruenbacher <agruen@suse.de>

---
 fs/namei.c         |    6 +++++-
 include/linux/fs.h |    2 ++
 2 files changed, 7 insertions(+), 1 deletion(-)

--- a/fs/namei.c
+++ b/fs/namei.c
@@ -252,6 +252,7 @@ int generic_permission(struct inode *ino
 int inode_permission(struct inode *inode, int mask)
 {
 	int retval;
+	int submask = mask;
 
 	if (mask & MAY_WRITE) {
 		umode_t mode = inode->i_mode;
@@ -270,8 +271,11 @@ int inode_permission(struct inode *inode
 			return -EACCES;
 	}
 
+	if (!IS_WITHAPPEND(inode))
+		submask &= ~MAY_APPEND;
+
 	if (inode->i_op->permission)
-		retval = inode->i_op->permission(inode, mask);
+		retval = inode->i_op->permission(inode, submask);
 	else
 		retval = generic_permission(inode, mask, inode->i_op->check_acl);
 
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -209,6 +209,7 @@ struct inodes_stat_t {
 #define MS_KERNMOUNT	(1<<22) /* this is a kern_mount call */
 #define MS_I_VERSION	(1<<23) /* Update inode I_version field */
 #define MS_STRICTATIME	(1<<24) /* Always perform atime updates */
+#define MS_WITHAPPEND	(1<<25) /* iop->permission() understands MAY_APPEND */
 #define MS_ACTIVE	(1<<30)
 #define MS_NOUSER	(1<<31)
 
@@ -259,6 +260,7 @@ struct inodes_stat_t {
 #define IS_MANDLOCK(inode)	__IS_FLG(inode, MS_MANDLOCK)
 #define IS_NOATIME(inode)   __IS_FLG(inode, MS_RDONLY|MS_NOATIME)
 #define IS_I_VERSION(inode)   __IS_FLG(inode, MS_I_VERSION)
+#define IS_WITHAPPEND(inode)	__IS_FLG(inode, MS_WITHAPPEND)
 
 #define IS_NOQUOTA(inode)	((inode)->i_flags & S_NOQUOTA)
 #define IS_APPEND(inode)	((inode)->i_flags & S_APPEND)
