Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * linux/fs/ocfs2/ioctl.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 2006 Herbert Poetzl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * adapted from Remy Card's ext2/ioctl.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/mount.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/compat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <cluster/masklog.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include "ocfs2.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include "alloc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include "dlmglue.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include "file.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include "inode.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include "journal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include "ocfs2_fs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include "ioctl.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include "resize.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include "refcounttree.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include "sysfile.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include "dir.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #include "buffer_head_io.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #include "suballoc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #include "move_extents.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define o2info_from_user(a, b)	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 		copy_from_user(&(a), (b), sizeof(a))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define o2info_to_user(a, b)	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 		copy_to_user((typeof(a) __user *)b, &(a), sizeof(a))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  * This is just a best-effort to tell userspace that this request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  * caused the error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) static inline void o2info_set_request_error(struct ocfs2_info_request *kreq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 					struct ocfs2_info_request __user *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	kreq->ir_flags |= OCFS2_INFO_FL_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	(void)put_user(kreq->ir_flags, (__u32 __user *)&(req->ir_flags));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) static inline void o2info_set_request_filled(struct ocfs2_info_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	req->ir_flags |= OCFS2_INFO_FL_FILLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) static inline void o2info_clear_request_filled(struct ocfs2_info_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	req->ir_flags &= ~OCFS2_INFO_FL_FILLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) static inline int o2info_coherent(struct ocfs2_info_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	return (!(req->ir_flags & OCFS2_INFO_FL_NON_COHERENT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) static int ocfs2_get_inode_attr(struct inode *inode, unsigned *flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	status = ocfs2_inode_lock(inode, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 		return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	ocfs2_get_inode_flags(OCFS2_I(inode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	*flags = OCFS2_I(inode)->ip_attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	ocfs2_inode_unlock(inode, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 				unsigned mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	struct ocfs2_inode_info *ocfs2_inode = OCFS2_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	handle_t *handle = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	struct buffer_head *bh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	unsigned oldflags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	inode_lock(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	status = ocfs2_inode_lock(inode, &bh, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	status = -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	if (!inode_owner_or_capable(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		goto bail_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	if (!S_ISDIR(inode->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		flags &= ~OCFS2_DIRSYNC_FL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	oldflags = ocfs2_inode->ip_attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	flags = flags & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	flags |= oldflags & ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	status = vfs_ioc_setflags_prepare(inode, oldflags, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		goto bail_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	if (IS_ERR(handle)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		status = PTR_ERR(handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		goto bail_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	ocfs2_inode->ip_attr = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	ocfs2_set_inode_flags(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	status = ocfs2_mark_inode_dirty(handle, inode, bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	ocfs2_commit_trans(osb, handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) bail_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	ocfs2_inode_unlock(inode, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) bail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	inode_unlock(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) static int ocfs2_info_handle_blocksize(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 				       struct ocfs2_info_request __user *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	struct ocfs2_info_blocksize oib;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	if (o2info_from_user(oib, req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	oib.ib_blocksize = inode->i_sb->s_blocksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	o2info_set_request_filled(&oib.ib_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	if (o2info_to_user(oib, req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static int ocfs2_info_handle_clustersize(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 					 struct ocfs2_info_request __user *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	struct ocfs2_info_clustersize oic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	if (o2info_from_user(oic, req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	oic.ic_clustersize = osb->s_clustersize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	o2info_set_request_filled(&oic.ic_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	if (o2info_to_user(oic, req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) static int ocfs2_info_handle_maxslots(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 				      struct ocfs2_info_request __user *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	struct ocfs2_info_maxslots oim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	if (o2info_from_user(oim, req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	oim.im_max_slots = osb->max_slots;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	o2info_set_request_filled(&oim.im_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	if (o2info_to_user(oim, req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static int ocfs2_info_handle_label(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 				   struct ocfs2_info_request __user *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	struct ocfs2_info_label oil;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	if (o2info_from_user(oil, req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	memcpy(oil.il_label, osb->vol_label, OCFS2_MAX_VOL_LABEL_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	o2info_set_request_filled(&oil.il_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	if (o2info_to_user(oil, req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) static int ocfs2_info_handle_uuid(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 				  struct ocfs2_info_request __user *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	struct ocfs2_info_uuid oiu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	if (o2info_from_user(oiu, req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	memcpy(oiu.iu_uuid_str, osb->uuid_str, OCFS2_TEXT_UUID_LEN + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	o2info_set_request_filled(&oiu.iu_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	if (o2info_to_user(oiu, req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) static int ocfs2_info_handle_fs_features(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 					 struct ocfs2_info_request __user *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	struct ocfs2_info_fs_features oif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	if (o2info_from_user(oif, req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	oif.if_compat_features = osb->s_feature_compat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	oif.if_incompat_features = osb->s_feature_incompat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	oif.if_ro_compat_features = osb->s_feature_ro_compat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	o2info_set_request_filled(&oif.if_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	if (o2info_to_user(oif, req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) static int ocfs2_info_handle_journal_size(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 					  struct ocfs2_info_request __user *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	struct ocfs2_info_journal_size oij;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	if (o2info_from_user(oij, req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	oij.ij_journal_size = i_size_read(osb->journal->j_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	o2info_set_request_filled(&oij.ij_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	if (o2info_to_user(oij, req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) static int ocfs2_info_scan_inode_alloc(struct ocfs2_super *osb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 				       struct inode *inode_alloc, u64 blkno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 				       struct ocfs2_info_freeinode *fi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 				       u32 slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	int status = 0, unlock = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	struct buffer_head *bh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	struct ocfs2_dinode *dinode_alloc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	if (inode_alloc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 		inode_lock(inode_alloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	if (inode_alloc && o2info_coherent(&fi->ifi_req)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		status = ocfs2_inode_lock(inode_alloc, &bh, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 		if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 			mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 			goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 		unlock = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 		status = ocfs2_read_blocks_sync(osb, blkno, 1, &bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 		if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 			mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 			goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	dinode_alloc = (struct ocfs2_dinode *)bh->b_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	fi->ifi_stat[slot].lfi_total =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 		le32_to_cpu(dinode_alloc->id1.bitmap1.i_total);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	fi->ifi_stat[slot].lfi_free =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 		le32_to_cpu(dinode_alloc->id1.bitmap1.i_total) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		le32_to_cpu(dinode_alloc->id1.bitmap1.i_used);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) bail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	if (unlock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 		ocfs2_inode_unlock(inode_alloc, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	if (inode_alloc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 		inode_unlock(inode_alloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) static int ocfs2_info_handle_freeinode(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 				       struct ocfs2_info_request __user *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	u64 blkno = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	char namebuf[40];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	int status, type = INODE_ALLOC_SYSTEM_INODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	struct ocfs2_info_freeinode *oifi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	struct inode *inode_alloc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	oifi = kzalloc(sizeof(struct ocfs2_info_freeinode), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	if (!oifi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 		status = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 		mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	if (o2info_from_user(*oifi, req)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 		status = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	oifi->ifi_slotnum = osb->max_slots;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	for (i = 0; i < oifi->ifi_slotnum; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 		if (o2info_coherent(&oifi->ifi_req)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 			inode_alloc = ocfs2_get_system_file_inode(osb, type, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 			if (!inode_alloc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 				mlog(ML_ERROR, "unable to get alloc inode in "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 				    "slot %u\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 				status = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 				goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 			ocfs2_sprintf_system_inode_name(namebuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 							sizeof(namebuf),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 							type, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 			status = ocfs2_lookup_ino_from_name(osb->sys_root_inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 							    namebuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 							    strlen(namebuf),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 							    &blkno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 			if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 				status = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 				goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		status = ocfs2_info_scan_inode_alloc(osb, inode_alloc, blkno, oifi, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 		iput(inode_alloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 		inode_alloc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 		if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 			goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	o2info_set_request_filled(&oifi->ifi_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	if (o2info_to_user(*oifi, req)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 		status = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) bail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 		o2info_set_request_error(&oifi->ifi_req, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	kfree(oifi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) static void o2ffg_update_histogram(struct ocfs2_info_free_chunk_list *hist,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 				   unsigned int chunksize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	u32 index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	index = __ilog2_u32(chunksize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	if (index >= OCFS2_INFO_MAX_HIST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 		index = OCFS2_INFO_MAX_HIST - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	hist->fc_chunks[index]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	hist->fc_clusters[index] += chunksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) static void o2ffg_update_stats(struct ocfs2_info_freefrag_stats *stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 			       unsigned int chunksize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	if (chunksize > stats->ffs_max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 		stats->ffs_max = chunksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	if (chunksize < stats->ffs_min)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 		stats->ffs_min = chunksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	stats->ffs_avg += chunksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	stats->ffs_free_chunks_real++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) static void ocfs2_info_update_ffg(struct ocfs2_info_freefrag *ffg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 				  unsigned int chunksize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	o2ffg_update_histogram(&(ffg->iff_ffs.ffs_fc_hist), chunksize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	o2ffg_update_stats(&(ffg->iff_ffs), chunksize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) static int ocfs2_info_freefrag_scan_chain(struct ocfs2_super *osb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 					  struct inode *gb_inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 					  struct ocfs2_dinode *gb_dinode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 					  struct ocfs2_chain_rec *rec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 					  struct ocfs2_info_freefrag *ffg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 					  u32 chunks_in_group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	int status = 0, used;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	u64 blkno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	struct buffer_head *bh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	struct ocfs2_group_desc *bg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	unsigned int max_bits, num_clusters;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	unsigned int offset = 0, cluster, chunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	unsigned int chunk_free, last_chunksize = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	if (!le32_to_cpu(rec->c_free))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 		goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 		if (!bg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 			blkno = le64_to_cpu(rec->c_blkno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 			blkno = le64_to_cpu(bg->bg_next_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 		if (bh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 			brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 			bh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 		if (o2info_coherent(&ffg->iff_req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 			status = ocfs2_read_group_descriptor(gb_inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 							     gb_dinode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 							     blkno, &bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 			status = ocfs2_read_blocks_sync(osb, blkno, 1, &bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 		if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 			mlog(ML_ERROR, "Can't read the group descriptor # "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 			     "%llu from device.", (unsigned long long)blkno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 			status = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 			goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 		bg = (struct ocfs2_group_desc *)bh->b_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 		if (!le16_to_cpu(bg->bg_free_bits_count))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 		max_bits = le16_to_cpu(bg->bg_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 		offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 		for (chunk = 0; chunk < chunks_in_group; chunk++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 			 * last chunk may be not an entire one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 			if ((offset + ffg->iff_chunksize) > max_bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 				num_clusters = max_bits - offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 				num_clusters = ffg->iff_chunksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 			chunk_free = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 			for (cluster = 0; cluster < num_clusters; cluster++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 				used = ocfs2_test_bit(offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 						(unsigned long *)bg->bg_bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 				 * - chunk_free counts free clusters in #N chunk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 				 * - last_chunksize records the size(in) clusters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 				 *   for the last real free chunk being counted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 				if (!used) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 					last_chunksize++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 					chunk_free++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 				if (used && last_chunksize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 					ocfs2_info_update_ffg(ffg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 							      last_chunksize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 					last_chunksize = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 				offset++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 			if (chunk_free == ffg->iff_chunksize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 				ffg->iff_ffs.ffs_free_chunks++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 		 * need to update the info for last free chunk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 		if (last_chunksize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 			ocfs2_info_update_ffg(ffg, last_chunksize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 	} while (le64_to_cpu(bg->bg_next_group));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) bail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) static int ocfs2_info_freefrag_scan_bitmap(struct ocfs2_super *osb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 					   struct inode *gb_inode, u64 blkno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 					   struct ocfs2_info_freefrag *ffg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 	u32 chunks_in_group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 	int status = 0, unlock = 0, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	struct buffer_head *bh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 	struct ocfs2_chain_list *cl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	struct ocfs2_chain_rec *rec = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 	struct ocfs2_dinode *gb_dinode = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	if (gb_inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 		inode_lock(gb_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	if (o2info_coherent(&ffg->iff_req)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 		status = ocfs2_inode_lock(gb_inode, &bh, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 		if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 			mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 			goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 		unlock = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 		status = ocfs2_read_blocks_sync(osb, blkno, 1, &bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 		if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 			mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 			goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 	gb_dinode = (struct ocfs2_dinode *)bh->b_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	cl = &(gb_dinode->id2.i_chain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	 * Chunksize(in) clusters from userspace should be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 	 * less than clusters in a group.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	if (ffg->iff_chunksize > le16_to_cpu(cl->cl_cpg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 		status = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 		goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 	memset(&ffg->iff_ffs, 0, sizeof(struct ocfs2_info_freefrag_stats));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	ffg->iff_ffs.ffs_min = ~0U;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 	ffg->iff_ffs.ffs_clusters =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 			le32_to_cpu(gb_dinode->id1.bitmap1.i_total);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	ffg->iff_ffs.ffs_free_clusters = ffg->iff_ffs.ffs_clusters -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 			le32_to_cpu(gb_dinode->id1.bitmap1.i_used);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 	chunks_in_group = le16_to_cpu(cl->cl_cpg) / ffg->iff_chunksize + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 	for (i = 0; i < le16_to_cpu(cl->cl_next_free_rec); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 		rec = &(cl->cl_recs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 		status = ocfs2_info_freefrag_scan_chain(osb, gb_inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 							gb_dinode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 							rec, ffg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 							chunks_in_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 		if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 			goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 	if (ffg->iff_ffs.ffs_free_chunks_real)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 		ffg->iff_ffs.ffs_avg = (ffg->iff_ffs.ffs_avg /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 					ffg->iff_ffs.ffs_free_chunks_real);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) bail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 	if (unlock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 		ocfs2_inode_unlock(gb_inode, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	if (gb_inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 		inode_unlock(gb_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 	iput(gb_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 	brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) static int ocfs2_info_handle_freefrag(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 				      struct ocfs2_info_request __user *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 	u64 blkno = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 	char namebuf[40];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 	int status, type = GLOBAL_BITMAP_SYSTEM_INODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 	struct ocfs2_info_freefrag *oiff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 	struct inode *gb_inode = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 	oiff = kzalloc(sizeof(struct ocfs2_info_freefrag), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 	if (!oiff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 		status = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 		mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 	if (o2info_from_user(*oiff, req)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 		status = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 	 * chunksize from userspace should be power of 2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 	if ((oiff->iff_chunksize & (oiff->iff_chunksize - 1)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 	    (!oiff->iff_chunksize)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 		status = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 		goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 	if (o2info_coherent(&oiff->iff_req)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 		gb_inode = ocfs2_get_system_file_inode(osb, type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 						       OCFS2_INVALID_SLOT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 		if (!gb_inode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 			mlog(ML_ERROR, "unable to get global_bitmap inode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 			status = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 			goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 		ocfs2_sprintf_system_inode_name(namebuf, sizeof(namebuf), type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 						OCFS2_INVALID_SLOT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 		status = ocfs2_lookup_ino_from_name(osb->sys_root_inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 						    namebuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 						    strlen(namebuf),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 						    &blkno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 		if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 			status = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 			goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 	status = ocfs2_info_freefrag_scan_bitmap(osb, gb_inode, blkno, oiff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 	if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 		goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 	o2info_set_request_filled(&oiff->iff_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 	if (o2info_to_user(*oiff, req)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 		status = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 	status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) bail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 	if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 		o2info_set_request_error(&oiff->iff_req, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 	kfree(oiff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) static int ocfs2_info_handle_unknown(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 				     struct ocfs2_info_request __user *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 	struct ocfs2_info_request oir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 	if (o2info_from_user(oir, req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 	o2info_clear_request_filled(&oir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 	if (o2info_to_user(oir, req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)  * Validate and distinguish OCFS2_IOC_INFO requests.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)  * - validate the magic number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)  * - distinguish different requests.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)  * - validate size of different requests.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) static int ocfs2_info_handle_request(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 				     struct ocfs2_info_request __user *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 	int status = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 	struct ocfs2_info_request oir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 	if (o2info_from_user(oir, req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 		goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 	status = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 	if (oir.ir_magic != OCFS2_INFO_MAGIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 		goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 	switch (oir.ir_code) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 	case OCFS2_INFO_BLOCKSIZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 		if (oir.ir_size == sizeof(struct ocfs2_info_blocksize))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 			status = ocfs2_info_handle_blocksize(inode, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 	case OCFS2_INFO_CLUSTERSIZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 		if (oir.ir_size == sizeof(struct ocfs2_info_clustersize))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 			status = ocfs2_info_handle_clustersize(inode, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 	case OCFS2_INFO_MAXSLOTS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 		if (oir.ir_size == sizeof(struct ocfs2_info_maxslots))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 			status = ocfs2_info_handle_maxslots(inode, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 	case OCFS2_INFO_LABEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 		if (oir.ir_size == sizeof(struct ocfs2_info_label))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 			status = ocfs2_info_handle_label(inode, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 	case OCFS2_INFO_UUID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 		if (oir.ir_size == sizeof(struct ocfs2_info_uuid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 			status = ocfs2_info_handle_uuid(inode, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 	case OCFS2_INFO_FS_FEATURES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 		if (oir.ir_size == sizeof(struct ocfs2_info_fs_features))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 			status = ocfs2_info_handle_fs_features(inode, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 	case OCFS2_INFO_JOURNAL_SIZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 		if (oir.ir_size == sizeof(struct ocfs2_info_journal_size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 			status = ocfs2_info_handle_journal_size(inode, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 	case OCFS2_INFO_FREEINODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 		if (oir.ir_size == sizeof(struct ocfs2_info_freeinode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 			status = ocfs2_info_handle_freeinode(inode, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 	case OCFS2_INFO_FREEFRAG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 		if (oir.ir_size == sizeof(struct ocfs2_info_freefrag))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 			status = ocfs2_info_handle_freefrag(inode, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 		status = ocfs2_info_handle_unknown(inode, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) bail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) static int ocfs2_get_request_ptr(struct ocfs2_info *info, int idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 				 u64 *req_addr, int compat_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 	int status = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 	u64 __user *bp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 	if (compat_flag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 		 * pointer bp stores the base address of a pointers array,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 		 * which collects all addresses of separate request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 		bp = (u64 __user *)(unsigned long)compat_ptr(info->oi_requests);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 		BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 		bp = (u64 __user *)(unsigned long)(info->oi_requests);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 	if (o2info_from_user(*req_addr, bp + idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 		goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 	status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) bail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)  * OCFS2_IOC_INFO handles an array of requests passed from userspace.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)  * ocfs2_info_handle() recevies a large info aggregation, grab and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)  * validate the request count from header, then break it into small
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)  * pieces, later specific handlers can handle them one by one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)  * Idea here is to make each separate request small enough to ensure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)  * a better backward&forward compatibility, since a small piece of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)  * request will be less likely to be broken if disk layout get changed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) static int ocfs2_info_handle(struct inode *inode, struct ocfs2_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 			     int compat_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 	int i, status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 	u64 req_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 	struct ocfs2_info_request __user *reqp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) 	if ((info->oi_count > OCFS2_INFO_MAX_REQUEST) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) 	    (!info->oi_requests)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 		status = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 		goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) 	for (i = 0; i < info->oi_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) 		status = ocfs2_get_request_ptr(info, i, &req_addr, compat_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) 		if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) 		reqp = (struct ocfs2_info_request __user *)(unsigned long)req_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) 		if (!reqp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) 			status = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) 			goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) 		status = ocfs2_info_handle_request(inode, reqp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) 		if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) bail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) long ocfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) 	struct inode *inode = file_inode(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) 	unsigned int flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) 	int new_clusters;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) 	int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) 	struct ocfs2_space_resv sr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) 	struct ocfs2_new_group_input input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) 	struct reflink_arguments args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) 	const char __user *old_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) 	const char __user *new_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) 	bool preserve;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) 	struct ocfs2_info info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) 	void __user *argp = (void __user *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) 	case OCFS2_IOC_GETFLAGS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) 		status = ocfs2_get_inode_attr(inode, &flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) 		if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) 			return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) 		flags &= OCFS2_FL_VISIBLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) 		return put_user(flags, (int __user *) arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) 	case OCFS2_IOC_SETFLAGS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) 		if (get_user(flags, (int __user *) arg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) 		status = mnt_want_write_file(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) 		if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) 			return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) 		status = ocfs2_set_inode_attr(inode, flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) 			OCFS2_FL_MODIFIABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) 		mnt_drop_write_file(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) 		return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) 	case OCFS2_IOC_RESVSP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) 	case OCFS2_IOC_RESVSP64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) 	case OCFS2_IOC_UNRESVSP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) 	case OCFS2_IOC_UNRESVSP64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) 		if (copy_from_user(&sr, (int __user *) arg, sizeof(sr)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) 		return ocfs2_change_file_space(filp, cmd, &sr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) 	case OCFS2_IOC_GROUP_EXTEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) 		if (!capable(CAP_SYS_RESOURCE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) 			return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) 		if (get_user(new_clusters, (int __user *)arg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) 		status = mnt_want_write_file(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) 		if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) 			return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) 		status = ocfs2_group_extend(inode, new_clusters);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) 		mnt_drop_write_file(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) 		return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) 	case OCFS2_IOC_GROUP_ADD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) 	case OCFS2_IOC_GROUP_ADD64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) 		if (!capable(CAP_SYS_RESOURCE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) 			return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) 		if (copy_from_user(&input, (int __user *) arg, sizeof(input)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) 		status = mnt_want_write_file(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) 		if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) 			return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) 		status = ocfs2_group_add(inode, &input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) 		mnt_drop_write_file(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) 		return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) 	case OCFS2_IOC_REFLINK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) 		if (copy_from_user(&args, argp, sizeof(args)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) 		old_path = (const char __user *)(unsigned long)args.old_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) 		new_path = (const char __user *)(unsigned long)args.new_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) 		preserve = (args.preserve != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) 		return ocfs2_reflink_ioctl(inode, old_path, new_path, preserve);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) 	case OCFS2_IOC_INFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) 		if (copy_from_user(&info, argp, sizeof(struct ocfs2_info)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) 		return ocfs2_info_handle(inode, &info, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) 	case FITRIM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) 		struct super_block *sb = inode->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) 		struct request_queue *q = bdev_get_queue(sb->s_bdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) 		struct fstrim_range range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) 		int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) 		if (!capable(CAP_SYS_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) 			return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) 		if (!blk_queue_discard(q))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) 			return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) 		if (copy_from_user(&range, argp, sizeof(range)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) 		range.minlen = max_t(u64, q->limits.discard_granularity,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) 				     range.minlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) 		ret = ocfs2_trim_fs(sb, &range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) 		if (copy_to_user(argp, &range, sizeof(range)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) 	case OCFS2_IOC_MOVE_EXT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) 		return ocfs2_ioctl_move_extents(filp, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) 		return -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) long ocfs2_compat_ioctl(struct file *file, unsigned cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) 	bool preserve;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) 	struct reflink_arguments args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) 	struct inode *inode = file_inode(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) 	struct ocfs2_info info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) 	void __user *argp = (void __user *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) 	case OCFS2_IOC32_GETFLAGS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) 		cmd = OCFS2_IOC_GETFLAGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) 	case OCFS2_IOC32_SETFLAGS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) 		cmd = OCFS2_IOC_SETFLAGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) 	case OCFS2_IOC_RESVSP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) 	case OCFS2_IOC_RESVSP64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) 	case OCFS2_IOC_UNRESVSP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) 	case OCFS2_IOC_UNRESVSP64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) 	case OCFS2_IOC_GROUP_EXTEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) 	case OCFS2_IOC_GROUP_ADD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) 	case OCFS2_IOC_GROUP_ADD64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) 	case OCFS2_IOC_REFLINK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) 		if (copy_from_user(&args, argp, sizeof(args)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) 		preserve = (args.preserve != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) 		return ocfs2_reflink_ioctl(inode, compat_ptr(args.old_path),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) 					   compat_ptr(args.new_path), preserve);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) 	case OCFS2_IOC_INFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) 		if (copy_from_user(&info, argp, sizeof(struct ocfs2_info)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) 		return ocfs2_info_handle(inode, &info, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) 	case FITRIM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) 	case OCFS2_IOC_MOVE_EXT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) 		return -ENOIOCTLCMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) 	return ocfs2_ioctl(file, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) #endif