aboutsummaryrefslogtreecommitdiffstats
path: root/fs/udf/namei.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /fs/udf/namei.c
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'fs/udf/namei.c')
-rw-r--r--fs/udf/namei.c60
1 files changed, 40 insertions, 20 deletions
diff --git a/fs/udf/namei.c b/fs/udf/namei.c
index 95fee278ab9..f1dce848ef9 100644
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -32,6 +32,8 @@
32#include <linux/crc-itu-t.h> 32#include <linux/crc-itu-t.h>
33#include <linux/exportfs.h> 33#include <linux/exportfs.h>
34 34
35enum { UDF_MAX_LINKS = 0xffff };
36
35static inline int udf_match(int len1, const unsigned char *name1, int len2, 37static inline int udf_match(int len1, const unsigned char *name1, int len2,
36 const unsigned char *name2) 38 const unsigned char *name2)
37{ 39{
@@ -251,7 +253,7 @@ out_ok:
251} 253}
252 254
253static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry, 255static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry,
254 unsigned int flags) 256 struct nameidata *nd)
255{ 257{
256 struct inode *inode = NULL; 258 struct inode *inode = NULL;
257 struct fileIdentDesc cfi; 259 struct fileIdentDesc cfi;
@@ -550,8 +552,8 @@ static int udf_delete_entry(struct inode *inode, struct fileIdentDesc *fi,
550 return udf_write_fi(inode, cfi, fi, fibh, NULL, NULL); 552 return udf_write_fi(inode, cfi, fi, fibh, NULL, NULL);
551} 553}
552 554
553static int udf_create(struct inode *dir, struct dentry *dentry, umode_t mode, 555static int udf_create(struct inode *dir, struct dentry *dentry, int mode,
554 bool excl) 556 struct nameidata *nd)
555{ 557{
556 struct udf_fileident_bh fibh; 558 struct udf_fileident_bh fibh;
557 struct inode *inode; 559 struct inode *inode;
@@ -575,7 +577,8 @@ static int udf_create(struct inode *dir, struct dentry *dentry, umode_t mode,
575 577
576 fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); 578 fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err);
577 if (!fi) { 579 if (!fi) {
578 inode_dec_link_count(inode); 580 inode->i_nlink--;
581 mark_inode_dirty(inode);
579 iput(inode); 582 iput(inode);
580 return err; 583 return err;
581 } 584 }
@@ -594,7 +597,7 @@ static int udf_create(struct inode *dir, struct dentry *dentry, umode_t mode,
594 return 0; 597 return 0;
595} 598}
596 599
597static int udf_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, 600static int udf_mknod(struct inode *dir, struct dentry *dentry, int mode,
598 dev_t rdev) 601 dev_t rdev)
599{ 602{
600 struct inode *inode; 603 struct inode *inode;
@@ -615,7 +618,8 @@ static int udf_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
615 init_special_inode(inode, mode, rdev); 618 init_special_inode(inode, mode, rdev);
616 fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); 619 fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err);
617 if (!fi) { 620 if (!fi) {
618 inode_dec_link_count(inode); 621 inode->i_nlink--;
622 mark_inode_dirty(inode);
619 iput(inode); 623 iput(inode);
620 return err; 624 return err;
621 } 625 }
@@ -638,7 +642,7 @@ out:
638 return err; 642 return err;
639} 643}
640 644
641static int udf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) 645static int udf_mkdir(struct inode *dir, struct dentry *dentry, int mode)
642{ 646{
643 struct inode *inode; 647 struct inode *inode;
644 struct udf_fileident_bh fibh; 648 struct udf_fileident_bh fibh;
@@ -647,6 +651,10 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
647 struct udf_inode_info *dinfo = UDF_I(dir); 651 struct udf_inode_info *dinfo = UDF_I(dir);
648 struct udf_inode_info *iinfo; 652 struct udf_inode_info *iinfo;
649 653
654 err = -EMLINK;
655 if (dir->i_nlink >= UDF_MAX_LINKS)
656 goto out;
657
650 err = -EIO; 658 err = -EIO;
651 inode = udf_new_inode(dir, S_IFDIR | mode, &err); 659 inode = udf_new_inode(dir, S_IFDIR | mode, &err);
652 if (!inode) 660 if (!inode)
@@ -657,11 +665,12 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
657 inode->i_fop = &udf_dir_operations; 665 inode->i_fop = &udf_dir_operations;
658 fi = udf_add_entry(inode, NULL, &fibh, &cfi, &err); 666 fi = udf_add_entry(inode, NULL, &fibh, &cfi, &err);
659 if (!fi) { 667 if (!fi) {
660 inode_dec_link_count(inode); 668 inode->i_nlink--;
669 mark_inode_dirty(inode);
661 iput(inode); 670 iput(inode);
662 goto out; 671 goto out;
663 } 672 }
664 set_nlink(inode, 2); 673 inode->i_nlink = 2;
665 cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); 674 cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
666 cfi.icb.extLocation = cpu_to_lelb(dinfo->i_location); 675 cfi.icb.extLocation = cpu_to_lelb(dinfo->i_location);
667 *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = 676 *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
@@ -674,7 +683,7 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
674 683
675 fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); 684 fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err);
676 if (!fi) { 685 if (!fi) {
677 clear_nlink(inode); 686 inode->i_nlink = 0;
678 mark_inode_dirty(inode); 687 mark_inode_dirty(inode);
679 iput(inode); 688 iput(inode);
680 goto out; 689 goto out;
@@ -790,8 +799,9 @@ static int udf_rmdir(struct inode *dir, struct dentry *dentry)
790 if (retval) 799 if (retval)
791 goto end_rmdir; 800 goto end_rmdir;
792 if (inode->i_nlink != 2) 801 if (inode->i_nlink != 2)
793 udf_warn(inode->i_sb, "empty directory has nlink != 2 (%d)\n", 802 udf_warning(inode->i_sb, "udf_rmdir",
794 inode->i_nlink); 803 "empty directory has nlink != 2 (%d)",
804 inode->i_nlink);
795 clear_nlink(inode); 805 clear_nlink(inode);
796 inode->i_size = 0; 806 inode->i_size = 0;
797 inode_dec_link_count(dir); 807 inode_dec_link_count(dir);
@@ -830,7 +840,7 @@ static int udf_unlink(struct inode *dir, struct dentry *dentry)
830 if (!inode->i_nlink) { 840 if (!inode->i_nlink) {
831 udf_debug("Deleting nonexistent file (%lu), %d\n", 841 udf_debug("Deleting nonexistent file (%lu), %d\n",
832 inode->i_ino, inode->i_nlink); 842 inode->i_ino, inode->i_nlink);
833 set_nlink(inode, 1); 843 inode->i_nlink = 1;
834 } 844 }
835 retval = udf_delete_entry(dir, fi, &fibh, &cfi); 845 retval = udf_delete_entry(dir, fi, &fibh, &cfi);
836 if (retval) 846 if (retval)
@@ -1026,6 +1036,9 @@ static int udf_link(struct dentry *old_dentry, struct inode *dir,
1026 struct fileIdentDesc cfi, *fi; 1036 struct fileIdentDesc cfi, *fi;
1027 int err; 1037 int err;
1028 1038
1039 if (inode->i_nlink >= UDF_MAX_LINKS)
1040 return -EMLINK;
1041
1029 fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); 1042 fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err);
1030 if (!fi) { 1043 if (!fi) {
1031 return err; 1044 return err;
@@ -1117,6 +1130,10 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry,
1117 if (udf_get_lb_pblock(old_inode->i_sb, &tloc, 0) != 1130 if (udf_get_lb_pblock(old_inode->i_sb, &tloc, 0) !=
1118 old_dir->i_ino) 1131 old_dir->i_ino)
1119 goto end_rename; 1132 goto end_rename;
1133
1134 retval = -EMLINK;
1135 if (!new_inode && new_dir->i_nlink >= UDF_MAX_LINKS)
1136 goto end_rename;
1120 } 1137 }
1121 if (!nfi) { 1138 if (!nfi) {
1122 nfi = udf_add_entry(new_dir, new_dentry, &nfibh, &ncfi, 1139 nfi = udf_add_entry(new_dir, new_dentry, &nfibh, &ncfi,
@@ -1193,7 +1210,7 @@ static struct dentry *udf_get_parent(struct dentry *child)
1193{ 1210{
1194 struct kernel_lb_addr tloc; 1211 struct kernel_lb_addr tloc;
1195 struct inode *inode = NULL; 1212 struct inode *inode = NULL;
1196 struct qstr dotdot = QSTR_INIT("..", 2); 1213 struct qstr dotdot = {.name = "..", .len = 2};
1197 struct fileIdentDesc cfi; 1214 struct fileIdentDesc cfi;
1198 struct udf_fileident_bh fibh; 1215 struct udf_fileident_bh fibh;
1199 1216
@@ -1260,15 +1277,16 @@ static struct dentry *udf_fh_to_parent(struct super_block *sb,
1260 fid->udf.parent_partref, 1277 fid->udf.parent_partref,
1261 fid->udf.parent_generation); 1278 fid->udf.parent_generation);
1262} 1279}
1263static int udf_encode_fh(struct inode *inode, __u32 *fh, int *lenp, 1280static int udf_encode_fh(struct dentry *de, __u32 *fh, int *lenp,
1264 struct inode *parent) 1281 int connectable)
1265{ 1282{
1266 int len = *lenp; 1283 int len = *lenp;
1284 struct inode *inode = de->d_inode;
1267 struct kernel_lb_addr location = UDF_I(inode)->i_location; 1285 struct kernel_lb_addr location = UDF_I(inode)->i_location;
1268 struct fid *fid = (struct fid *)fh; 1286 struct fid *fid = (struct fid *)fh;
1269 int type = FILEID_UDF_WITHOUT_PARENT; 1287 int type = FILEID_UDF_WITHOUT_PARENT;
1270 1288
1271 if (parent && (len < 5)) { 1289 if (connectable && (len < 5)) {
1272 *lenp = 5; 1290 *lenp = 5;
1273 return 255; 1291 return 255;
1274 } else if (len < 3) { 1292 } else if (len < 3) {
@@ -1279,14 +1297,16 @@ static int udf_encode_fh(struct inode *inode, __u32 *fh, int *lenp,
1279 *lenp = 3; 1297 *lenp = 3;
1280 fid->udf.block = location.logicalBlockNum; 1298 fid->udf.block = location.logicalBlockNum;
1281 fid->udf.partref = location.partitionReferenceNum; 1299 fid->udf.partref = location.partitionReferenceNum;
1282 fid->udf.parent_partref = 0;
1283 fid->udf.generation = inode->i_generation; 1300 fid->udf.generation = inode->i_generation;
1284 1301
1285 if (parent) { 1302 if (connectable && !S_ISDIR(inode->i_mode)) {
1286 location = UDF_I(parent)->i_location; 1303 spin_lock(&de->d_lock);
1304 inode = de->d_parent->d_inode;
1305 location = UDF_I(inode)->i_location;
1287 fid->udf.parent_block = location.logicalBlockNum; 1306 fid->udf.parent_block = location.logicalBlockNum;
1288 fid->udf.parent_partref = location.partitionReferenceNum; 1307 fid->udf.parent_partref = location.partitionReferenceNum;
1289 fid->udf.parent_generation = inode->i_generation; 1308 fid->udf.parent_generation = inode->i_generation;
1309 spin_unlock(&de->d_lock);
1290 *lenp = 5; 1310 *lenp = 5;
1291 type = FILEID_UDF_WITH_PARENT; 1311 type = FILEID_UDF_WITH_PARENT;
1292 } 1312 }