aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/fuse/dir.c51
-rw-r--r--fs/nfs/nfs4xdr.c2
-rw-r--r--fs/nfsd/vfs.c5
-rw-r--r--fs/xfs/xfs_dinode.h3
-rw-r--r--fs/xfs/xfs_inode.c31
-rw-r--r--fs/xfs/xfs_log_recover.c13
6 files changed, 76 insertions, 29 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 0eda52738ec4..72a5d5b04494 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -1223,30 +1223,46 @@ static int fuse_direntplus_link(struct file *file,
1223 if (name.name[1] == '.' && name.len == 2) 1223 if (name.name[1] == '.' && name.len == 2)
1224 return 0; 1224 return 0;
1225 } 1225 }
1226
1227 if (invalid_nodeid(o->nodeid))
1228 return -EIO;
1229 if (!fuse_valid_type(o->attr.mode))
1230 return -EIO;
1231
1226 fc = get_fuse_conn(dir); 1232 fc = get_fuse_conn(dir);
1227 1233
1228 name.hash = full_name_hash(name.name, name.len); 1234 name.hash = full_name_hash(name.name, name.len);
1229 dentry = d_lookup(parent, &name); 1235 dentry = d_lookup(parent, &name);
1230 if (dentry && dentry->d_inode) { 1236 if (dentry) {
1231 inode = dentry->d_inode; 1237 inode = dentry->d_inode;
1232 if (get_node_id(inode) == o->nodeid) { 1238 if (!inode) {
1239 d_drop(dentry);
1240 } else if (get_node_id(inode) != o->nodeid ||
1241 ((o->attr.mode ^ inode->i_mode) & S_IFMT)) {
1242 err = d_invalidate(dentry);
1243 if (err)
1244 goto out;
1245 } else if (is_bad_inode(inode)) {
1246 err = -EIO;
1247 goto out;
1248 } else {
1233 struct fuse_inode *fi; 1249 struct fuse_inode *fi;
1234 fi = get_fuse_inode(inode); 1250 fi = get_fuse_inode(inode);
1235 spin_lock(&fc->lock); 1251 spin_lock(&fc->lock);
1236 fi->nlookup++; 1252 fi->nlookup++;
1237 spin_unlock(&fc->lock); 1253 spin_unlock(&fc->lock);
1238 1254
1255 fuse_change_attributes(inode, &o->attr,
1256 entry_attr_timeout(o),
1257 attr_version);
1258
1239 /* 1259 /*
1240 * The other branch to 'found' comes via fuse_iget() 1260 * The other branch to 'found' comes via fuse_iget()
1241 * which bumps nlookup inside 1261 * which bumps nlookup inside
1242 */ 1262 */
1243 goto found; 1263 goto found;
1244 } 1264 }
1245 err = d_invalidate(dentry);
1246 if (err)
1247 goto out;
1248 dput(dentry); 1265 dput(dentry);
1249 dentry = NULL;
1250 } 1266 }
1251 1267
1252 dentry = d_alloc(parent, &name); 1268 dentry = d_alloc(parent, &name);
@@ -1259,25 +1275,30 @@ static int fuse_direntplus_link(struct file *file,
1259 if (!inode) 1275 if (!inode)
1260 goto out; 1276 goto out;
1261 1277
1262 alias = d_materialise_unique(dentry, inode); 1278 if (S_ISDIR(inode->i_mode)) {
1263 err = PTR_ERR(alias); 1279 mutex_lock(&fc->inst_mutex);
1264 if (IS_ERR(alias)) 1280 alias = fuse_d_add_directory(dentry, inode);
1265 goto out; 1281 mutex_unlock(&fc->inst_mutex);
1282 err = PTR_ERR(alias);
1283 if (IS_ERR(alias)) {
1284 iput(inode);
1285 goto out;
1286 }
1287 } else {
1288 alias = d_splice_alias(inode, dentry);
1289 }
1290
1266 if (alias) { 1291 if (alias) {
1267 dput(dentry); 1292 dput(dentry);
1268 dentry = alias; 1293 dentry = alias;
1269 } 1294 }
1270 1295
1271found: 1296found:
1272 fuse_change_attributes(inode, &o->attr, entry_attr_timeout(o),
1273 attr_version);
1274
1275 fuse_change_entry_timeout(dentry, o); 1297 fuse_change_entry_timeout(dentry, o);
1276 1298
1277 err = 0; 1299 err = 0;
1278out: 1300out:
1279 if (dentry) 1301 dput(dentry);
1280 dput(dentry);
1281 return err; 1302 return err;
1282} 1303}
1283 1304
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index c74d6168db99..3850b018815f 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -1118,11 +1118,11 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap,
1118 len, ((char *)p - (char *)q) + 4); 1118 len, ((char *)p - (char *)q) + 4);
1119 BUG(); 1119 BUG();
1120 } 1120 }
1121 len = (char *)p - (char *)q - (bmval_len << 2);
1122 *q++ = htonl(bmval0); 1121 *q++ = htonl(bmval0);
1123 *q++ = htonl(bmval1); 1122 *q++ = htonl(bmval1);
1124 if (bmval_len == 3) 1123 if (bmval_len == 3)
1125 *q++ = htonl(bmval2); 1124 *q++ = htonl(bmval2);
1125 len = (char *)p - (char *)(q + 1);
1126 *q = htonl(len); 1126 *q = htonl(len);
1127 1127
1128/* out: */ 1128/* out: */
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 8ff6a0019b0b..c827acb0e943 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -830,9 +830,10 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type,
830 flags = O_WRONLY|O_LARGEFILE; 830 flags = O_WRONLY|O_LARGEFILE;
831 } 831 }
832 *filp = dentry_open(&path, flags, current_cred()); 832 *filp = dentry_open(&path, flags, current_cred());
833 if (IS_ERR(*filp)) 833 if (IS_ERR(*filp)) {
834 host_err = PTR_ERR(*filp); 834 host_err = PTR_ERR(*filp);
835 else { 835 *filp = NULL;
836 } else {
836 host_err = ima_file_check(*filp, may_flags); 837 host_err = ima_file_check(*filp, may_flags);
837 838
838 if (may_flags & NFSD_MAY_64BIT_COOKIE) 839 if (may_flags & NFSD_MAY_64BIT_COOKIE)
diff --git a/fs/xfs/xfs_dinode.h b/fs/xfs/xfs_dinode.h
index 07d735a80a0f..e5869b50dc41 100644
--- a/fs/xfs/xfs_dinode.h
+++ b/fs/xfs/xfs_dinode.h
@@ -39,6 +39,9 @@ typedef struct xfs_timestamp {
39 * There is a very similar struct icdinode in xfs_inode which matches the 39 * There is a very similar struct icdinode in xfs_inode which matches the
40 * layout of the first 96 bytes of this structure, but is kept in native 40 * layout of the first 96 bytes of this structure, but is kept in native
41 * format instead of big endian. 41 * format instead of big endian.
42 *
43 * Note: di_flushiter is only used by v1/2 inodes - it's effectively a zeroed
44 * padding field for v3 inodes.
42 */ 45 */
43typedef struct xfs_dinode { 46typedef struct xfs_dinode {
44 __be16 di_magic; /* inode magic # = XFS_DINODE_MAGIC */ 47 __be16 di_magic; /* inode magic # = XFS_DINODE_MAGIC */
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index b78481f99d9d..bb262c25c8de 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -896,7 +896,6 @@ xfs_dinode_to_disk(
896 to->di_projid_lo = cpu_to_be16(from->di_projid_lo); 896 to->di_projid_lo = cpu_to_be16(from->di_projid_lo);
897 to->di_projid_hi = cpu_to_be16(from->di_projid_hi); 897 to->di_projid_hi = cpu_to_be16(from->di_projid_hi);
898 memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad)); 898 memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad));
899 to->di_flushiter = cpu_to_be16(from->di_flushiter);
900 to->di_atime.t_sec = cpu_to_be32(from->di_atime.t_sec); 899 to->di_atime.t_sec = cpu_to_be32(from->di_atime.t_sec);
901 to->di_atime.t_nsec = cpu_to_be32(from->di_atime.t_nsec); 900 to->di_atime.t_nsec = cpu_to_be32(from->di_atime.t_nsec);
902 to->di_mtime.t_sec = cpu_to_be32(from->di_mtime.t_sec); 901 to->di_mtime.t_sec = cpu_to_be32(from->di_mtime.t_sec);
@@ -924,6 +923,9 @@ xfs_dinode_to_disk(
924 to->di_lsn = cpu_to_be64(from->di_lsn); 923 to->di_lsn = cpu_to_be64(from->di_lsn);
925 memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2)); 924 memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2));
926 uuid_copy(&to->di_uuid, &from->di_uuid); 925 uuid_copy(&to->di_uuid, &from->di_uuid);
926 to->di_flushiter = 0;
927 } else {
928 to->di_flushiter = cpu_to_be16(from->di_flushiter);
927 } 929 }
928} 930}
929 931
@@ -1029,10 +1031,14 @@ xfs_dinode_calc_crc(
1029/* 1031/*
1030 * Read the disk inode attributes into the in-core inode structure. 1032 * Read the disk inode attributes into the in-core inode structure.
1031 * 1033 *
1032 * If we are initialising a new inode and we are not utilising the 1034 * For version 5 superblocks, if we are initialising a new inode and we are not
1033 * XFS_MOUNT_IKEEP inode cluster mode, we can simple build the new inode core 1035 * utilising the XFS_MOUNT_IKEEP inode cluster mode, we can simple build the new
1034 * with a random generation number. If we are keeping inodes around, we need to 1036 * inode core with a random generation number. If we are keeping inodes around,
1035 * read the inode cluster to get the existing generation number off disk. 1037 * we need to read the inode cluster to get the existing generation number off
1038 * disk. Further, if we are using version 4 superblocks (i.e. v1/v2 inode
1039 * format) then log recovery is dependent on the di_flushiter field being
1040 * initialised from the current on-disk value and hence we must also read the
1041 * inode off disk.
1036 */ 1042 */
1037int 1043int
1038xfs_iread( 1044xfs_iread(
@@ -1054,6 +1060,7 @@ xfs_iread(
1054 1060
1055 /* shortcut IO on inode allocation if possible */ 1061 /* shortcut IO on inode allocation if possible */
1056 if ((iget_flags & XFS_IGET_CREATE) && 1062 if ((iget_flags & XFS_IGET_CREATE) &&
1063 xfs_sb_version_hascrc(&mp->m_sb) &&
1057 !(mp->m_flags & XFS_MOUNT_IKEEP)) { 1064 !(mp->m_flags & XFS_MOUNT_IKEEP)) {
1058 /* initialise the on-disk inode core */ 1065 /* initialise the on-disk inode core */
1059 memset(&ip->i_d, 0, sizeof(ip->i_d)); 1066 memset(&ip->i_d, 0, sizeof(ip->i_d));
@@ -2882,12 +2889,18 @@ xfs_iflush_int(
2882 __func__, ip->i_ino, ip->i_d.di_forkoff, ip); 2889 __func__, ip->i_ino, ip->i_d.di_forkoff, ip);
2883 goto corrupt_out; 2890 goto corrupt_out;
2884 } 2891 }
2892
2885 /* 2893 /*
2886 * bump the flush iteration count, used to detect flushes which 2894 * Inode item log recovery for v1/v2 inodes are dependent on the
2887 * postdate a log record during recovery. This is redundant as we now 2895 * di_flushiter count for correct sequencing. We bump the flush
2888 * log every change and hence this can't happen. Still, it doesn't hurt. 2896 * iteration count so we can detect flushes which postdate a log record
2897 * during recovery. This is redundant as we now log every change and
2898 * hence this can't happen but we need to still do it to ensure
2899 * backwards compatibility with old kernels that predate logging all
2900 * inode changes.
2889 */ 2901 */
2890 ip->i_d.di_flushiter++; 2902 if (ip->i_d.di_version < 3)
2903 ip->i_d.di_flushiter++;
2891 2904
2892 /* 2905 /*
2893 * Copy the dirty parts of the inode into the on-disk 2906 * Copy the dirty parts of the inode into the on-disk
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 6fcc910a50b9..7681b19aa5dc 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -2592,8 +2592,16 @@ xlog_recover_inode_pass2(
2592 goto error; 2592 goto error;
2593 } 2593 }
2594 2594
2595 /* Skip replay when the on disk inode is newer than the log one */ 2595 /*
2596 if (dicp->di_flushiter < be16_to_cpu(dip->di_flushiter)) { 2596 * di_flushiter is only valid for v1/2 inodes. All changes for v3 inodes
2597 * are transactional and if ordering is necessary we can determine that
2598 * more accurately by the LSN field in the V3 inode core. Don't trust
2599 * the inode versions we might be changing them here - use the
2600 * superblock flag to determine whether we need to look at di_flushiter
2601 * to skip replay when the on disk inode is newer than the log one
2602 */
2603 if (!xfs_sb_version_hascrc(&mp->m_sb) &&
2604 dicp->di_flushiter < be16_to_cpu(dip->di_flushiter)) {
2597 /* 2605 /*
2598 * Deal with the wrap case, DI_MAX_FLUSH is less 2606 * Deal with the wrap case, DI_MAX_FLUSH is less
2599 * than smaller numbers 2607 * than smaller numbers
@@ -2608,6 +2616,7 @@ xlog_recover_inode_pass2(
2608 goto error; 2616 goto error;
2609 } 2617 }
2610 } 2618 }
2619
2611 /* Take the opportunity to reset the flush iteration count */ 2620 /* Take the opportunity to reset the flush iteration count */
2612 dicp->di_flushiter = 0; 2621 dicp->di_flushiter = 0;
2613 2622