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 | ||
