^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) #include <linux/ceph/ceph_debug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include <linux/in.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include "super.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include "mds_client.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include "ioctl.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/ceph/striper.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * ioctls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * get and set the file layout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) static long ceph_ioctl_get_layout(struct file *file, void __user *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) struct ceph_inode_info *ci = ceph_inode(file_inode(file));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) struct ceph_ioctl_layout l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) err = ceph_do_getattr(file_inode(file), CEPH_STAT_CAP_LAYOUT, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) if (!err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) l.stripe_unit = ci->i_layout.stripe_unit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) l.stripe_count = ci->i_layout.stripe_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) l.object_size = ci->i_layout.object_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) l.data_pool = ci->i_layout.pool_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) l.preferred_osd = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) if (copy_to_user(arg, &l, sizeof(l)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static long __validate_layout(struct ceph_mds_client *mdsc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct ceph_ioctl_layout *l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) /* validate striping parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) if ((l->object_size & ~PAGE_MASK) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) (l->stripe_unit & ~PAGE_MASK) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) ((unsigned)l->stripe_unit != 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) ((unsigned)l->object_size % (unsigned)l->stripe_unit)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) /* make sure it's a valid data pool */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) mutex_lock(&mdsc->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) for (i = 0; i < mdsc->mdsmap->m_num_data_pg_pools; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) if (mdsc->mdsmap->m_data_pg_pools[i] == l->data_pool) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) mutex_unlock(&mdsc->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) return 0;
^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 long ceph_ioctl_set_layout(struct file *file, void __user *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct inode *inode = file_inode(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct ceph_mds_request *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct ceph_ioctl_layout l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) struct ceph_inode_info *ci = ceph_inode(file_inode(file));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) struct ceph_ioctl_layout nl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) if (copy_from_user(&l, arg, sizeof(l)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /* validate changed params against current layout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) err = ceph_do_getattr(file_inode(file), CEPH_STAT_CAP_LAYOUT, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) memset(&nl, 0, sizeof(nl));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) if (l.stripe_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) nl.stripe_count = l.stripe_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) nl.stripe_count = ci->i_layout.stripe_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (l.stripe_unit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) nl.stripe_unit = l.stripe_unit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) nl.stripe_unit = ci->i_layout.stripe_unit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (l.object_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) nl.object_size = l.object_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) nl.object_size = ci->i_layout.object_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (l.data_pool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) nl.data_pool = l.data_pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) nl.data_pool = ci->i_layout.pool_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) /* this is obsolete, and always -1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) nl.preferred_osd = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) err = __validate_layout(mdsc, &nl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SETLAYOUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) USE_AUTH_MDS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (IS_ERR(req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return PTR_ERR(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) req->r_inode = inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) ihold(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) req->r_num_caps = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) req->r_inode_drop = CEPH_CAP_FILE_SHARED | CEPH_CAP_FILE_EXCL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) req->r_args.setlayout.layout.fl_stripe_unit =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) cpu_to_le32(l.stripe_unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) req->r_args.setlayout.layout.fl_stripe_count =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) cpu_to_le32(l.stripe_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) req->r_args.setlayout.layout.fl_object_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) cpu_to_le32(l.object_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) req->r_args.setlayout.layout.fl_pg_pool = cpu_to_le32(l.data_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) err = ceph_mdsc_do_request(mdsc, NULL, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) ceph_mdsc_put_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * Set a layout policy on a directory inode. All items in the tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * rooted at this inode will inherit this layout on creation,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * (It doesn't apply retroactively )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * unless a subdirectory has its own layout policy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static long ceph_ioctl_set_layout_policy (struct file *file, void __user *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) struct inode *inode = file_inode(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) struct ceph_mds_request *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct ceph_ioctl_layout l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /* copy and validate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (copy_from_user(&l, arg, sizeof(l)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) err = __validate_layout(mdsc, &l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SETDIRLAYOUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) USE_AUTH_MDS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (IS_ERR(req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return PTR_ERR(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) req->r_inode = inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) ihold(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) req->r_num_caps = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) req->r_args.setlayout.layout.fl_stripe_unit =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) cpu_to_le32(l.stripe_unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) req->r_args.setlayout.layout.fl_stripe_count =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) cpu_to_le32(l.stripe_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) req->r_args.setlayout.layout.fl_object_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) cpu_to_le32(l.object_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) req->r_args.setlayout.layout.fl_pg_pool =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) cpu_to_le32(l.data_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) err = ceph_mdsc_do_request(mdsc, inode, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) ceph_mdsc_put_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^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) * Return object name, size/offset information, and location (OSD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) * number, network address) for a given file offset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) static long ceph_ioctl_get_dataloc(struct file *file, void __user *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) struct ceph_ioctl_dataloc dl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) struct inode *inode = file_inode(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct ceph_inode_info *ci = ceph_inode(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) struct ceph_osd_client *osdc =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) &ceph_sb_to_client(inode->i_sb)->client->osdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) struct ceph_object_locator oloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) CEPH_DEFINE_OID_ONSTACK(oid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) u32 xlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) u64 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) struct ceph_pg pgid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) /* copy and validate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if (copy_from_user(&dl, arg, sizeof(dl)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) down_read(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) ceph_calc_file_object_mapping(&ci->i_layout, dl.file_offset, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) &dl.object_no, &dl.object_offset, &xlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) dl.file_offset -= dl.object_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) dl.object_size = ci->i_layout.object_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) dl.block_size = ci->i_layout.stripe_unit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /* block_offset = object_offset % block_size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) tmp = dl.object_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) dl.block_offset = do_div(tmp, dl.block_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) snprintf(dl.object_name, sizeof(dl.object_name), "%llx.%08llx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) ceph_ino(inode), dl.object_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) oloc.pool = ci->i_layout.pool_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) oloc.pool_ns = ceph_try_get_string(ci->i_layout.pool_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) ceph_oid_printf(&oid, "%s", dl.object_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) r = ceph_object_locator_to_pg(osdc->osdmap, &oid, &oloc, &pgid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) ceph_oloc_destroy(&oloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (r < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) up_read(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) dl.osd = ceph_pg_to_acting_primary(osdc->osdmap, &pgid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (dl.osd >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) struct ceph_entity_addr *a =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) ceph_osd_addr(osdc->osdmap, dl.osd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) memcpy(&dl.osd_addr, &a->in_addr, sizeof(dl.osd_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) memset(&dl.osd_addr, 0, sizeof(dl.osd_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) up_read(&osdc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) /* send result back to user */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if (copy_to_user(arg, &dl, sizeof(dl)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static long ceph_ioctl_lazyio(struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) struct ceph_file_info *fi = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) struct inode *inode = file_inode(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) struct ceph_inode_info *ci = ceph_inode(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) struct ceph_mds_client *mdsc = ceph_inode_to_client(inode)->mdsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if ((fi->fmode & CEPH_FILE_MODE_LAZY) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) spin_lock(&ci->i_ceph_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) fi->fmode |= CEPH_FILE_MODE_LAZY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) ci->i_nr_by_mode[ffs(CEPH_FILE_MODE_LAZY)]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) __ceph_touch_fmode(ci, mdsc, fi->fmode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) spin_unlock(&ci->i_ceph_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) dout("ioctl_layzio: file %p marked lazy\n", file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) ceph_check_caps(ci, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) dout("ioctl_layzio: file %p already lazy\n", file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static long ceph_ioctl_syncio(struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) struct ceph_file_info *fi = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) fi->flags |= CEPH_F_SYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) long ceph_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) dout("ioctl file %p cmd %u arg %lu\n", file, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) case CEPH_IOC_GET_LAYOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) return ceph_ioctl_get_layout(file, (void __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) case CEPH_IOC_SET_LAYOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) return ceph_ioctl_set_layout(file, (void __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) case CEPH_IOC_SET_LAYOUT_POLICY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) return ceph_ioctl_set_layout_policy(file, (void __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) case CEPH_IOC_GET_DATALOC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) return ceph_ioctl_get_dataloc(file, (void __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) case CEPH_IOC_LAZYIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) return ceph_ioctl_lazyio(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) case CEPH_IOC_SYNCIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) return ceph_ioctl_syncio(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }