ceph: add CEPH_MDS_OP_SETDIRLAYOUT and associated ioctl.

Signed-off-by: Sage Weil <sage@newdream.net>

authored by Greg Farnum and committed by Sage Weil 571dba52 010e3b48

+70 -1
+66
fs/ceph/ioctl.c
··· 92 } 93 94 /* 95 * Return object name, size/offset information, and location (OSD 96 * number, network address) for a given file offset. 97 */ ··· 239 case CEPH_IOC_SET_LAYOUT: 240 return ceph_ioctl_set_layout(file, (void __user *)arg); 241 242 case CEPH_IOC_GET_DATALOC: 243 return ceph_ioctl_get_dataloc(file, (void __user *)arg); 244 245 case CEPH_IOC_LAZYIO: 246 return ceph_ioctl_lazyio(file); 247 } 248 return -ENOTTY; 249 }
··· 92 } 93 94 /* 95 + * Set a layout policy on a directory inode. All items in the tree 96 + * rooted at this inode will inherit this layout on creation, 97 + * (It doesn't apply retroactively ) 98 + * unless a subdirectory has its own layout policy. 99 + */ 100 + static long ceph_ioctl_set_layout_policy (struct file *file, void __user *arg) 101 + { 102 + struct inode *inode = file->f_dentry->d_inode; 103 + struct ceph_mds_request *req; 104 + struct ceph_ioctl_layout l; 105 + int err, i; 106 + struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc; 107 + 108 + /* copy and validate */ 109 + if (copy_from_user(&l, arg, sizeof(l))) 110 + return -EFAULT; 111 + 112 + if ((l.object_size & ~PAGE_MASK) || 113 + (l.stripe_unit & ~PAGE_MASK) || 114 + !l.stripe_unit || 115 + (l.object_size && 116 + (unsigned)l.object_size % (unsigned)l.stripe_unit)) 117 + return -EINVAL; 118 + 119 + /* make sure it's a valid data pool */ 120 + if (l.data_pool > 0) { 121 + mutex_lock(&mdsc->mutex); 122 + err = -EINVAL; 123 + for (i = 0; i < mdsc->mdsmap->m_num_data_pg_pools; i++) 124 + if (mdsc->mdsmap->m_data_pg_pools[i] == l.data_pool) { 125 + err = 0; 126 + break; 127 + } 128 + mutex_unlock(&mdsc->mutex); 129 + if (err) 130 + return err; 131 + } 132 + 133 + req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SETDIRLAYOUT, 134 + USE_AUTH_MDS); 135 + 136 + if (IS_ERR(req)) 137 + return PTR_ERR(req); 138 + req->r_inode = igrab(inode); 139 + 140 + req->r_args.setlayout.layout.fl_stripe_unit = 141 + cpu_to_le32(l.stripe_unit); 142 + req->r_args.setlayout.layout.fl_stripe_count = 143 + cpu_to_le32(l.stripe_count); 144 + req->r_args.setlayout.layout.fl_object_size = 145 + cpu_to_le32(l.object_size); 146 + req->r_args.setlayout.layout.fl_pg_pool = 147 + cpu_to_le32(l.data_pool); 148 + req->r_args.setlayout.layout.fl_pg_preferred = 149 + cpu_to_le32(l.preferred_osd); 150 + 151 + err = ceph_mdsc_do_request(mdsc, inode, req); 152 + ceph_mdsc_put_request(req); 153 + return err; 154 + } 155 + 156 + /* 157 * Return object name, size/offset information, and location (OSD 158 * number, network address) for a given file offset. 159 */ ··· 177 case CEPH_IOC_SET_LAYOUT: 178 return ceph_ioctl_set_layout(file, (void __user *)arg); 179 180 + case CEPH_IOC_SET_LAYOUT_POLICY: 181 + return ceph_ioctl_set_layout_policy(file, (void __user *)arg); 182 + 183 case CEPH_IOC_GET_DATALOC: 184 return ceph_ioctl_get_dataloc(file, (void __user *)arg); 185 186 case CEPH_IOC_LAZYIO: 187 return ceph_ioctl_lazyio(file); 188 } 189 + 190 return -ENOTTY; 191 }
+3 -1
fs/ceph/ioctl.h
··· 4 #include <linux/ioctl.h> 5 #include <linux/types.h> 6 7 - #define CEPH_IOCTL_MAGIC 0x97 8 9 /* just use u64 to align sanely on all archs */ 10 struct ceph_ioctl_layout { ··· 16 #define CEPH_IOC_GET_LAYOUT _IOR(CEPH_IOCTL_MAGIC, 1, \ 17 struct ceph_ioctl_layout) 18 #define CEPH_IOC_SET_LAYOUT _IOW(CEPH_IOCTL_MAGIC, 2, \ 19 struct ceph_ioctl_layout) 20 21 /*
··· 4 #include <linux/ioctl.h> 5 #include <linux/types.h> 6 7 + #define CEPH_IOCTL_MAGIC 0x98 8 9 /* just use u64 to align sanely on all archs */ 10 struct ceph_ioctl_layout { ··· 16 #define CEPH_IOC_GET_LAYOUT _IOR(CEPH_IOCTL_MAGIC, 1, \ 17 struct ceph_ioctl_layout) 18 #define CEPH_IOC_SET_LAYOUT _IOW(CEPH_IOCTL_MAGIC, 2, \ 19 + struct ceph_ioctl_layout) 20 + #define CEPH_IOC_SET_LAYOUT_POLICY _IOW(CEPH_IOCTL_MAGIC, 5, \ 21 struct ceph_ioctl_layout) 22 23 /*
+1
include/linux/ceph/ceph_fs.h
··· 299 CEPH_MDS_OP_SETATTR = 0x01108, 300 CEPH_MDS_OP_SETFILELOCK= 0x01109, 301 CEPH_MDS_OP_GETFILELOCK= 0x00110, 302 303 CEPH_MDS_OP_MKNOD = 0x01201, 304 CEPH_MDS_OP_LINK = 0x01202,
··· 299 CEPH_MDS_OP_SETATTR = 0x01108, 300 CEPH_MDS_OP_SETFILELOCK= 0x01109, 301 CEPH_MDS_OP_GETFILELOCK= 0x00110, 302 + CEPH_MDS_OP_SETDIRLAYOUT=0x0110a, 303 304 CEPH_MDS_OP_MKNOD = 0x01201, 305 CEPH_MDS_OP_LINK = 0x01202,