diff options
Diffstat (limited to 'fs/gfs2/ops_inode.c')
-rw-r--r-- | fs/gfs2/ops_inode.c | 75 |
1 files changed, 60 insertions, 15 deletions
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c index d232991b9046..49877546beb9 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" |
@@ -31,12 +32,11 @@ | |||
31 | #include "glock.h" | 32 | #include "glock.h" |
32 | #include "inode.h" | 33 | #include "inode.h" |
33 | #include "meta_io.h" | 34 | #include "meta_io.h" |
34 | #include "ops_dentry.h" | ||
35 | #include "ops_inode.h" | ||
36 | #include "quota.h" | 35 | #include "quota.h" |
37 | #include "rgrp.h" | 36 | #include "rgrp.h" |
38 | #include "trans.h" | 37 | #include "trans.h" |
39 | #include "util.h" | 38 | #include "util.h" |
39 | #include "super.h" | ||
40 | 40 | ||
41 | /** | 41 | /** |
42 | * gfs2_create - Create a file | 42 | * gfs2_create - Create a file |
@@ -185,7 +185,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, | |||
185 | if (!dip->i_inode.i_nlink) | 185 | if (!dip->i_inode.i_nlink) |
186 | goto out_gunlock; | 186 | goto out_gunlock; |
187 | error = -EFBIG; | 187 | error = -EFBIG; |
188 | if (dip->i_di.di_entries == (u32)-1) | 188 | if (dip->i_entries == (u32)-1) |
189 | goto out_gunlock; | 189 | goto out_gunlock; |
190 | error = -EPERM; | 190 | error = -EPERM; |
191 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) | 191 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) |
@@ -371,7 +371,7 @@ static int gfs2_symlink(struct inode *dir, struct dentry *dentry, | |||
371 | 371 | ||
372 | ip = ghs[1].gh_gl->gl_object; | 372 | ip = ghs[1].gh_gl->gl_object; |
373 | 373 | ||
374 | ip->i_di.di_size = size; | 374 | ip->i_disksize = size; |
375 | 375 | ||
376 | error = gfs2_meta_inode_buffer(ip, &dibh); | 376 | error = gfs2_meta_inode_buffer(ip, &dibh); |
377 | 377 | ||
@@ -425,9 +425,9 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
425 | ip = ghs[1].gh_gl->gl_object; | 425 | ip = ghs[1].gh_gl->gl_object; |
426 | 426 | ||
427 | ip->i_inode.i_nlink = 2; | 427 | ip->i_inode.i_nlink = 2; |
428 | ip->i_di.di_size = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode); | 428 | ip->i_disksize = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode); |
429 | ip->i_di.di_flags |= GFS2_DIF_JDATA; | 429 | ip->i_diskflags |= GFS2_DIF_JDATA; |
430 | ip->i_di.di_entries = 2; | 430 | ip->i_entries = 2; |
431 | 431 | ||
432 | error = gfs2_meta_inode_buffer(ip, &dibh); | 432 | error = gfs2_meta_inode_buffer(ip, &dibh); |
433 | 433 | ||
@@ -517,13 +517,13 @@ static int gfs2_rmdir(struct inode *dir, struct dentry *dentry) | |||
517 | if (error) | 517 | if (error) |
518 | goto out_gunlock; | 518 | goto out_gunlock; |
519 | 519 | ||
520 | if (ip->i_di.di_entries < 2) { | 520 | if (ip->i_entries < 2) { |
521 | if (gfs2_consist_inode(ip)) | 521 | if (gfs2_consist_inode(ip)) |
522 | gfs2_dinode_print(ip); | 522 | gfs2_dinode_print(ip); |
523 | error = -EIO; | 523 | error = -EIO; |
524 | goto out_gunlock; | 524 | goto out_gunlock; |
525 | } | 525 | } |
526 | if (ip->i_di.di_entries > 2) { | 526 | if (ip->i_entries > 2) { |
527 | error = -ENOTEMPTY; | 527 | error = -ENOTEMPTY; |
528 | goto out_gunlock; | 528 | goto out_gunlock; |
529 | } | 529 | } |
@@ -726,13 +726,13 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
726 | goto out_gunlock; | 726 | goto out_gunlock; |
727 | 727 | ||
728 | if (S_ISDIR(nip->i_inode.i_mode)) { | 728 | if (S_ISDIR(nip->i_inode.i_mode)) { |
729 | if (nip->i_di.di_entries < 2) { | 729 | if (nip->i_entries < 2) { |
730 | if (gfs2_consist_inode(nip)) | 730 | if (gfs2_consist_inode(nip)) |
731 | gfs2_dinode_print(nip); | 731 | gfs2_dinode_print(nip); |
732 | error = -EIO; | 732 | error = -EIO; |
733 | goto out_gunlock; | 733 | goto out_gunlock; |
734 | } | 734 | } |
735 | if (nip->i_di.di_entries > 2) { | 735 | if (nip->i_entries > 2) { |
736 | error = -ENOTEMPTY; | 736 | error = -ENOTEMPTY; |
737 | goto out_gunlock; | 737 | goto out_gunlock; |
738 | } | 738 | } |
@@ -758,7 +758,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
758 | error = -EINVAL; | 758 | error = -EINVAL; |
759 | goto out_gunlock; | 759 | goto out_gunlock; |
760 | } | 760 | } |
761 | if (ndip->i_di.di_entries == (u32)-1) { | 761 | if (ndip->i_entries == (u32)-1) { |
762 | error = -EFBIG; | 762 | error = -EFBIG; |
763 | goto out_gunlock; | 763 | goto out_gunlock; |
764 | } | 764 | } |
@@ -990,7 +990,7 @@ static int setattr_size(struct inode *inode, struct iattr *attr) | |||
990 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 990 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
991 | int error; | 991 | int error; |
992 | 992 | ||
993 | if (attr->ia_size != ip->i_di.di_size) { | 993 | if (attr->ia_size != ip->i_disksize) { |
994 | error = gfs2_trans_begin(sdp, 0, sdp->sd_jdesc->jd_blocks); | 994 | error = gfs2_trans_begin(sdp, 0, sdp->sd_jdesc->jd_blocks); |
995 | if (error) | 995 | if (error) |
996 | return error; | 996 | return error; |
@@ -1001,8 +1001,8 @@ static int setattr_size(struct inode *inode, struct iattr *attr) | |||
1001 | } | 1001 | } |
1002 | 1002 | ||
1003 | error = gfs2_truncatei(ip, attr->ia_size); | 1003 | error = gfs2_truncatei(ip, attr->ia_size); |
1004 | if (error && (inode->i_size != ip->i_di.di_size)) | 1004 | if (error && (inode->i_size != ip->i_disksize)) |
1005 | i_size_write(inode, ip->i_di.di_size); | 1005 | i_size_write(inode, ip->i_disksize); |
1006 | 1006 | ||
1007 | return error; | 1007 | return error; |
1008 | } | 1008 | } |
@@ -1212,6 +1212,48 @@ static int gfs2_removexattr(struct dentry *dentry, const char *name) | |||
1212 | return gfs2_ea_remove(GFS2_I(dentry->d_inode), &er); | 1212 | return gfs2_ea_remove(GFS2_I(dentry->d_inode), &er); |
1213 | } | 1213 | } |
1214 | 1214 | ||
1215 | static int gfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | ||
1216 | u64 start, u64 len) | ||
1217 | { | ||
1218 | struct gfs2_inode *ip = GFS2_I(inode); | ||
1219 | struct gfs2_holder gh; | ||
1220 | int ret; | ||
1221 | |||
1222 | ret = fiemap_check_flags(fieinfo, FIEMAP_FLAG_SYNC); | ||
1223 | if (ret) | ||
1224 | return ret; | ||
1225 | |||
1226 | mutex_lock(&inode->i_mutex); | ||
1227 | |||
1228 | ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &gh); | ||
1229 | if (ret) | ||
1230 | goto out; | ||
1231 | |||
1232 | if (gfs2_is_stuffed(ip)) { | ||
1233 | u64 phys = ip->i_no_addr << inode->i_blkbits; | ||
1234 | u64 size = i_size_read(inode); | ||
1235 | u32 flags = FIEMAP_EXTENT_LAST|FIEMAP_EXTENT_NOT_ALIGNED| | ||
1236 | FIEMAP_EXTENT_DATA_INLINE; | ||
1237 | phys += sizeof(struct gfs2_dinode); | ||
1238 | phys += start; | ||
1239 | if (start + len > size) | ||
1240 | len = size - start; | ||
1241 | if (start < size) | ||
1242 | ret = fiemap_fill_next_extent(fieinfo, start, phys, | ||
1243 | len, flags); | ||
1244 | if (ret == 1) | ||
1245 | ret = 0; | ||
1246 | } else { | ||
1247 | ret = __generic_block_fiemap(inode, fieinfo, start, len, | ||
1248 | gfs2_block_map); | ||
1249 | } | ||
1250 | |||
1251 | gfs2_glock_dq_uninit(&gh); | ||
1252 | out: | ||
1253 | mutex_unlock(&inode->i_mutex); | ||
1254 | return ret; | ||
1255 | } | ||
1256 | |||
1215 | const struct inode_operations gfs2_file_iops = { | 1257 | const struct inode_operations gfs2_file_iops = { |
1216 | .permission = gfs2_permission, | 1258 | .permission = gfs2_permission, |
1217 | .setattr = gfs2_setattr, | 1259 | .setattr = gfs2_setattr, |
@@ -1220,6 +1262,7 @@ const struct inode_operations gfs2_file_iops = { | |||
1220 | .getxattr = gfs2_getxattr, | 1262 | .getxattr = gfs2_getxattr, |
1221 | .listxattr = gfs2_listxattr, | 1263 | .listxattr = gfs2_listxattr, |
1222 | .removexattr = gfs2_removexattr, | 1264 | .removexattr = gfs2_removexattr, |
1265 | .fiemap = gfs2_fiemap, | ||
1223 | }; | 1266 | }; |
1224 | 1267 | ||
1225 | const struct inode_operations gfs2_dir_iops = { | 1268 | const struct inode_operations gfs2_dir_iops = { |
@@ -1239,6 +1282,7 @@ const struct inode_operations gfs2_dir_iops = { | |||
1239 | .getxattr = gfs2_getxattr, | 1282 | .getxattr = gfs2_getxattr, |
1240 | .listxattr = gfs2_listxattr, | 1283 | .listxattr = gfs2_listxattr, |
1241 | .removexattr = gfs2_removexattr, | 1284 | .removexattr = gfs2_removexattr, |
1285 | .fiemap = gfs2_fiemap, | ||
1242 | }; | 1286 | }; |
1243 | 1287 | ||
1244 | const struct inode_operations gfs2_symlink_iops = { | 1288 | const struct inode_operations gfs2_symlink_iops = { |
@@ -1251,5 +1295,6 @@ const struct inode_operations gfs2_symlink_iops = { | |||
1251 | .getxattr = gfs2_getxattr, | 1295 | .getxattr = gfs2_getxattr, |
1252 | .listxattr = gfs2_listxattr, | 1296 | .listxattr = gfs2_listxattr, |
1253 | .removexattr = gfs2_removexattr, | 1297 | .removexattr = gfs2_removexattr, |
1298 | .fiemap = gfs2_fiemap, | ||
1254 | }; | 1299 | }; |
1255 | 1300 | ||