Re: [PATCH 4/4] Adds ioctl interface support for ext4 project

Started by Jan Kara on Sep 24, 2014

open the first message on its own page

Message details and related content
On Wed 24-09-14 22:04:30, Li Xi wrote:
This patch adds ioctl interface for setting/getting project of ext4.
  One more thing...
Signed-off-by: Li Xi <redacted>
---
 Documentation/filesystems/ext4.txt |    4 ++
 fs/ext4/ext4.h                     |    2 +
 fs/ext4/ioctl.c                    |   85 ++++++++++++++++++++++++++++++++++++
 3 files changed, 91 insertions(+), 0 deletions(-)

+	case EXT4_IOC_SETPROJECT:
+	{
+		__u32 projid;
+		int err;
+		handle_t *handle;
+		kprojid_t kprojid;
+		struct ext4_iloc iloc;
+		struct ext4_inode *raw_inode;
+
+		struct dquot *transfer_to[EXT4_MAXQUOTAS] = { };
+
+		/* Make sure caller can change project. */
+		if (!capable(CAP_SYS_ADMIN))
+			return -EACCES;
  I realized you forgot to check EXT4_FEATURE_RO_COMPAT_PROJECT here...

								Honza
+
+		if (get_user(projid, (__u32 __user *) arg))
+			return -EFAULT;
+
+		kprojid = make_kprojid(&init_user_ns, (projid_t)projid);
+
+		if (projid_eq(kprojid, EXT4_I(inode)->i_projid))
+			return 0;
+
+		err = mnt_want_write_file(filp);
+		if (err)
+			return err;
+
+		err = -EPERM;
+		mutex_lock(&inode->i_mutex);
+		/* Is it quota file? Do not allow user to mess with it */
+		if (IS_NOQUOTA(inode))
+			goto project_out;
+
+		dquot_initialize(inode);
+
+		handle = ext4_journal_start(inode, EXT4_HT_QUOTA,
+			EXT4_QUOTA_INIT_BLOCKS(sb) +
+			EXT4_QUOTA_DEL_BLOCKS(sb) + 3);
+		if (IS_ERR(handle)) {
+			err = PTR_ERR(handle);
+			goto project_out;
+		}
+
+		err = ext4_reserve_inode_write(handle, inode, &iloc);
+		if (err)
+			goto project_stop;
+
+		raw_inode = ext4_raw_inode(&iloc);
+		if ((EXT4_INODE_SIZE(inode->i_sb) <=
+		     EXT4_GOOD_OLD_INODE_SIZE) ||
+		    (!EXT4_FITS_IN_INODE(raw_inode, ei, i_projid))) {
+		    	err = -EFBIG;
+		    	goto project_stop;
+		}
+
+		transfer_to[PRJQUOTA] = dqget(sb, make_kqid_projid(kprojid));
+		if (!transfer_to[PRJQUOTA])
+			goto project_set;
+
+		err = __dquot_transfer(inode, transfer_to);
+		dqput(transfer_to[PRJQUOTA]);
+		if (err)
+			goto project_stop;
+
+project_set:
+		EXT4_I(inode)->i_projid = kprojid;
+		inode->i_ctime = ext4_current_time(inode);
+		err = ext4_mark_iloc_dirty(handle, inode, &iloc);
+project_stop:
+		ext4_journal_stop(handle);
+project_out:
+		mutex_unlock(&inode->i_mutex);
+		mnt_drop_write_file(filp);
+		return err;
+	}
 	default:
 		return -ENOTTY;
 	}
-- 
1.7.1
-- 
Jan Kara [off-list ref]
SUSE Labs, CR
Keyboard shortcuts
hback out one level
jnext message in thread / next series-diff position
kprevious message in thread / previous series-diff position
ldrill in
Escclose help / fold thread tree
?toggle this help