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.c75
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
1215static 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);
1252out:
1253 mutex_unlock(&inode->i_mutex);
1254 return ret;
1255}
1256
1215const struct inode_operations gfs2_file_iops = { 1257const 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
1225const struct inode_operations gfs2_dir_iops = { 1268const 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
1244const struct inode_operations gfs2_symlink_iops = { 1288const 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