aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/ops_inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2/ops_inode.c')
-rw-r--r--fs/gfs2/ops_inode.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c
index d232991b9046..1e24b65e1d23 100644
--- a/fs/gfs2/ops_inode.c
+++ b/fs/gfs2/ops_inode.c
@@ -19,6 +19,7 @@
19#include <linux/gfs2_ondisk.h> 19#include <linux/gfs2_ondisk.h>
20#include <linux/crc32.h> 20#include <linux/crc32.h>
21#include <linux/lm_interface.h> 21#include <linux/lm_interface.h>
22#include <linux/fiemap.h>
22#include <asm/uaccess.h> 23#include <asm/uaccess.h>
23 24
24#include "gfs2.h" 25#include "gfs2.h"
@@ -1212,6 +1213,48 @@ static int gfs2_removexattr(struct dentry *dentry, const char *name)
1212 return gfs2_ea_remove(GFS2_I(dentry->d_inode), &er); 1213 return gfs2_ea_remove(GFS2_I(dentry->d_inode), &er);
1213} 1214}
1214 1215
1216static int gfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
1217 u64 start, u64 len)
1218{
1219 struct gfs2_inode *ip = GFS2_I(inode);
1220 struct gfs2_holder gh;
1221 int ret;
1222
1223 ret = fiemap_check_flags(fieinfo, FIEMAP_FLAG_SYNC);
1224 if (ret)
1225 return ret;
1226
1227 mutex_lock(&inode->i_mutex);
1228
1229 ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &gh);
1230 if (ret)
1231 goto out;
1232
1233 if (gfs2_is_stuffed(ip)) {
1234 u64 phys = ip->i_no_addr << inode->i_blkbits;
1235 u64 size = i_size_read(inode);
1236 u32 flags = FIEMAP_EXTENT_LAST|FIEMAP_EXTENT_NOT_ALIGNED|
1237 FIEMAP_EXTENT_DATA_INLINE;
1238 phys += sizeof(struct gfs2_dinode);
1239 phys += start;
1240 if (start + len > size)
1241 len = size - start;
1242 if (start < size)
1243 ret = fiemap_fill_next_extent(fieinfo, start, phys,
1244 len, flags);
1245 if (ret == 1)
1246 ret = 0;
1247 } else {
1248 ret = __generic_block_fiemap(inode, fieinfo, start, len,
1249 gfs2_block_map);
1250 }
1251
1252 gfs2_glock_dq_uninit(&gh);
1253out:
1254 mutex_unlock(&inode->i_mutex);
1255 return ret;
1256}
1257
1215const struct inode_operations gfs2_file_iops = { 1258const struct inode_operations gfs2_file_iops = {
1216 .permission = gfs2_permission, 1259 .permission = gfs2_permission,
1217 .setattr = gfs2_setattr, 1260 .setattr = gfs2_setattr,
@@ -1220,6 +1263,7 @@ const struct inode_operations gfs2_file_iops = {
1220 .getxattr = gfs2_getxattr, 1263 .getxattr = gfs2_getxattr,
1221 .listxattr = gfs2_listxattr, 1264 .listxattr = gfs2_listxattr,
1222 .removexattr = gfs2_removexattr, 1265 .removexattr = gfs2_removexattr,
1266 .fiemap = gfs2_fiemap,
1223}; 1267};
1224 1268
1225const struct inode_operations gfs2_dir_iops = { 1269const struct inode_operations gfs2_dir_iops = {
@@ -1239,6 +1283,7 @@ const struct inode_operations gfs2_dir_iops = {
1239 .getxattr = gfs2_getxattr, 1283 .getxattr = gfs2_getxattr,
1240 .listxattr = gfs2_listxattr, 1284 .listxattr = gfs2_listxattr,
1241 .removexattr = gfs2_removexattr, 1285 .removexattr = gfs2_removexattr,
1286 .fiemap = gfs2_fiemap,
1242}; 1287};
1243 1288
1244const struct inode_operations gfs2_symlink_iops = { 1289const struct inode_operations gfs2_symlink_iops = {
@@ -1251,5 +1296,6 @@ const struct inode_operations gfs2_symlink_iops = {
1251 .getxattr = gfs2_getxattr, 1296 .getxattr = gfs2_getxattr,
1252 .listxattr = gfs2_listxattr, 1297 .listxattr = gfs2_listxattr,
1253 .removexattr = gfs2_removexattr, 1298 .removexattr = gfs2_removexattr,
1299 .fiemap = gfs2_fiemap,
1254}; 1300};
1255 1301